//! Strings for the community group: discussions, the wiki and snippets. See `super` for the //! pattern: one variant per UI phrase, an exhaustive `t` match, and small helpers for sentences //! that carry arguments. use forge_core::discussions::DiscussionCategory; use super::Lang; #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum K { // Discussions: list, new, view and settings. AllCategories, CategoriesNav, NewDiscussion, NoDiscussionsYet, Discussions, Newer, Older, Category, Title, Description, MarkdownSupported, StartDiscussion, Cancel, Save, Delete, Edit, EditComment, CouldNotSave, CommentDeleted, Answer, MarkAsAnswer, UnmarkAnswer, Reply, DeleteDiscussion, Conversation, LockConversation, UnlockConversation, Answered, Locked, OpenedThis, OpenedSeparator, NoDescription, LockedNotice, AddComment, CommentButton, LogInLink, ToCommentSuffix, ArchivedDiscussions, DiscussionsDescription, TurnOffDiscussions, TurnOnDiscussions, CategoryGeneral, CategoryIdeas, CategoryQa, CategoryAnnouncements, // Wiki. Wiki, Home, AllPages, NewPage, History, PageNav, WikiNoPages, CreateFirstPage, NoPagesYet, BackToPage, NoChangesYet, PageName, PageNameHint, ContentMarkdown, WikiLinkHint, Summary, SavePage, PageNameRules, PageExists, WikiConflict, WikiSettings, EnableWiki, WikiDisabledHint, WikiPages, // Snippets. Snippets, NewSnippet, NoSnippets, Visibility, VisibilityPublic, VisibilityUnlisted, VisibilityPrivate, PublicOption, UnlistedOption, PrivateOption, FileLabel, FileNamePlaceholder, FileName, FileContents, Untitled, Files, SnippetTitlePlaceholder, DescriptionOptional, AddFile, RemoveFile, SaveSnippet, EditSnippet, Raw, SnippetNav, FileNav, OnlyOwnerEdits, Revisions, BackToSnippet, NoRevisions, RevisionLabel, ChooseVisibility, } pub fn t(lang: Lang, key: K) -> &'static str { use K::*; use Lang::*; match (key, lang) { (AllCategories, En) => "All", (AllCategories, Tr) => "Tümü", (CategoriesNav, En) => "Discussion categories", (CategoriesNav, Tr) => "Tartışma kategorileri", (NewDiscussion, En) => "New discussion", (NewDiscussion, Tr) => "Yeni tartışma", (NoDiscussionsYet, En) => "No discussions here yet.", (NoDiscussionsYet, Tr) => "Henüz tartışma yok.", (Discussions, En) => "Discussions", (Discussions, Tr) => "Tartışmalar", (Newer, En) => "Newer", (Newer, Tr) => "Daha yeni", (Older, En) => "Older", (Older, Tr) => "Daha eski", (Category, En) => "Category", (Category, Tr) => "Kategori", (Title, En) => "Title", (Title, Tr) => "Başlık", (Description, En) => "Description", (Description, Tr) => "Açıklama", (MarkdownSupported, En) => "Markdown supported.", (MarkdownSupported, Tr) => "Markdown desteklenir.", (StartDiscussion, En) => "Start discussion", (StartDiscussion, Tr) => "Tartışma başlat", (Cancel, En) => "Cancel", (Cancel, Tr) => "İptal", (Save, En) => "Save", (Save, Tr) => "Kaydet", (Delete, En) => "Delete", (Delete, Tr) => "Sil", (Edit, En) => "Edit", (Edit, Tr) => "Düzenle", (EditComment, En) => "Edit comment", (EditComment, Tr) => "Yorumu düzenle", (CouldNotSave, En) => "Could not save", (CouldNotSave, Tr) => "Kaydedilemedi", (CommentDeleted, En) => "Comment deleted", (CommentDeleted, Tr) => "Yorum silindi", (Answer, En) => "Answer", (Answer, Tr) => "Cevap", (MarkAsAnswer, En) => "Mark as answer", (MarkAsAnswer, Tr) => "Cevap olarak işaretle", (UnmarkAnswer, En) => "Unmark answer", (UnmarkAnswer, Tr) => "Cevap işaretini kaldır", (Reply, En) => "Reply", (Reply, Tr) => "Yanıtla", (DeleteDiscussion, En) => "Delete discussion", (DeleteDiscussion, Tr) => "Tartışmayı sil", (Conversation, En) => "Conversation", (Conversation, Tr) => "Konuşma", (LockConversation, En) => "Lock conversation", (LockConversation, Tr) => "Konuşmayı kilitle", (UnlockConversation, En) => "Unlock conversation", (UnlockConversation, Tr) => "Konuşmanın kilidini aç", (Answered, En) => "Answered", (Answered, Tr) => "Cevaplandı", (Locked, En) => "Locked", (Locked, Tr) => "Kilitli", (OpenedThis, En) => " opened this ", (OpenedThis, Tr) => " tarafından ", (OpenedSeparator, En) => " · ", (OpenedSeparator, Tr) => " açıldı · ", (NoDescription, En) => "_No description provided._", (NoDescription, Tr) => "_Açıklama eklenmedi._", (LockedNotice, En) => { "This conversation is locked. Only people with Triage access can comment." } (LockedNotice, Tr) => { "Bu konuşma kilitli. Yorum yalnızca Triage erişimi olanlar tarafından yapılabilir." } (AddComment, En) => "Add a comment", (AddComment, Tr) => "Yorum ekle", (CommentButton, En) => "Comment", (CommentButton, Tr) => "Yorum yap", (LogInLink, En) => "Log in", (LogInLink, Tr) => "giriş yapın", (ToCommentSuffix, En) => " to comment.", (ToCommentSuffix, Tr) => ".", (ArchivedDiscussions, En) => { "This repository is archived, so its discussions are read-only." } (ArchivedDiscussions, Tr) => "Bu depo arşivlendiği için tartışmalar salt okunur.", (DiscussionsDescription, En) => { "A forum for questions, ideas and announcements, next to issues. Off by default. Turning it off hides the tab; existing discussions are kept." } (DiscussionsDescription, Tr) => { "Sorunların yanında sorular, fikirler ve duyurular için bir forum. Varsayılan olarak kapalıdır. Kapatıldığında sekme gizlenir; mevcut tartışmalar korunur." } (TurnOffDiscussions, En) => "Turn off discussions", (TurnOffDiscussions, Tr) => "Tartışmaları kapat", (TurnOnDiscussions, En) => "Turn on discussions", (TurnOnDiscussions, Tr) => "Tartışmaları aç", (CategoryGeneral, En) => "General", (CategoryGeneral, Tr) => "Genel", (CategoryIdeas, En) => "Ideas", (CategoryIdeas, Tr) => "Fikirler", (CategoryQa, En) => "Q&A", (CategoryQa, Tr) => "Soru-cevap", (CategoryAnnouncements, En) => "Announcements", (CategoryAnnouncements, Tr) => "Duyurular", (Wiki, En) => "Wiki", (Wiki, Tr) => "Wiki", (Home, En) => "Home", (Home, Tr) => "Ana sayfa", (AllPages, En) => "All pages", (AllPages, Tr) => "Tüm sayfalar", (NewPage, En) => "New page", (NewPage, Tr) => "Yeni sayfa", (History, En) => "History", (History, Tr) => "Geçmiş", (PageNav, En) => "Page", (PageNav, Tr) => "Sayfa", (WikiNoPages, En) => "This wiki has no pages yet.", (WikiNoPages, Tr) => "Bu wiki'de henüz sayfa yok.", (CreateFirstPage, En) => "Create the first page", (CreateFirstPage, Tr) => "İlk sayfayı oluştur", (NoPagesYet, En) => "No pages yet.", (NoPagesYet, Tr) => "Henüz sayfa yok.", (BackToPage, En) => "Back to page", (BackToPage, Tr) => "Sayfaya dön", (NoChangesYet, En) => "No changes yet.", (NoChangesYet, Tr) => "Henüz değişiklik yok.", (PageName, En) => "Page name", (PageName, Tr) => "Sayfa adı", (PageNameHint, En) => "Letters, digits, - and _. Dashes show as spaces in titles.", (PageNameHint, Tr) => "Harfler, rakamlar, - ve _. Başlıkta tireler boşluk olarak görünür.", (ContentMarkdown, En) => "Content (Markdown)", (ContentMarkdown, Tr) => "İçerik (Markdown)", (WikiLinkHint, En) => "Link to another page with [[Page-Name]] or [[Label|Page-Name]].", (WikiLinkHint, Tr) => { "Başka bir sayfaya [[Sayfa-Adı]] ya da [[Etiket|Sayfa-Adı]] biçiminde bağlantı verin." } (Summary, En) => "Summary", (Summary, Tr) => "Özet", (SavePage, En) => "Save page", (SavePage, Tr) => "Sayfayı kaydet", (PageNameRules, En) => "Page names use letters, digits, - and _, up to 100 characters.", (PageNameRules, Tr) => { "Sayfa adları harf, rakam, - ve _ içerebilir; en fazla 100 karakter olabilir." } (PageExists, En) => "A page with that name already exists. Edit it instead.", (PageExists, Tr) => "Bu adla bir sayfa zaten var. Bunun yerine onu düzenleyin.", (WikiConflict, En) => { "Someone else saved this wiki while you were editing. Your text is kept below; copy it, reload the page, and save again." } (WikiConflict, Tr) => { "Siz düzenlerken başka biri bu wiki'yi kaydetti. Metniniz aşağıda duruyor; kopyalayın, sayfayı yenileyin ve yeniden kaydedin." } (WikiSettings, En) => "Wiki settings", (WikiSettings, Tr) => "Wiki ayarları", (EnableWiki, En) => "Enable the wiki", (EnableWiki, Tr) => "Wiki'yi etkinleştir", (WikiDisabledHint, En) => { "A disabled wiki is hidden and refuses edits and pushes. Its pages are kept." } (WikiDisabledHint, Tr) => { "Devre dışı bir wiki gizlenir; düzenlemelerini ve göndermelerini kabul etmez. Sayfaları korunur." } (WikiPages, En) => "Wiki pages", (WikiPages, Tr) => "Wiki sayfaları", (Snippets, En) => "Snippets", (Snippets, Tr) => "Parçacıklar", (NewSnippet, En) => "New snippet", (NewSnippet, Tr) => "Yeni parçacık", (NoSnippets, En) => "No snippets to show.", (NoSnippets, Tr) => "Gösterilecek parçacık yok.", (Visibility, En) => "Visibility", (Visibility, Tr) => "Görünürlük", (VisibilityPublic, En) => "Public", (VisibilityPublic, Tr) => "Herkese açık", (VisibilityUnlisted, En) => "Unlisted", (VisibilityUnlisted, Tr) => "Listelenmez", (VisibilityPrivate, En) => "Private", (VisibilityPrivate, Tr) => "Özel", (PublicOption, En) => "Public: listed on /snippets", (PublicOption, Tr) => "Herkese açık: /snippets üzerinde listelenir", (UnlistedOption, En) => "Unlisted: anyone with the link", (UnlistedOption, Tr) => "Listelenmez: bağlantıya sahip herkes", (PrivateOption, En) => "Private: only you", (PrivateOption, Tr) => "Özel: yalnızca siz", (FileLabel, En) => "File ", (FileLabel, Tr) => "Dosya ", (FileNamePlaceholder, En) => "file name, for example notes.md", (FileNamePlaceholder, Tr) => "dosya adı, örneğin notes.md", (FileName, En) => "File name", (FileName, Tr) => "Dosya adı", (FileContents, En) => "File contents", (FileContents, Tr) => "Dosya içeriği", (Untitled, En) => "untitled", (Untitled, Tr) => "adsız", (Files, En) => "Files", (Files, Tr) => "Dosyalar", (SnippetTitlePlaceholder, En) => "Snippet title", (SnippetTitlePlaceholder, Tr) => "Parçacık başlığı", (DescriptionOptional, En) => "Description (optional)", (DescriptionOptional, Tr) => "Açıklama (isteğe bağlı)", (AddFile, En) => "Add file", (AddFile, Tr) => "Dosya ekle", (RemoveFile, En) => "Remove file", (RemoveFile, Tr) => "Dosyayı kaldır", (SaveSnippet, En) => "Save snippet", (SaveSnippet, Tr) => "Parçacığı kaydet", (EditSnippet, En) => "Edit snippet", (EditSnippet, Tr) => "Parçacığı düzenle", (Raw, En) => "Raw", (Raw, Tr) => "Ham", (SnippetNav, En) => "Snippet", (SnippetNav, Tr) => "Parçacık", (FileNav, En) => "File", (FileNav, Tr) => "Dosya", (OnlyOwnerEdits, En) => "Only the owner can edit this snippet.", (OnlyOwnerEdits, Tr) => "Bu parçacığı yalnızca sahibi düzenleyebilir.", (Revisions, En) => "Revisions", (Revisions, Tr) => "Revizyonlar", (BackToSnippet, En) => "Back to the snippet", (BackToSnippet, Tr) => "Parçacığa dön", (NoRevisions, En) => "No revisions.", (NoRevisions, Tr) => "Revizyon yok.", (RevisionLabel, En) => "Revision ", (RevisionLabel, Tr) => "Revizyon ", (ChooseVisibility, En) => "Choose a visibility.", (ChooseVisibility, Tr) => "Bir görünürlük seçin.", } } /// The name of a discussion category, as the list, the form and the discussion show it. pub fn category_label(lang: Lang, category: DiscussionCategory) -> &'static str { match category { DiscussionCategory::General => t(lang, K::CategoryGeneral), DiscussionCategory::Ideas => t(lang, K::CategoryIdeas), DiscussionCategory::Qa => t(lang, K::CategoryQa), DiscussionCategory::Announcements => t(lang, K::CategoryAnnouncements), } } /// The byline of a discussion row, split around the author and the time. English reads /// `by Ali 3 days ago`; Turkish reads `Ali tarafından 3 gün önce açıldı`. Returns the text /// before the author, between the author and the time, and after the time. pub fn byline(lang: Lang) -> (&'static str, &'static str, &'static str) { match lang { Lang::En => (" by ", " ", ""), Lang::Tr => ("", " tarafından ", " açıldı"), } } /// `Page 3` / `Sayfa 3`. pub fn page_number(lang: Lang, page: u32) -> String { match lang { Lang::En => format!("Page {page}"), Lang::Tr => format!("Sayfa {page}"), } } /// `1 comment` / `3 comments` in a list row, and `3 yorum` in Turkish. pub fn comments_count(lang: Lang, count: i64) -> String { match lang { Lang::En => format!("{count} comment{}", if count == 1 { "" } else { "s" }), Lang::Tr => format!("{count} yorum"), } } /// `1 comment` / `3 comments` in a discussion header, and `3 yorum` in Turkish. pub fn comments_total(lang: Lang, count: i64) -> String { match lang { Lang::En => format!("{count} comment{}", if count == 1 { "" } else { "s" }), Lang::Tr => format!("{count} yorum"), } } /// The text before the "Log in" link of a sign-in prompt. English has none. pub fn comment_login_lead(lang: Lang) -> &'static str { match lang { Lang::En => "", Lang::Tr => "Yorum yapmak için ", } } /// `The page is larger than 1048576 bytes.` / `Sayfa 1048576 bayttan büyük.` pub fn page_too_large(lang: Lang, max: usize) -> String { match lang { Lang::En => format!("The page is larger than {max} bytes."), Lang::Tr => format!("Sayfa {max} bayttan büyük."), } } /// `2 file(s) · updated 3 days ago` / `2 dosya · 3 gün önce güncellendi`. /// `updated 3 days ago` / `3 gün önce güncellendi`. pub fn updated_on(lang: Lang, updated: &str) -> String { match lang { Lang::En => format!("updated {updated}"), Lang::Tr => format!("{updated} güncellendi"), } } pub fn files_updated(lang: Lang, count: u64, updated: &str) -> String { match lang { Lang::En => format!("{count} file(s) · updated {updated}"), Lang::Tr => format!("{count} dosya · {updated} güncellendi"), } } /// `1 of 10 files · 1 MiB max` / `1 / 10 dosya · en fazla 1 MiB`. pub fn files_limit(lang: Lang, count: usize, max_files: usize, max_mib: usize) -> String { match lang { Lang::En => format!("{count} of {max_files} files · {max_mib} MiB max"), Lang::Tr => format!("{count} / {max_files} dosya · en fazla {max_mib} MiB"), } } /// `Revisions of Home` / `Home revizyonları`. pub fn revisions_of(lang: Lang, title: &str) -> String { match lang { Lang::En => format!("Revisions of {title}"), Lang::Tr => format!("{title} revizyonları"), } } #[cfg(test)] mod tests { use super::*; const ALL: &[K] = &[ K::AllCategories, K::CategoriesNav, K::NewDiscussion, K::NoDiscussionsYet, K::Discussions, K::Newer, K::Older, K::Category, K::Title, K::Description, K::MarkdownSupported, K::StartDiscussion, K::Cancel, K::Save, K::Delete, K::Edit, K::EditComment, K::CouldNotSave, K::CommentDeleted, K::Answer, K::MarkAsAnswer, K::UnmarkAnswer, K::Reply, K::DeleteDiscussion, K::Conversation, K::LockConversation, K::UnlockConversation, K::Answered, K::Locked, K::OpenedThis, K::OpenedSeparator, K::NoDescription, K::LockedNotice, K::AddComment, K::CommentButton, K::LogInLink, K::ToCommentSuffix, K::ArchivedDiscussions, K::DiscussionsDescription, K::TurnOffDiscussions, K::TurnOnDiscussions, K::CategoryGeneral, K::CategoryIdeas, K::CategoryQa, K::CategoryAnnouncements, K::Wiki, K::Home, K::AllPages, K::NewPage, K::History, K::PageNav, K::WikiNoPages, K::CreateFirstPage, K::NoPagesYet, K::BackToPage, K::NoChangesYet, K::PageName, K::PageNameHint, K::ContentMarkdown, K::WikiLinkHint, K::Summary, K::SavePage, K::PageNameRules, K::PageExists, K::WikiConflict, K::WikiSettings, K::EnableWiki, K::WikiDisabledHint, K::WikiPages, K::Snippets, K::NewSnippet, K::NoSnippets, K::Visibility, K::VisibilityPublic, K::VisibilityUnlisted, K::VisibilityPrivate, K::PublicOption, K::UnlistedOption, K::PrivateOption, K::FileLabel, K::FileNamePlaceholder, K::FileName, K::FileContents, K::Untitled, K::Files, K::SnippetTitlePlaceholder, K::DescriptionOptional, K::AddFile, K::RemoveFile, K::SaveSnippet, K::EditSnippet, K::Raw, K::SnippetNav, K::FileNav, K::OnlyOwnerEdits, K::Revisions, K::BackToSnippet, K::NoRevisions, K::RevisionLabel, K::ChooseVisibility, ]; #[test] fn every_key_has_both_languages() { for key in ALL { assert!(!t(Lang::En, *key).is_empty(), "{key:?} has no English"); assert!(!t(Lang::Tr, *key).is_empty(), "{key:?} has no Turkish"); } } #[test] fn turkish_differs_from_english() { let differing = ALL .iter() .filter(|key| t(Lang::En, **key) != t(Lang::Tr, **key)) .count(); assert!(differing >= 3, "only {differing} keys differ"); assert_eq!(t(Lang::Tr, K::NewDiscussion), "Yeni tartışma"); assert_eq!(t(Lang::En, K::NewDiscussion), "New discussion"); } #[test] fn counts_and_sentences_follow_the_language() { assert_eq!(comments_count(Lang::En, 1), "1 comment"); assert_eq!(comments_count(Lang::En, 3), "3 comments"); assert_eq!(comments_count(Lang::Tr, 3), "3 yorum"); assert_eq!(page_number(Lang::Tr, 2), "Sayfa 2"); assert_eq!(files_updated(Lang::En, 2, "now"), "2 file(s) · updated now"); } }