Tahinli/forge
public0 watching
★ 0
| 1 | //! Strings for the organization pages (`/org/...`), org creation, and the org-related parts of the |
| 2 | //! profile, explore and dashboard pages. |
| 3 | |
| 4 | use super::Lang; |
| 5 | |
| 6 | #[derive(Clone, Copy, Debug, PartialEq, Eq)] |
| 7 | pub enum K { |
| 8 | // One-shot notices shown after a redirect (see `pages::org_ctx::NOTICES`). |
| 9 | NoticeSettingsSaved, |
| 10 | NoticeMemberAdded, |
| 11 | NoticeRoleUpdated, |
| 12 | NoticeMemberRemoved, |
| 13 | NoticeTeamCreated, |
| 14 | NoticeTeamSaved, |
| 15 | NoticeTeamDeleted, |
| 16 | NoticeTeamMemberAdded, |
| 17 | NoticeTeamMemberRemoved, |
| 18 | NoticeTeamRepoAdded, |
| 19 | NoticeTeamRepoRemoved, |
| 20 | NoticeEmptyUsername, |
| 21 | NoticeUnknownUser, |
| 22 | NoticeAlreadyMember, |
| 23 | NoticeNotMember, |
| 24 | NoticeLastOwner, |
| 25 | NoticeInvalidRole, |
| 26 | NoticeInvalidName, |
| 27 | NoticeTeamDescriptionLength, |
| 28 | NoticeTeamExists, |
| 29 | NoticeAlreadyInTeam, |
| 30 | NoticeNotInOrg, |
| 31 | NoticeNotOwned, |
| 32 | NoticeAlreadyLinked, |
| 33 | NoticeHasRepos, |
| 34 | NoticeConfirmName, |
| 35 | NoticeDescriptionLength, |
| 36 | // Shared labels. |
| 37 | Save, |
| 38 | Remove, |
| 39 | Username, |
| 40 | Name, |
| 41 | Explore, |
| 42 | NewRepository, |
| 43 | // Organization creation. |
| 44 | NewOrganization, |
| 45 | NewOrgIntro, |
| 46 | OrgName, |
| 47 | DescriptionOptional, |
| 48 | CreateOrg, |
| 49 | // Organization settings. |
| 50 | Settings, |
| 51 | Description, |
| 52 | DefaultRoleLabel, |
| 53 | DefaultRoleHelp, |
| 54 | MembersCanCreate, |
| 55 | SaveSettings, |
| 56 | DeleteOrg, |
| 57 | DeleteOrgIntro, |
| 58 | // Members. |
| 59 | Members, |
| 60 | Teams, |
| 61 | Organization, |
| 62 | MemberHeader, |
| 63 | Role, |
| 64 | RoleOwner, |
| 65 | RoleMember, |
| 66 | Leave, |
| 67 | AddMember, |
| 68 | AddMemberButton, |
| 69 | OwnersHelp, |
| 70 | // Teams. |
| 71 | TeamsIntro, |
| 72 | NoTeamsYet, |
| 73 | NewTeam, |
| 74 | CoversAllRepos, |
| 75 | CreateTeam, |
| 76 | SaveTeam, |
| 77 | DeleteTeam, |
| 78 | NoTeamMembers, |
| 79 | AddToTeam, |
| 80 | Repositories, |
| 81 | NoTeamRepos, |
| 82 | Unlink, |
| 83 | Repository, |
| 84 | LinkRepository, |
| 85 | AllRepositories, |
| 86 | LinkedRepositories, |
| 87 | // Role words shown in selects and coverage text. The stored words stay English. |
| 88 | RoleNone, |
| 89 | RoleRead, |
| 90 | RoleWrite, |
| 91 | RoleTriage, |
| 92 | RoleMaintain, |
| 93 | RoleAdmin, |
| 94 | // Explore. |
| 95 | Pages, |
| 96 | Previous, |
| 97 | Next, |
| 98 | PublicReposIntro, |
| 99 | Organizations, |
| 100 | SearchPublicRepos, |
| 101 | Search, |
| 102 | SortBy, |
| 103 | SortNav, |
| 104 | SortRecentlyUpdated, |
| 105 | SortMostStars, |
| 106 | NoPublicReposMatch, |
| 107 | // Profile. |
| 108 | LocalTime, |
| 109 | AllMembers, |
| 110 | NoMembers, |
| 111 | NoVisibleRepos, |
| 112 | Starred, |
| 113 | NoVisibleStarred, |
| 114 | // Dashboard and landing. |
| 115 | Dashboard, |
| 116 | Home, |
| 117 | LandingTagline, |
| 118 | LogIn, |
| 119 | SetUpForge, |
| 120 | YourRepositories, |
| 121 | NoReposYet, |
| 122 | } |
| 123 | |
| 124 | pub fn t(lang: Lang, key: K) -> &'static str { |
| 125 | use K::*; |
| 126 | use Lang::*; |
| 127 | match (key, lang) { |
| 128 | (NoticeSettingsSaved, En) => "Settings saved.", |
| 129 | (NoticeSettingsSaved, Tr) => "Ayarlar kaydedildi.", |
| 130 | (NoticeMemberAdded, En) => "Member added.", |
| 131 | (NoticeMemberAdded, Tr) => "Üye eklendi.", |
| 132 | (NoticeRoleUpdated, En) => "Role updated.", |
| 133 | (NoticeRoleUpdated, Tr) => "Rol güncellendi.", |
| 134 | (NoticeMemberRemoved, En) => "Member removed.", |
| 135 | (NoticeMemberRemoved, Tr) => "Üye çıkarıldı.", |
| 136 | (NoticeTeamCreated, En) => "Team created.", |
| 137 | (NoticeTeamCreated, Tr) => "Takım oluşturuldu.", |
| 138 | (NoticeTeamSaved, En) => "Team saved.", |
| 139 | (NoticeTeamSaved, Tr) => "Takım kaydedildi.", |
| 140 | (NoticeTeamDeleted, En) => "Team deleted.", |
| 141 | (NoticeTeamDeleted, Tr) => "Takım silindi.", |
| 142 | (NoticeTeamMemberAdded, En) => "Member added to the team.", |
| 143 | (NoticeTeamMemberAdded, Tr) => "Üye takıma eklendi.", |
| 144 | (NoticeTeamMemberRemoved, En) => "Member removed from the team.", |
| 145 | (NoticeTeamMemberRemoved, Tr) => "Üye takımdan çıkarıldı.", |
| 146 | (NoticeTeamRepoAdded, En) => "Repository linked to the team.", |
| 147 | (NoticeTeamRepoAdded, Tr) => "Depo takıma bağlandı.", |
| 148 | (NoticeTeamRepoRemoved, En) => "Repository unlinked from the team.", |
| 149 | (NoticeTeamRepoRemoved, Tr) => "Deponun takım bağlantısı kaldırıldı.", |
| 150 | (NoticeEmptyUsername, En) => "Enter a username.", |
| 151 | (NoticeEmptyUsername, Tr) => "Bir kullanıcı adı girin.", |
| 152 | (NoticeUnknownUser, En) => "No person has that username.", |
| 153 | (NoticeUnknownUser, Tr) => "Bu kullanıcı adına sahip bir kişi yok.", |
| 154 | (NoticeAlreadyMember, En) => "That person is already a member.", |
| 155 | (NoticeAlreadyMember, Tr) => "Bu kişi zaten bir üye.", |
| 156 | (NoticeNotMember, En) => "That person is not a member of this organization.", |
| 157 | (NoticeNotMember, Tr) => "Bu kişi bu kuruluşun üyesi değil.", |
| 158 | (NoticeLastOwner, En) => "An organization needs at least one owner.", |
| 159 | (NoticeLastOwner, Tr) => "Bir kuruluşun en az bir sahibi olmalı.", |
| 160 | (NoticeInvalidRole, En) => "Choose a valid role.", |
| 161 | (NoticeInvalidRole, Tr) => "Geçerli bir rol seçin.", |
| 162 | (NoticeInvalidName, En) => "Choose a valid name.", |
| 163 | (NoticeInvalidName, Tr) => "Geçerli bir ad seçin.", |
| 164 | (NoticeTeamDescriptionLength, En) => "A team description is at most 350 characters.", |
| 165 | (NoticeTeamDescriptionLength, Tr) => "Takım açıklaması en fazla 350 karakter olabilir.", |
| 166 | (NoticeTeamExists, En) => "A team with this name already exists.", |
| 167 | (NoticeTeamExists, Tr) => "Bu adla bir takım zaten var.", |
| 168 | (NoticeAlreadyInTeam, En) => "That person is already in this team.", |
| 169 | (NoticeAlreadyInTeam, Tr) => "Bu kişi zaten bu takımda.", |
| 170 | (NoticeNotInOrg, En) => "Only members of the organization can join its teams.", |
| 171 | (NoticeNotInOrg, Tr) => "Yalnızca kuruluşun üyeleri takımlarına katılabilir.", |
| 172 | (NoticeNotOwned, En) => "Only repositories this organization owns can join its teams.", |
| 173 | (NoticeNotOwned, Tr) => "Yalnızca bu kuruluşa ait depolar takımlarına katılabilir.", |
| 174 | (NoticeAlreadyLinked, En) => "This team already covers that repository.", |
| 175 | (NoticeAlreadyLinked, Tr) => "Bu takım bu depoyu zaten kapsıyor.", |
| 176 | (NoticeHasRepos, En) => "Transfer or delete the organization's repositories first.", |
| 177 | (NoticeHasRepos, Tr) => "Önce kuruluşun depolarını devredin veya silin.", |
| 178 | (NoticeConfirmName, En) => "Type the organization's name exactly to delete it.", |
| 179 | (NoticeConfirmName, Tr) => "Kuruluşu silmek için adını tam olarak yazın.", |
| 180 | (NoticeDescriptionLength, En) => "The description is longer than 2000 characters.", |
| 181 | (NoticeDescriptionLength, Tr) => "Açıklama 2000 karakterden uzun.", |
| 182 | (Save, En) => "Save", |
| 183 | (Save, Tr) => "Kaydet", |
| 184 | (Remove, En) => "Remove", |
| 185 | (Remove, Tr) => "Kaldır", |
| 186 | (Username, En) => "Username", |
| 187 | (Username, Tr) => "Kullanıcı adı", |
| 188 | (Name, En) => "Name", |
| 189 | (Name, Tr) => "Ad", |
| 190 | (Explore, En) => "Explore", |
| 191 | (Explore, Tr) => "Keşfet", |
| 192 | (NewRepository, En) => "New repository", |
| 193 | (NewRepository, Tr) => "Yeni depo", |
| 194 | (NewOrganization, En) => "New organization", |
| 195 | (NewOrganization, Tr) => "Yeni kuruluş", |
| 196 | (NewOrgIntro, En) => { |
| 197 | "An organization owns repositories and shares them with its members through teams. You become its first owner." |
| 198 | } |
| 199 | (NewOrgIntro, Tr) => { |
| 200 | "Kuruluş depolara sahip olur ve bunları takımları aracılığıyla üyeleriyle paylaşır. Kuruluşun ilk sahibi siz olursunuz." |
| 201 | } |
| 202 | (OrgName, En) => "Organization name", |
| 203 | (OrgName, Tr) => "Kuruluş adı", |
| 204 | (DescriptionOptional, En) => "Description (optional)", |
| 205 | (DescriptionOptional, Tr) => "Açıklama (isteğe bağlı)", |
| 206 | (CreateOrg, En) => "Create organization", |
| 207 | (CreateOrg, Tr) => "Kuruluş oluştur", |
| 208 | (Settings, En) => "Settings", |
| 209 | (Settings, Tr) => "Ayarlar", |
| 210 | (Description, En) => "Description", |
| 211 | (Description, Tr) => "Açıklama", |
| 212 | (DefaultRoleLabel, En) => "Default role on the organization's repositories", |
| 213 | (DefaultRoleLabel, Tr) => "Kuruluş depolarında varsayılan rol", |
| 214 | (DefaultRoleHelp, En) => { |
| 215 | "Members get this role on every repository the organization owns, unless a team gives them more. Owners always have admin." |
| 216 | } |
| 217 | (DefaultRoleHelp, Tr) => { |
| 218 | "Üyeler, bir takım daha fazla yetki vermedikçe kuruluşa ait her depoda bu rolü alır. Sahipler her zaman yönetici yetkisine sahiptir." |
| 219 | } |
| 220 | (MembersCanCreate, En) => "Members can create repositories for this organization", |
| 221 | (MembersCanCreate, Tr) => "Üyeler bu kuruluş için depo oluşturabilir", |
| 222 | (SaveSettings, En) => "Save settings", |
| 223 | (SaveSettings, Tr) => "Ayarları kaydet", |
| 224 | (DeleteOrg, En) => "Delete organization", |
| 225 | (DeleteOrg, Tr) => "Kuruluşu sil", |
| 226 | (DeleteOrgIntro, En) => { |
| 227 | "Deleting removes the organization, its members and its teams. It is refused while the organization owns repositories." |
| 228 | } |
| 229 | (DeleteOrgIntro, Tr) => { |
| 230 | "Silme işlemi kuruluşu, üyelerini ve takımlarını kaldırır. Kuruluşun depoları varken reddedilir." |
| 231 | } |
| 232 | (Members, En) => "Members", |
| 233 | (Members, Tr) => "Üyeler", |
| 234 | (Teams, En) => "Teams", |
| 235 | (Teams, Tr) => "Takımlar", |
| 236 | (Organization, En) => "Organization", |
| 237 | (Organization, Tr) => "Kuruluş", |
| 238 | (MemberHeader, En) => "Member", |
| 239 | (MemberHeader, Tr) => "Üye", |
| 240 | (Role, En) => "Role", |
| 241 | (Role, Tr) => "Rol", |
| 242 | (RoleOwner, En) => "owner", |
| 243 | (RoleOwner, Tr) => "sahip", |
| 244 | (RoleMember, En) => "member", |
| 245 | (RoleMember, Tr) => "üye", |
| 246 | (Leave, En) => "Leave", |
| 247 | (Leave, Tr) => "Ayrıl", |
| 248 | (AddMember, En) => "Add a member", |
| 249 | (AddMember, Tr) => "Bir üye ekle", |
| 250 | (AddMemberButton, En) => "Add member", |
| 251 | (AddMemberButton, Tr) => "Üye ekle", |
| 252 | (OwnersHelp, En) => { |
| 253 | "Owners manage the organization, its teams and its settings. Members get the repository access their teams give them." |
| 254 | } |
| 255 | (OwnersHelp, Tr) => { |
| 256 | "Sahipler kuruluşu, takımlarını ve ayarlarını yönetir. Üyeler, takımlarının verdiği depo erişimini alır." |
| 257 | } |
| 258 | (TeamsIntro, En) => { |
| 259 | "A team gives its members a role on the repositories it covers: every repository the organization owns when the team covers all of them, otherwise only the repositories linked to it." |
| 260 | } |
| 261 | (TeamsIntro, Tr) => { |
| 262 | "Takım, üyelerine kapsadığı depolarda bir rol verir: takım kuruluşun tüm depolarını kapsıyorsa kuruluşa ait her depo, aksi halde yalnızca takıma bağlı depolar." |
| 263 | } |
| 264 | (NoTeamsYet, En) => "No teams yet.", |
| 265 | (NoTeamsYet, Tr) => "Henüz takım yok.", |
| 266 | (NewTeam, En) => "New team", |
| 267 | (NewTeam, Tr) => "Yeni takım", |
| 268 | (CoversAllRepos, En) => "Covers all of the organization's repositories", |
| 269 | (CoversAllRepos, Tr) => "Kuruluşun tüm depolarını kapsar", |
| 270 | (CreateTeam, En) => "Create team", |
| 271 | (CreateTeam, Tr) => "Takım oluştur", |
| 272 | (SaveTeam, En) => "Save team", |
| 273 | (SaveTeam, Tr) => "Takımı kaydet", |
| 274 | (DeleteTeam, En) => "Delete team", |
| 275 | (DeleteTeam, Tr) => "Takımı sil", |
| 276 | (NoTeamMembers, En) => "No members in this team yet.", |
| 277 | (NoTeamMembers, Tr) => "Bu takımda henüz üye yok.", |
| 278 | (AddToTeam, En) => "Add to team", |
| 279 | (AddToTeam, Tr) => "Takıma ekle", |
| 280 | (Repositories, En) => "Repositories", |
| 281 | (Repositories, Tr) => "Depolar", |
| 282 | (NoTeamRepos, En) => "No repositories are linked to this team.", |
| 283 | (NoTeamRepos, Tr) => "Bu takıma bağlı depo yok.", |
| 284 | (Unlink, En) => "Unlink", |
| 285 | (Unlink, Tr) => "Bağlantıyı kaldır", |
| 286 | (Repository, En) => "Repository", |
| 287 | (Repository, Tr) => "Depo", |
| 288 | (LinkRepository, En) => "Link repository", |
| 289 | (LinkRepository, Tr) => "Depoyu bağla", |
| 290 | (AllRepositories, En) => "all repositories", |
| 291 | (AllRepositories, Tr) => "tüm depolarda", |
| 292 | (LinkedRepositories, En) => "linked repositories", |
| 293 | (LinkedRepositories, Tr) => "bağlı depolarda", |
| 294 | (RoleNone, En) => "none", |
| 295 | (RoleNone, Tr) => "yok", |
| 296 | (RoleRead, En) => "read", |
| 297 | (RoleRead, Tr) => "okuma", |
| 298 | (RoleWrite, En) => "write", |
| 299 | (RoleWrite, Tr) => "yazma", |
| 300 | (RoleTriage, En) => "triage", |
| 301 | (RoleTriage, Tr) => "triyaj", |
| 302 | (RoleMaintain, En) => "maintain", |
| 303 | (RoleMaintain, Tr) => "bakım", |
| 304 | (RoleAdmin, En) => "admin", |
| 305 | (RoleAdmin, Tr) => "yönetici", |
| 306 | (Pages, En) => "Pages", |
| 307 | (Pages, Tr) => "Sayfalar", |
| 308 | (Previous, En) => "Previous", |
| 309 | (Previous, Tr) => "Önceki", |
| 310 | (Next, En) => "Next", |
| 311 | (Next, Tr) => "Sonraki", |
| 312 | (PublicReposIntro, En) => "Public repositories on this forge.", |
| 313 | (PublicReposIntro, Tr) => "Bu forge üzerindeki herkese açık depolar.", |
| 314 | (Organizations, En) => "Organizations", |
| 315 | (Organizations, Tr) => "Kuruluşlar", |
| 316 | (SearchPublicRepos, En) => "Search public repositories", |
| 317 | (SearchPublicRepos, Tr) => "Herkese açık depolarda ara", |
| 318 | (Search, En) => "Search", |
| 319 | (Search, Tr) => "Ara", |
| 320 | (SortBy, En) => "Sort by", |
| 321 | (SortBy, Tr) => "Sırala", |
| 322 | (SortNav, En) => "Sort", |
| 323 | (SortNav, Tr) => "Sırala", |
| 324 | (SortRecentlyUpdated, En) => "Recently updated", |
| 325 | (SortRecentlyUpdated, Tr) => "Son güncellenenler", |
| 326 | (SortMostStars, En) => "Most stars", |
| 327 | (SortMostStars, Tr) => "En çok yıldızlananlar", |
| 328 | (NoPublicReposMatch, En) => "No public repositories match.", |
| 329 | (NoPublicReposMatch, Tr) => "Aramayla eşleşen herkese açık depo yok.", |
| 330 | (LocalTime, En) => "Local time: ", |
| 331 | (LocalTime, Tr) => "Yerel saat: ", |
| 332 | (AllMembers, En) => "All members", |
| 333 | (AllMembers, Tr) => "Tüm üyeler", |
| 334 | (NoMembers, En) => "No members.", |
| 335 | (NoMembers, Tr) => "Üye yok.", |
| 336 | (NoVisibleRepos, En) => "No visible repositories.", |
| 337 | (NoVisibleRepos, Tr) => "Görünür depo yok.", |
| 338 | (Starred, En) => "Starred", |
| 339 | (Starred, Tr) => "Yıldızlılar", |
| 340 | (NoVisibleStarred, En) => "No visible starred repositories.", |
| 341 | (NoVisibleStarred, Tr) => "Görünür yıldızlı depo yok.", |
| 342 | (Dashboard, En) => "Dashboard", |
| 343 | (Dashboard, Tr) => "Pano", |
| 344 | (Home, En) => "Home", |
| 345 | (Home, Tr) => "Ana sayfa", |
| 346 | (LandingTagline, En) => "Self-hosted git repositories with a small, fast web interface.", |
| 347 | (LandingTagline, Tr) => { |
| 348 | "Kendi sunucunuzda barındırılan git depoları, küçük ve hızlı bir web arayüzüyle." |
| 349 | } |
| 350 | (LogIn, En) => "Log in", |
| 351 | (LogIn, Tr) => "Giriş yap", |
| 352 | (SetUpForge, En) => "Set up forge", |
| 353 | (SetUpForge, Tr) => "forge'u kur", |
| 354 | (YourRepositories, En) => "Your repositories", |
| 355 | (YourRepositories, Tr) => "Depolarınız", |
| 356 | (NoReposYet, En) => "You have no repositories yet.", |
| 357 | (NoReposYet, Tr) => "Henüz deponuz yok.", |
| 358 | } |
| 359 | } |
| 360 | |
| 361 | /// The text for a role word from a select or a coverage line. Unknown words pass through. |
| 362 | pub fn role_name(lang: Lang, word: &'static str) -> &'static str { |
| 363 | let key = match word { |
| 364 | "none" => K::RoleNone, |
| 365 | "read" => K::RoleRead, |
| 366 | "write" => K::RoleWrite, |
| 367 | "triage" => K::RoleTriage, |
| 368 | "maintain" => K::RoleMaintain, |
| 369 | "admin" => K::RoleAdmin, |
| 370 | _ => return word, |
| 371 | }; |
| 372 | t(lang, key) |
| 373 | } |
| 374 | |
| 375 | /// A team's role and coverage, in words: "write on all repositories", or "tüm depolarda yazma". |
| 376 | pub fn coverage_text(lang: Lang, role: &'static str, all_repos: bool) -> String { |
| 377 | let scope = t( |
| 378 | lang, |
| 379 | if all_repos { |
| 380 | K::AllRepositories |
| 381 | } else { |
| 382 | K::LinkedRepositories |
| 383 | }, |
| 384 | ); |
| 385 | let role = role_name(lang, role); |
| 386 | match lang { |
| 387 | Lang::En => format!("{role} on {scope}"), |
| 388 | Lang::Tr => format!("{scope} {role}"), |
| 389 | } |
| 390 | } |
| 391 | |
| 392 | /// The "too long" rejection for an organization description. |
| 393 | pub fn description_too_long(lang: Lang, max: usize) -> String { |
| 394 | match lang { |
| 395 | Lang::En => format!("description must be at most {max} characters"), |
| 396 | Lang::Tr => format!("Açıklama en fazla {max} karakter olabilir."), |
| 397 | } |
| 398 | } |
| 399 | |
| 400 | /// The label that asks for the org's name before deleting it. |
| 401 | pub fn type_to_confirm(lang: Lang, name: &str) -> String { |
| 402 | match lang { |
| 403 | Lang::En => format!("Type {name} to confirm"), |
| 404 | Lang::Tr => format!("Onaylamak için {name} yazın"), |
| 405 | } |
| 406 | } |
| 407 | |
| 408 | /// The page title: the org name, a separator, then the section name. |
| 409 | pub fn page_title(lang: Lang, org: &str, section: K) -> String { |
| 410 | format!("{org} \u{b7} {}", t(lang, section)) |
| 411 | } |
| 412 | |
| 413 | /// The label for a member's role select. |
| 414 | pub fn role_for(lang: Lang, user: &str) -> String { |
| 415 | match lang { |
| 416 | Lang::En => format!("Role for {user}"), |
| 417 | Lang::Tr => format!("{user} için rol"), |
| 418 | } |
| 419 | } |
| 420 | |
| 421 | /// The member and team counts on a profile. |
| 422 | pub fn members_and_teams(lang: Lang, members: usize, teams: usize) -> String { |
| 423 | match lang { |
| 424 | Lang::En => format!("{members} members \u{b7} {teams} teams"), |
| 425 | Lang::Tr => format!("{members} üye \u{b7} {teams} takım"), |
| 426 | } |
| 427 | } |
| 428 | |
| 429 | /// "3 repositories", or "3 depo" in Turkish. |
| 430 | pub fn repo_count(lang: Lang, total: u64) -> String { |
| 431 | match lang { |
| 432 | Lang::En => format!("{total} repositories"), |
| 433 | Lang::Tr => format!("{total} depo"), |
| 434 | } |
| 435 | } |
| 436 | |
| 437 | /// "Page 2 of 5", or "Sayfa 2 / 5" in Turkish. |
| 438 | pub fn page_of(lang: Lang, page: u64, pages: u64) -> String { |
| 439 | match lang { |
| 440 | Lang::En => format!("Page {page} of {pages}"), |
| 441 | Lang::Tr => format!("Sayfa {page} / {pages}"), |
| 442 | } |
| 443 | } |
| 444 | |
| 445 | /// The updated note after a repository's stars: " · updated 3 days ago", or " · 3 gün önce güncellendi". |
| 446 | pub fn updated_text(lang: Lang, when: &str) -> String { |
| 447 | match lang { |
| 448 | Lang::En => format!(" \u{b7} updated {when}"), |
| 449 | Lang::Tr => format!(" \u{b7} {when} güncellendi"), |
| 450 | } |
| 451 | } |
| 452 | |
| 453 | #[cfg(test)] |
| 454 | mod tests { |
| 455 | use super::*; |
| 456 | |
| 457 | /// Every key, for the coverage tests. Keep it in step with the enum. |
| 458 | const ALL: &[K] = &[ |
| 459 | K::NoticeSettingsSaved, |
| 460 | K::NoticeMemberAdded, |
| 461 | K::NoticeRoleUpdated, |
| 462 | K::NoticeMemberRemoved, |
| 463 | K::NoticeTeamCreated, |
| 464 | K::NoticeTeamSaved, |
| 465 | K::NoticeTeamDeleted, |
| 466 | K::NoticeTeamMemberAdded, |
| 467 | K::NoticeTeamMemberRemoved, |
| 468 | K::NoticeTeamRepoAdded, |
| 469 | K::NoticeTeamRepoRemoved, |
| 470 | K::NoticeEmptyUsername, |
| 471 | K::NoticeUnknownUser, |
| 472 | K::NoticeAlreadyMember, |
| 473 | K::NoticeNotMember, |
| 474 | K::NoticeLastOwner, |
| 475 | K::NoticeInvalidRole, |
| 476 | K::NoticeInvalidName, |
| 477 | K::NoticeTeamDescriptionLength, |
| 478 | K::NoticeTeamExists, |
| 479 | K::NoticeAlreadyInTeam, |
| 480 | K::NoticeNotInOrg, |
| 481 | K::NoticeNotOwned, |
| 482 | K::NoticeAlreadyLinked, |
| 483 | K::NoticeHasRepos, |
| 484 | K::NoticeConfirmName, |
| 485 | K::NoticeDescriptionLength, |
| 486 | K::Save, |
| 487 | K::Remove, |
| 488 | K::Username, |
| 489 | K::Name, |
| 490 | K::Explore, |
| 491 | K::NewRepository, |
| 492 | K::NewOrganization, |
| 493 | K::NewOrgIntro, |
| 494 | K::OrgName, |
| 495 | K::DescriptionOptional, |
| 496 | K::CreateOrg, |
| 497 | K::Settings, |
| 498 | K::Description, |
| 499 | K::DefaultRoleLabel, |
| 500 | K::DefaultRoleHelp, |
| 501 | K::MembersCanCreate, |
| 502 | K::SaveSettings, |
| 503 | K::DeleteOrg, |
| 504 | K::DeleteOrgIntro, |
| 505 | K::Members, |
| 506 | K::Teams, |
| 507 | K::Organization, |
| 508 | K::MemberHeader, |
| 509 | K::Role, |
| 510 | K::RoleOwner, |
| 511 | K::RoleMember, |
| 512 | K::Leave, |
| 513 | K::AddMember, |
| 514 | K::AddMemberButton, |
| 515 | K::OwnersHelp, |
| 516 | K::TeamsIntro, |
| 517 | K::NoTeamsYet, |
| 518 | K::NewTeam, |
| 519 | K::CoversAllRepos, |
| 520 | K::CreateTeam, |
| 521 | K::SaveTeam, |
| 522 | K::DeleteTeam, |
| 523 | K::NoTeamMembers, |
| 524 | K::AddToTeam, |
| 525 | K::Repositories, |
| 526 | K::NoTeamRepos, |
| 527 | K::Unlink, |
| 528 | K::Repository, |
| 529 | K::LinkRepository, |
| 530 | K::AllRepositories, |
| 531 | K::LinkedRepositories, |
| 532 | K::RoleNone, |
| 533 | K::RoleRead, |
| 534 | K::RoleWrite, |
| 535 | K::RoleTriage, |
| 536 | K::RoleMaintain, |
| 537 | K::RoleAdmin, |
| 538 | K::Pages, |
| 539 | K::Previous, |
| 540 | K::Next, |
| 541 | K::PublicReposIntro, |
| 542 | K::Organizations, |
| 543 | K::SearchPublicRepos, |
| 544 | K::Search, |
| 545 | K::SortBy, |
| 546 | K::SortNav, |
| 547 | K::SortRecentlyUpdated, |
| 548 | K::SortMostStars, |
| 549 | K::NoPublicReposMatch, |
| 550 | K::LocalTime, |
| 551 | K::AllMembers, |
| 552 | K::NoMembers, |
| 553 | K::NoVisibleRepos, |
| 554 | K::Starred, |
| 555 | K::NoVisibleStarred, |
| 556 | K::Dashboard, |
| 557 | K::Home, |
| 558 | K::LandingTagline, |
| 559 | K::LogIn, |
| 560 | K::SetUpForge, |
| 561 | K::YourRepositories, |
| 562 | K::NoReposYet, |
| 563 | ]; |
| 564 | |
| 565 | #[test] |
| 566 | fn every_key_has_text_in_both_languages() { |
| 567 | for key in ALL { |
| 568 | assert!(!t(Lang::En, *key).is_empty(), "{key:?} has no English"); |
| 569 | assert!(!t(Lang::Tr, *key).is_empty(), "{key:?} has no Turkish"); |
| 570 | } |
| 571 | } |
| 572 | |
| 573 | #[test] |
| 574 | fn turkish_differs_from_english_for_most_keys() { |
| 575 | let differing = ALL |
| 576 | .iter() |
| 577 | .filter(|key| t(Lang::En, **key) != t(Lang::Tr, **key)) |
| 578 | .count(); |
| 579 | assert!(differing >= 3, "only {differing} keys are translated"); |
| 580 | assert_eq!(t(Lang::Tr, K::NoTeamsYet), "Henüz takım yok."); |
| 581 | } |
| 582 | |
| 583 | #[test] |
| 584 | fn helpers_keep_the_english_sentences() { |
| 585 | assert_eq!( |
| 586 | coverage_text(Lang::En, "write", true), |
| 587 | "write on all repositories" |
| 588 | ); |
| 589 | assert_eq!( |
| 590 | coverage_text(Lang::En, "read", false), |
| 591 | "read on linked repositories" |
| 592 | ); |
| 593 | assert_eq!( |
| 594 | coverage_text(Lang::Tr, "read", false), |
| 595 | "bağlı depolarda okuma" |
| 596 | ); |
| 597 | assert_eq!(page_of(Lang::En, 2, 5), "Page 2 of 5"); |
| 598 | assert_eq!( |
| 599 | updated_text(Lang::En, "3 days ago"), |
| 600 | " \u{b7} updated 3 days ago" |
| 601 | ); |
| 602 | assert_eq!( |
| 603 | updated_text(Lang::Tr, "3 gün önce"), |
| 604 | " \u{b7} 3 gün önce güncellendi" |
| 605 | ); |
| 606 | assert_eq!(repo_count(Lang::En, 3), "3 repositories"); |
| 607 | assert_eq!( |
| 608 | members_and_teams(Lang::En, 2, 1), |
| 609 | "2 members \u{b7} 1 teams" |
| 610 | ); |
| 611 | assert_eq!(type_to_confirm(Lang::En, "acme"), "Type acme to confirm"); |
| 612 | assert_eq!( |
| 613 | description_too_long(Lang::En, 2000), |
| 614 | "description must be at most 2000 characters" |
| 615 | ); |
| 616 | } |
| 617 | } |