//! Strings for the code group: repo browsing, commits, refs, diffs, archives, code search, //! star and fork. One `K` variant per phrase, an exhaustive `t` match, and helpers for //! sentences that carry arguments. use forge_core::store::commit_status::StatusState; use super::Lang; #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum K { SearchWord, SearchFailed, SearchCodePlaceholder, SearchButton, RefField, PathField, MatchCase, RegexOption, SearchFilesAt, NoMatches, ShowingFirst, ShowingFirstEnd, CloneTitle, SshRequiresKey, BranchesTitle, EmptyRepoPush, OverHttps, OverSsh, DownloadNav, DownloadZip, DownloadTarGz, RecentPushes, HadRecentPushes, CompareAndPr, BranchLabel, NameHeader, LastCommitHeader, AgeHeader, KindDir, KindFile, KindExec, KindLink, KindSubmodule, Rendered, SourceToggle, HistoryLink, RawLink, DownloadLink, FileNav, SymlinkPrefix, SubmodulePrefix, SubmoduleSuffix, TruncatedPrefix, ViewFullRaw, StatusAdded, StatusDeleted, StatusModified, StatusRenamed, StatusCopied, StatusTypeChanged, NoFileChanges, BinaryFileChanged, DiffTooLargePrefix, ViewFile, DiffTooLarge, CommentOnLine, AddReviewComment, StartReview, CommentLabel, AddSingleComment, CancelLink, ThisCommit, CommitStatusPrefix, StateSuccess, StateFailure, StateError, StatePending, NoChecksReported, AllChecksPassed, ChecksPending, SomeChecksFailed, ShowChecks, DetailsLink, AuthorLabel, CommitterLabel, RootCommit, ParentLabel, BrowseFiles, SigVerified, SigUnverified, CommitsOn, FilteredTo, ClearFilter, NoCommits, Committed, BrowseFilesShort, NewerLink, OlderLink, NothingHere, DefaultBadge, TagsTitle, TagKindLabel, ForkedFrom, MirrorOf, NotSyncedYet, ForkButton, StarsAria, ArchivedNotice, RepositoryNav, TabIssues, TabPulls, TabCommits, TabReleases, TabCi, TabDiscussions, TabWiki, TabSettings, } pub fn t(lang: Lang, key: K) -> &'static str { use K::*; use Lang::*; match (key, lang) { (SearchWord, En) => "search", (SearchWord, Tr) => "arama", (SearchFailed, En) => { "The search could not run. Check the pattern; regex mode uses extended regular expressions." } (SearchFailed, Tr) => { "Arama çalıştırılamadı. Deseni kontrol edin; regex kipi genişletilmiş düzenli ifadeleri kullanır." } (SearchCodePlaceholder, En) => "Search code", (SearchCodePlaceholder, Tr) => "Kodda ara", (SearchButton, En) => "Search", (SearchButton, Tr) => "Ara", (RefField, En) => "Ref ", (RefField, Tr) => "Referans ", (PathField, En) => "Path ", (PathField, Tr) => "Yol ", (MatchCase, En) => " Match case", (MatchCase, Tr) => " Büyük/küçük harfe duyarlı", (RegexOption, En) => " Regex", (RegexOption, Tr) => " Düzenli ifade", (SearchFilesAt, En) => "Search the files at ", (SearchFilesAt, Tr) => "Dosyaları şurada ara: ", (NoMatches, En) => "No matches.", (NoMatches, Tr) => "Eşleşme yok.", (ShowingFirst, En) => " (showing the first ", (ShowingFirst, Tr) => " (ilk ", (ShowingFirstEnd, En) => ")", (ShowingFirstEnd, Tr) => " gösteriliyor)", (CloneTitle, En) => "Clone", (CloneTitle, Tr) => "Klonla", (SshRequiresKey, En) => "SSH (requires an ed25519 or ECDSA key on your account)", (SshRequiresKey, Tr) => "SSH (hesabınızda bir ed25519 veya ECDSA anahtarı olmalı)", (BranchesTitle, En) => "Branches", (BranchesTitle, Tr) => "Dallar", (EmptyRepoPush, En) => "This repository is empty. Push a branch to get started:", (EmptyRepoPush, Tr) => "Bu depo boş. Başlamak için bir dal gönderin:", (OverHttps, En) => "Over HTTPS", (OverHttps, Tr) => "HTTPS üzerinden", (OverSsh, En) => "Over SSH", (OverSsh, Tr) => "SSH üzerinden", (DownloadNav, En) => "Download", (DownloadNav, Tr) => "İndir", (DownloadZip, En) => "Download ZIP", (DownloadZip, Tr) => "ZIP olarak indir", (DownloadTarGz, En) => "Download tar.gz", (DownloadTarGz, Tr) => "tar.gz olarak indir", (RecentPushes, En) => "Recent pushes", (RecentPushes, Tr) => "Son gönderimler", (HadRecentPushes, En) => " had recent pushes ", (HadRecentPushes, Tr) => " dalına son zamanlarda gönderim yapıldı ", (CompareAndPr, En) => "Compare & pull request", (CompareAndPr, Tr) => "Karşılaştır ve çekme isteği aç", (BranchLabel, En) => "Branch", (BranchLabel, Tr) => "Dal", (NameHeader, En) => "Name", (NameHeader, Tr) => "Ad", (LastCommitHeader, En) => "Last commit", (LastCommitHeader, Tr) => "Son commit", (AgeHeader, En) => "Age", (AgeHeader, Tr) => "Zaman", (KindDir, En) => "dir", (KindDir, Tr) => "dizin", (KindFile, En) => "file", (KindFile, Tr) => "dosya", (KindExec, En) => "exec", (KindExec, Tr) => "çalıştırılabilir", (KindLink, En) => "link", (KindLink, Tr) => "bağlantı", (KindSubmodule, En) => "submodule", (KindSubmodule, Tr) => "alt modül", (Rendered, En) => "Rendered", (Rendered, Tr) => "Önizleme", (SourceToggle, En) => "Source", (SourceToggle, Tr) => "Kaynak", (HistoryLink, En) => "History", (HistoryLink, Tr) => "Geçmiş", (RawLink, En) => "Raw", (RawLink, Tr) => "Ham", (DownloadLink, En) => "Download", (DownloadLink, Tr) => "İndir", (FileNav, En) => "File", (FileNav, Tr) => "Dosya", (SymlinkPrefix, En) => "Symbolic link → ", (SymlinkPrefix, Tr) => "Sembolik bağlantı → ", (SubmodulePrefix, En) => "Submodule at commit ", (SubmodulePrefix, Tr) => "Alt modül, şu commit'te: ", (SubmoduleSuffix, En) => ". Its contents are not in this repository.", (SubmoduleSuffix, Tr) => ". İçeriği bu depoda yok.", (TruncatedPrefix, En) => "Showing the first 1 MiB of this file. ", (TruncatedPrefix, Tr) => "Bu dosyanın ilk 1 MiB'ı gösteriliyor. ", (ViewFullRaw, En) => "View the full file raw", (ViewFullRaw, Tr) => "Dosyanın tamamını ham olarak görüntüle", (StatusAdded, En) => "added", (StatusAdded, Tr) => "eklendi", (StatusDeleted, En) => "deleted", (StatusDeleted, Tr) => "silindi", (StatusModified, En) => "modified", (StatusModified, Tr) => "değiştirildi", (StatusRenamed, En) => "renamed", (StatusRenamed, Tr) => "yeniden adlandırıldı", (StatusCopied, En) => "copied", (StatusCopied, Tr) => "kopyalandı", (StatusTypeChanged, En) => "type changed", (StatusTypeChanged, Tr) => "tür değiştirildi", (NoFileChanges, En) => "No file changes.", (NoFileChanges, Tr) => "Dosya değişikliği yok.", (BinaryFileChanged, En) => "Binary file changed", (BinaryFileChanged, Tr) => "İkili dosya değiştirildi", (DiffTooLargePrefix, En) => "Diff too large; ", (DiffTooLargePrefix, Tr) => "Fark çok büyük; ", (ViewFile, En) => "view file", (ViewFile, Tr) => "dosyayı görüntüle", (DiffTooLarge, En) => "Diff too large.", (DiffTooLarge, Tr) => "Fark çok büyük.", (CommentOnLine, En) => "Comment on this line", (CommentOnLine, Tr) => "Bu satıra yorum yap", (AddReviewComment, En) => "Add review comment", (AddReviewComment, Tr) => "İnceleme yorumu ekle", (StartReview, En) => "Start a review", (StartReview, Tr) => "İnceleme başlat", (CommentLabel, En) => "Comment", (CommentLabel, Tr) => "Yorum", (AddSingleComment, En) => "Add single comment", (AddSingleComment, Tr) => "Tek yorum ekle", (CancelLink, En) => "Cancel", (CancelLink, Tr) => "İptal", (ThisCommit, En) => "this commit", (ThisCommit, Tr) => "bu commit", (CommitStatusPrefix, En) => "Commit status: ", (CommitStatusPrefix, Tr) => "Commit durumu: ", (StateSuccess, En) => "success", (StateSuccess, Tr) => "başarılı", (StateFailure, En) => "failure", (StateFailure, Tr) => "başarısız", (StateError, En) => "error", (StateError, Tr) => "hata", (StatePending, En) => "pending", (StatePending, Tr) => "bekliyor", (NoChecksReported, En) => "No checks reported", (NoChecksReported, Tr) => "Hiç kontrol bildirilmedi", (AllChecksPassed, En) => "All checks have passed", (AllChecksPassed, Tr) => "Tüm kontroller geçti", (ChecksPending, En) => "Checks pending", (ChecksPending, Tr) => "Kontroller bekliyor", (SomeChecksFailed, En) => "Some checks failed", (SomeChecksFailed, Tr) => "Bazı kontroller başarısız oldu", (ShowChecks, En) => "Show checks", (ShowChecks, Tr) => "Kontrolleri göster", (DetailsLink, En) => "Details", (DetailsLink, Tr) => "Ayrıntılar", (AuthorLabel, En) => "Author ", (AuthorLabel, Tr) => "Yazar ", (CommitterLabel, En) => "Committer ", (CommitterLabel, Tr) => "Commit eden ", (RootCommit, En) => "Root commit (no parents)", (RootCommit, Tr) => "Kök commit (üst commit yok)", (ParentLabel, En) => "Parent: ", (ParentLabel, Tr) => "Üst commit: ", (BrowseFiles, En) => "Browse files at this commit", (BrowseFiles, Tr) => "Bu commit'teki dosyalara göz at", (SigVerified, En) => "Verified", (SigVerified, Tr) => "Doğrulandı", (SigUnverified, En) => "Unverified", (SigUnverified, Tr) => "Doğrulanmadı", (CommitsOn, En) => "Commits on ", (CommitsOn, Tr) => "Referanstaki commit'ler: ", (FilteredTo, En) => "Filtered to ", (FilteredTo, Tr) => "Şuna göre filtrelendi: ", (ClearFilter, En) => "Clear filter", (ClearFilter, Tr) => "Filtreyi temizle", (NoCommits, En) => "No commits.", (NoCommits, Tr) => "Commit yok.", (Committed, En) => "committed", (Committed, Tr) => "commit etti", (BrowseFilesShort, En) => "Browse files", (BrowseFilesShort, Tr) => "Dosyalara göz at", (NewerLink, En) => "Newer", (NewerLink, Tr) => "Daha yeni", (OlderLink, En) => "Older", (OlderLink, Tr) => "Daha eski", (NothingHere, En) => "Nothing here yet.", (NothingHere, Tr) => "Henüz burada bir şey yok.", (DefaultBadge, En) => "default", (DefaultBadge, Tr) => "varsayılan", (TagsTitle, En) => "Tags", (TagsTitle, Tr) => "Etiketler", (TagKindLabel, En) => "Tag", (TagKindLabel, Tr) => "Etiket", (ForkedFrom, En) => "forked from ", (ForkedFrom, Tr) => "Şu depodan çatallandı: ", (MirrorOf, En) => "Mirror of ", (MirrorOf, Tr) => "Yansı kaynağı: ", (NotSyncedYet, En) => "not synced yet", (NotSyncedYet, Tr) => "henüz eşitlenmedi", (ForkButton, En) => "Fork", (ForkButton, Tr) => "Çatalla", (StarsAria, En) => "Stars", (StarsAria, Tr) => "Yıldızlar", (ArchivedNotice, En) => "This repository is archived. It is read-only.", (ArchivedNotice, Tr) => "Bu depo arşivlendi. Salt okunurdur.", (RepositoryNav, En) => "Repository", (RepositoryNav, Tr) => "Depo", (TabIssues, En) => "Issues", (TabIssues, Tr) => "Sorunlar", (TabPulls, En) => "Pull requests", (TabPulls, Tr) => "Çekme istekleri", (TabCommits, En) => "Commits", (TabCommits, Tr) => "Commitler", (TabReleases, En) => "Releases", (TabReleases, Tr) => "Sürümler", (TabCi, En) => "CI", (TabCi, Tr) => "CI", (TabDiscussions, En) => "Discussions", (TabDiscussions, Tr) => "Tartışmalar", (TabWiki, En) => "Wiki", (TabWiki, Tr) => "Wiki", (TabSettings, En) => "Settings", (TabSettings, Tr) => "Ayarlar", } } /// `N match(es) in M file(s)` in English, `N eşleşme, M dosyada` in Turkish. pub fn match_summary(lang: Lang, matches: usize, files: usize) -> String { match lang { Lang::En => format!( "{matches} match{} in {files} file{}", if matches == 1 { "" } else { "es" }, if files == 1 { "" } else { "s" }, ), Lang::Tr => format!("{matches} eşleşme, {files} dosyada"), } } /// The notice for a repo with no commits on its default branch. pub fn empty_repo_message(lang: Lang, branch: &str) -> String { match lang { Lang::En => format!("This repository has no commits on {branch}. Nothing to search yet."), Lang::Tr => { format!("Bu depoda {branch} dalında commit yok. Henüz aranacak bir şey yok.") } } } /// The label shown for a directory-listing row kind. Kinds without a translation show as they are. pub fn kind_label(lang: Lang, kind: &'static str) -> &'static str { let key = match kind { "dir" => K::KindDir, "file" => K::KindFile, "exec" => K::KindExec, "link" => K::KindLink, "submodule" => K::KindSubmodule, _ => return kind, }; t(lang, key) } /// The note for a file stored with Git LFS, with its size. pub fn lfs_stored(lang: Lang, size: &str) -> String { match lang { Lang::En => format!("Stored with Git LFS ({size})"), Lang::Tr => format!("Git LFS ile saklanıyor ({size})"), } } /// The note for a Git LFS file whose object this forge does not have. pub fn lfs_missing(lang: Lang, size: &str) -> String { match lang { Lang::En => { format!("Stored with Git LFS ({size}), but this forge does not have the object") } Lang::Tr => { format!("Git LFS ile saklanıyor ({size}), ancak bu forge sunucusunda bu nesne yok") } } } /// The note for a binary file, with its size in bytes. pub fn binary_note(lang: Lang, bytes: impl std::fmt::Display) -> String { match lang { Lang::En => format!("Binary file, {bytes} bytes"), Lang::Tr => format!("İkili dosya, {bytes} bayt"), } } /// `N changed file(s)` in English, `N dosya değişti` in Turkish. pub fn changed_files(lang: Lang, count: usize) -> String { match lang { Lang::En => format!("{count} changed file{}", if count == 1 { "" } else { "s" }), Lang::Tr => format!("{count} dosya değişti"), } } /// The note that a diff stops at `max` files. `subject` names what the diff shows. pub fn diff_truncated(lang: Lang, max: usize, subject: &str) -> String { match lang { Lang::En => format!("Showing the first {max} files; {subject} changes more."), Lang::Tr => { format!("İlk {max} dosya gösteriliyor; {subject} daha fazla değişiklik içeriyor.") } } } /// The word for a commit status state, as the status title and the checks line use it. pub fn state_word(lang: Lang, state: StatusState) -> &'static str { let key = match state { StatusState::Pending => K::StatePending, StatusState::Success => K::StateSuccess, StatusState::Failure => K::StateFailure, StatusState::Error => K::StateError, }; t(lang, key) } /// `Signed by with ` in English, the Turkish equivalent otherwise. pub fn signed_by(lang: Lang, signer: &str, key: &str) -> String { match lang { Lang::En => format!("Signed by {signer} with {key}"), Lang::Tr => format!("{signer} tarafından {key} ile imzalandı"), } } /// `Page ` for the commit list pager. pub fn page_label(lang: Lang, page: u32) -> String { match lang { Lang::En => format!("Page {page}"), Lang::Tr => format!("Sayfa {page}"), } } /// The star button label: `Unstar ` when starred, `★ Star ` otherwise. pub fn star_label(lang: Lang, starred: bool, stars: u64) -> String { match (lang, starred) { (Lang::En, true) => format!("Unstar {stars}"), (Lang::En, false) => format!("\u{2605} Star {stars}"), (Lang::Tr, true) => format!("Yıldızı kaldır {stars}"), (Lang::Tr, false) => format!("\u{2605} Yıldızla {stars}"), } } /// ` watching` in English, ` izleyici` in Turkish. pub fn watching_count(lang: Lang, watchers: u64) -> String { match lang { Lang::En => format!("{watchers} watching"), Lang::Tr => format!("{watchers} izleyici"), } } /// The mirror status after a successful sync. pub fn mirror_synced(lang: Lang, at: &str) -> String { match lang { Lang::En => format!("last synced {at}"), Lang::Tr => format!("son eşitleme: {at}"), } } /// The mirror status after a failed sync. pub fn mirror_sync_failed(lang: Lang, at: &str) -> String { match lang { Lang::En => format!("last sync {at} failed"), Lang::Tr => format!("son eşitleme {at} başarısız oldu"), } } #[cfg(test)] mod tests { use super::*; const ALL: &[K] = &[ K::SearchWord, K::SearchFailed, K::SearchCodePlaceholder, K::SearchButton, K::RefField, K::PathField, K::MatchCase, K::RegexOption, K::SearchFilesAt, K::NoMatches, K::ShowingFirst, K::ShowingFirstEnd, K::CloneTitle, K::SshRequiresKey, K::BranchesTitle, K::EmptyRepoPush, K::OverHttps, K::OverSsh, K::DownloadNav, K::DownloadZip, K::DownloadTarGz, K::RecentPushes, K::HadRecentPushes, K::CompareAndPr, K::BranchLabel, K::NameHeader, K::LastCommitHeader, K::AgeHeader, K::KindDir, K::KindFile, K::KindExec, K::KindLink, K::KindSubmodule, K::Rendered, K::SourceToggle, K::HistoryLink, K::RawLink, K::DownloadLink, K::FileNav, K::SymlinkPrefix, K::SubmodulePrefix, K::SubmoduleSuffix, K::TruncatedPrefix, K::ViewFullRaw, K::StatusAdded, K::StatusDeleted, K::StatusModified, K::StatusRenamed, K::StatusCopied, K::StatusTypeChanged, K::NoFileChanges, K::BinaryFileChanged, K::DiffTooLargePrefix, K::ViewFile, K::DiffTooLarge, K::CommentOnLine, K::AddReviewComment, K::StartReview, K::CommentLabel, K::AddSingleComment, K::CancelLink, K::ThisCommit, K::CommitStatusPrefix, K::StateSuccess, K::StateFailure, K::StateError, K::StatePending, K::NoChecksReported, K::AllChecksPassed, K::ChecksPending, K::SomeChecksFailed, K::ShowChecks, K::DetailsLink, K::AuthorLabel, K::CommitterLabel, K::RootCommit, K::ParentLabel, K::BrowseFiles, K::SigVerified, K::SigUnverified, K::CommitsOn, K::FilteredTo, K::ClearFilter, K::NoCommits, K::Committed, K::BrowseFilesShort, K::NewerLink, K::OlderLink, K::NothingHere, K::DefaultBadge, K::TagsTitle, K::TagKindLabel, K::ForkedFrom, K::MirrorOf, K::NotSyncedYet, K::ForkButton, K::StarsAria, K::ArchivedNotice, K::RepositoryNav, K::TabIssues, K::TabPulls, K::TabCommits, K::TabReleases, K::TabCi, K::TabDiscussions, K::TabWiki, K::TabSettings, ]; #[test] fn every_key_has_text_in_both_languages() { for key in ALL { assert!(!t(Lang::En, *key).is_empty(), "{key:?} has no English text"); assert!(!t(Lang::Tr, *key).is_empty(), "{key:?} has no Turkish text"); } } #[test] fn all_lists_each_key_once() { for (i, key) in ALL.iter().enumerate() { assert!(!ALL[i + 1..].contains(key), "{key:?} is listed twice"); } } #[test] fn turkish_differs_from_english_for_several_keys() { let differing = ALL .iter() .filter(|key| t(Lang::En, **key) != t(Lang::Tr, **key)) .count(); assert!(differing >= 3, "only {differing} keys differ"); } }