//! Strings for the admin pages: users, replication, backups, mail, CI runners and the audit log. //! See `docs` in `super` for the pattern. use forge_core::mail::OutboxStatus; use forge_core::store::backup_runs::{RunKind, RunTrigger}; use super::Lang; #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum K { ActionLabel, ActorUsername, AddARunner, Administrator, AllActions, Anonymous, AtLeast12Chars, AuditIntro, AuditLog, BackToRunners, BackToUsers, BackupInterval, Backups, BackupsIntro, CiRunners, CopyTokenNow, CreateAUser, CreateRegistrationToken, CreateUser, Database, DatabaseErrorPrefix, DeleteAccountRest, DeletesAccount, DeleteUser, Directory, Disable, Disabled, Enable, Enabled, ErrAccountCannotBeDeleted, ErrBackupsNotConfigured, ErrChooseSecurity, ErrInvalidUsername, ErrNoAddressForTest, ErrPasswordTooLong, ErrPortRange, ErrReplicationNotConfigured, ErrTestNeedsMailOn, ErrTypeUsernameExactly, Filter, FromAddress, FromName, Fsck, Healthcheck, HealthcheckNotSet, HealthcheckSet, HealthcheckUrlInvalid, HealthError, HealthLagging, HealthNever, HealthOk, Interval, Invites, LastDbAttempt, LastDbSnapshotShipped, LastSeen, LastSuccess, Mail, MailHost, MailIntro, MailPort, MailSettingsSaved, MovedToGhost, NoEntries, NoPasswordStored, NoReposYet, NoRunnersYet, NoRunnerWithId, NoRunsYet, NothingQueued, Older, OwnLogIntro, PasswordStoredHint, RecentMessages, RecentRuns, ReconcileNow, ReconcileStarted, RegisterARunner, RegistrationToken, RemovedWithAccount, ReplacePrefix, ReplaceSuffix, Replication, ReplicationIntro, ReplicationOff, ReplicationTarget, Repos, Retention, Role, RoleAdmin, RoleOrganization, RoleUser, RunBackupNow, RunFsckNow, RunnerDeletedNotice, RunnerDisabledNotice, RunnerEnabledNotice, Runners, ScheduledBackupsOff, SecurityLogTitle, SecurityNone, SendMailCheckbox, SendTestMailToMe, Settings, SmtpServer, Standby, StatusFailed, StatusInProgress, StatusOk, TableActor, TableDetails, TableDuration, TableError, TableKind, TableLabels, TableLastError, TableName, TableQueued, TableRepo, TableResult, TableSize, TableStarted, TableState, TableStatus, TableSubject, TableTarget, TableTo, TableTries, TableTrigger, TableWhen, TestQueued, Token, TokenCreateFailed, TransferOrDeleteFirst, UnknownHost, Users, WhatHappens, } pub fn t(lang: Lang, key: K) -> &'static str { use K::*; use Lang::*; match (key, lang) { (ActionLabel, En) => "Action", (ActionLabel, Tr) => "İşlem", (ActorUsername, En) => "Actor username", (ActorUsername, Tr) => "Yapan kullanıcı adı", (AddARunner, En) => "Add a runner", (AddARunner, Tr) => "Çalıştırıcı ekle", (Administrator, En) => "Administrator", (Administrator, Tr) => "Yönetici", (AllActions, En) => "All actions", (AllActions, Tr) => "Tüm işlemler", (Anonymous, En) => "anonymous", (Anonymous, Tr) => "anonim", (AtLeast12Chars, En) => "At least 12 characters.", (AtLeast12Chars, Tr) => "En az 12 karakter.", (AuditIntro, En) => { "Security events across the instance, newest first. Times are in your timezone." } (AuditIntro, Tr) => { "Sunucudaki güvenlik olayları, en yeniden en eskiye sıralı. Saatler sizin saat diliminizde gösterilir." } (AuditLog, En) => "Audit log", (AuditLog, Tr) => "Denetim günlüğü", (BackToRunners, En) => "Back to runners", (BackToRunners, Tr) => "Çalıştırıcılara dön", (BackToUsers, En) => "Back to users", (BackToUsers, Tr) => "Kullanıcılara dön", (BackupInterval, En) => "Backup interval", (BackupInterval, Tr) => "Yedekleme aralığı", (Backups, En) => "Backups", (Backups, Tr) => "Yedeklemeler", (BackupsIntro, En) => { "Backup sets and integrity checks. Times are in your timezone. Settings come from the [backup] section of the config file." } (BackupsIntro, Tr) => { "Yedek kümeleri ve bütünlük denetimleri. Saatler sizin saat diliminizde gösterilir. Ayarlar, yapılandırma dosyasındaki [backup] bölümünden gelir." } (CiRunners, En) => "CI runners", (CiRunners, Tr) => "CI çalıştırıcıları", (CopyTokenNow, En) => { "Copy this token now. It is shown once and cannot be looked up again." } (CopyTokenNow, Tr) => { "Bu belirteci şimdi kopyalayın. Yalnızca bir kez gösterilir ve sonradan yeniden görüntülenemez." } (CreateAUser, En) => "Create a user", (CreateAUser, Tr) => "Kullanıcı oluştur", (CreateRegistrationToken, En) => "Create registration token", (CreateRegistrationToken, Tr) => "Kayıt belirteci oluştur", (CreateUser, En) => "Create user", (CreateUser, Tr) => "Kullanıcı oluştur", (Database, En) => "Database", (Database, Tr) => "Veritabanı", (DatabaseErrorPrefix, En) => "Database: ", (DatabaseErrorPrefix, Tr) => "Veritabanı: ", (DeleteAccountRest, En) => { ". Its sessions, SSH keys, access tokens and stars are removed. Its issues, comments and reviews stay and are shown as written by the deleted user. This cannot be undone." } (DeleteAccountRest, Tr) => { " hesabını siler. Oturumları, SSH anahtarları, erişim belirteçleri ve yıldızları kaldırılır. Sorunları, yorumları ve incelemeleri kalır; silinmiş kullanıcının adıyla gösterilir. Bu işlem geri alınamaz." } (DeletesAccount, En) => "This deletes the account ", (DeletesAccount, Tr) => "Bu işlem ", (DeleteUser, En) => "Delete user", (DeleteUser, Tr) => "Kullanıcıyı sil", (Directory, En) => "Directory", (Directory, Tr) => "Dizin", (Disable, En) => "Disable", (Disable, Tr) => "Devre dışı bırak", (Disabled, En) => "disabled", (Disabled, Tr) => "devre dışı", (Enable, En) => "Enable", (Enable, Tr) => "Etkinleştir", (Enabled, En) => "enabled", (Enabled, Tr) => "etkin", (ErrAccountCannotBeDeleted, En) => "this account cannot be deleted", (ErrAccountCannotBeDeleted, Tr) => "bu hesap silinemez", (ErrBackupsNotConfigured, En) => { "backups are not configured: set [backup] dir in the config file" } (ErrBackupsNotConfigured, Tr) => { "yedeklemeler yapılandırılmamış: yapılandırma dosyasında [backup] dir ayarını yapın" } (ErrChooseSecurity, En) => "choose a security option", (ErrChooseSecurity, Tr) => "bir güvenlik seçeneği seçin", (ErrInvalidUsername, En) => "invalid username", (ErrInvalidUsername, Tr) => "geçersiz kullanıcı adı", (ErrNoAddressForTest, En) => "your account has no email address to send the test to", (ErrNoAddressForTest, Tr) => { "hesabınızda test iletisinin gönderileceği bir e-posta adresi yok" } (ErrPasswordTooLong, En) => "password is too long", (ErrPasswordTooLong, Tr) => "parola çok uzun", (ErrPortRange, En) => "the port must be a number from 1 to 65535", (ErrPortRange, Tr) => "bağlantı noktası 1 ile 65535 arasında bir sayı olmalı", (ErrReplicationNotConfigured, En) => { "replication is not configured: set [replication] target in the config file" } (ErrReplicationNotConfigured, Tr) => { "çoğaltma yapılandırılmamış: yapılandırma dosyasında [replication] target ayarını yapın" } (ErrTestNeedsMailOn, En) => "turn mail on and save the settings before sending a test", (ErrTestNeedsMailOn, Tr) => "test göndermeden önce e-postayı açın ve ayarları kaydedin", (ErrTypeUsernameExactly, En) => "Type the username exactly to confirm.", (ErrTypeUsernameExactly, Tr) => "Onaylamak için kullanıcı adını tam olarak yazın.", (Filter, En) => "Filter", (Filter, Tr) => "Filtrele", (FromAddress, En) => "From address", (FromAddress, Tr) => "Gönderen adresi", (FromName, En) => "From name", (FromName, Tr) => "Gönderen adı", (Fsck, En) => "Fsck", (Fsck, Tr) => "Fsck", (Healthcheck, En) => "Healthcheck", (Healthcheck, Tr) => "Sağlık denetimi", (HealthcheckNotSet, En) => "not set", (HealthcheckNotSet, Tr) => "ayarlanmamış", (HealthcheckSet, En) => "set", (HealthcheckSet, Tr) => "ayarlı", (HealthcheckUrlInvalid, En) => "set (the URL is not valid)", (HealthcheckUrlInvalid, Tr) => "ayarlı (URL geçersiz)", (HealthError, En) => "error", (HealthError, Tr) => "hata", (HealthLagging, En) => "lagging", (HealthLagging, Tr) => "gecikmeli", (HealthNever, En) => "never replicated", (HealthNever, Tr) => "hiç çoğaltılmadı", (HealthOk, En) => "ok", (HealthOk, Tr) => "tamam", (Interval, En) => "Interval", (Interval, Tr) => "Aralık", (Invites, En) => "Invites", (Invites, Tr) => "Davetler", (LastDbAttempt, En) => "Last database attempt", (LastDbAttempt, Tr) => "Son veritabanı denemesi", (LastDbSnapshotShipped, En) => "Last database snapshot shipped", (LastDbSnapshotShipped, Tr) => "Son gönderilen veritabanı anlık görüntüsü", (LastSeen, En) => "Last seen", (LastSeen, Tr) => "Son görülme", (LastSuccess, En) => "Last success", (LastSuccess, Tr) => "Son başarı", (Mail, En) => "Mail", (Mail, Tr) => "E-posta", (MailHost, En) => "Host", (MailHost, Tr) => "Sunucu", (MailIntro, En) => { "Outgoing mail for password resets, verification and notifications. Mail is sent from a queue with retries; a message that keeps failing is marked as gave up." } (MailIntro, Tr) => { "Parola sıfırlama, doğrulama ve bildirimler için giden e-posta. E-postalar yeniden denemelerle bir kuyruktan gönderilir; sürekli başarısız olan bir ileti vazgeçildi olarak işaretlenir." } (MailPort, En) => "Port", (MailPort, Tr) => "Bağlantı noktası", (MailSettingsSaved, En) => "Mail settings saved.", (MailSettingsSaved, Tr) => "E-posta ayarları kaydedildi.", (MovedToGhost, En) => "Moved to the ghost user:", (MovedToGhost, Tr) => "Hayalet kullanıcıya taşınanlar:", (NoEntries, En) => "No entries.", (NoEntries, Tr) => "Kayıt yok.", (NoPasswordStored, En) => "No password is stored.", (NoPasswordStored, Tr) => "Kayıtlı parola yok.", (NoReposYet, En) => "No repos yet.", (NoReposYet, Tr) => "Henüz depo yok.", (NoRunnersYet, En) => "No runners registered yet.", (NoRunnersYet, Tr) => "Henüz kayıtlı çalıştırıcı yok.", (NoRunnerWithId, En) => "No runner has that id. Nothing was changed.", (NoRunnerWithId, Tr) => "Bu kimlikte bir çalıştırıcı yok. Hiçbir şey değiştirilmedi.", (NoRunsYet, En) => "No runs yet.", (NoRunsYet, Tr) => "Henüz çalıştırma yok.", (NothingQueued, En) => "Nothing has been queued yet.", (NothingQueued, Tr) => "Henüz kuyruğa alınmış bir şey yok.", (Older, En) => "Older", (Older, Tr) => "Daha eski", (OwnLogIntro, En) => { "Sign-ins, changes to your account and keys, and sessions you revoked. Times are in your timezone." } (OwnLogIntro, Tr) => { "Oturum açmalar, hesabınızdaki ve anahtarlarınızdaki değişiklikler ile iptal ettiğiniz oturumlar. Saatler sizin saat diliminizde gösterilir." } (PasswordStoredHint, En) => "A password is stored. Leave this blank to keep it.", (PasswordStoredHint, Tr) => { "Bir parola kayıtlı. Mevcut parolayı korumak için bu alanı boş bırakın." } (RecentMessages, En) => "Recent messages", (RecentMessages, Tr) => "Son iletiler", (RecentRuns, En) => "Recent runs", (RecentRuns, Tr) => "Son çalıştırmalar", (ReconcileNow, En) => "Reconcile now", (ReconcileNow, Tr) => "Şimdi uzlaştır", (ReconcileStarted, En) => "Reconcile started.", (ReconcileStarted, Tr) => "Uzlaştırma başlatıldı.", (RegisterARunner, En) => "Register a runner", (RegisterARunner, Tr) => "Bir çalıştırıcı kaydet", (RegistrationToken, En) => "Registration token", (RegistrationToken, Tr) => "Kayıt belirteci", (RemovedWithAccount, En) => "Removed with the account:", (RemovedWithAccount, Tr) => "Hesapla birlikte silinenler:", (ReplacePrefix, En) => "Replace ", (ReplacePrefix, Tr) => "Çalıştırıcının adını ", (ReplaceSuffix, En) => " with the runner's name.", (ReplaceSuffix, Tr) => " yerine yazın.", (Replication, En) => "Replication", (Replication, Tr) => "Çoğaltma", (ReplicationIntro, En) => { "Standby copies of every repo and of the database. Times are in your timezone. Settings come from the [replication] section of the config file." } (ReplicationIntro, Tr) => { "Her deponun ve veritabanının bekleme kopyaları. Saatler sizin saat diliminizde gösterilir. Ayarlar, yapılandırma dosyasındaki [replication] bölümünden gelir." } (ReplicationOff, En) => { "Replication is off. Set target, identity_file and known_hosts_file in the [replication] section to turn it on." } (ReplicationOff, Tr) => { "Çoğaltma kapalı. Açmak için [replication] bölümünde target, identity_file ve known_hosts_file ayarlarını yapın." } (ReplicationTarget, En) => "Target", (ReplicationTarget, Tr) => "Hedef", (Repos, En) => "Repos", (Repos, Tr) => "Depolar", (Retention, En) => "Retention", (Retention, Tr) => "Saklama", (Role, En) => "Role", (Role, Tr) => "Rol", (RoleAdmin, En) => "admin", (RoleAdmin, Tr) => "yönetici", (RoleOrganization, En) => "organization", (RoleOrganization, Tr) => "kuruluş", (RoleUser, En) => "user", (RoleUser, Tr) => "kullanıcı", (RunBackupNow, En) => "Run backup now", (RunBackupNow, Tr) => "Şimdi yedekle", (RunFsckNow, En) => "Run fsck now", (RunFsckNow, Tr) => "Şimdi fsck çalıştır", (RunnerDeletedNotice, En) => "Runner deleted.", (RunnerDeletedNotice, Tr) => "Çalıştırıcı silindi.", (RunnerDisabledNotice, En) => "Runner disabled. It will not take new jobs.", (RunnerDisabledNotice, Tr) => "Çalıştırıcı devre dışı bırakıldı. Yeni iş almayacak.", (RunnerEnabledNotice, En) => "Runner enabled.", (RunnerEnabledNotice, Tr) => "Çalıştırıcı etkinleştirildi.", (Runners, En) => "Runners", (Runners, Tr) => "Çalıştırıcılar", (ScheduledBackupsOff, En) => { "Scheduled backups are off. Set dir in the [backup] section to turn them on." } (ScheduledBackupsOff, Tr) => { "Zamanlanmış yedeklemeler kapalı. Açmak için [backup] bölümünde dir ayarını yapın." } (SecurityLogTitle, En) => "Security log", (SecurityLogTitle, Tr) => "Güvenlik günlüğü", (SecurityNone, En) => "None (plain text)", (SecurityNone, Tr) => "Yok (düz metin)", (SendMailCheckbox, En) => " Send mail", (SendMailCheckbox, Tr) => " E-posta gönder", (SendTestMailToMe, En) => "Send test mail to me", (SendTestMailToMe, Tr) => "Bana test e-postası gönder", (Settings, En) => "Settings", (Settings, Tr) => "Ayarlar", (SmtpServer, En) => "SMTP server", (SmtpServer, Tr) => "SMTP sunucusu", (Standby, En) => "Standby", (Standby, Tr) => "Bekleme kopyası", (StatusFailed, En) => "failed", (StatusFailed, Tr) => "başarısız", (StatusInProgress, En) => "in progress", (StatusInProgress, Tr) => "sürüyor", (StatusOk, En) => "ok", (StatusOk, Tr) => "tamam", (TableActor, En) => "Actor", (TableActor, Tr) => "Yapan", (TableDetails, En) => "Details", (TableDetails, Tr) => "Ayrıntılar", (TableDuration, En) => "Duration", (TableDuration, Tr) => "Süre", (TableError, En) => "Error", (TableError, Tr) => "Hata", (TableKind, En) => "Kind", (TableKind, Tr) => "Tür", (TableLabels, En) => "Labels", (TableLabels, Tr) => "Etiketler", (TableLastError, En) => "Last error", (TableLastError, Tr) => "Son hata", (TableName, En) => "Name", (TableName, Tr) => "Ad", (TableQueued, En) => "Queued", (TableQueued, Tr) => "Kuyruğa alındı", (TableRepo, En) => "Repo", (TableRepo, Tr) => "Depo", (TableResult, En) => "Result", (TableResult, Tr) => "Sonuç", (TableSize, En) => "Size", (TableSize, Tr) => "Boyut", (TableStarted, En) => "Started", (TableStarted, Tr) => "Başlangıç", (TableState, En) => "State", (TableState, Tr) => "Durum", (TableStatus, En) => "Status", (TableStatus, Tr) => "Durum", (TableSubject, En) => "Subject", (TableSubject, Tr) => "Konu", (TableTarget, En) => "Target", (TableTarget, Tr) => "Hedef", (TableTo, En) => "To", (TableTo, Tr) => "Alıcı", (TableTries, En) => "Tries", (TableTries, Tr) => "Deneme", (TableTrigger, En) => "Trigger", (TableTrigger, Tr) => "Tetikleyen", (TableWhen, En) => "When", (TableWhen, Tr) => "Ne zaman", (TestQueued, En) => "Test message queued. It appears in the list when it is sent.", (TestQueued, Tr) => "Test iletisi kuyruğa alındı. Gönderildiğinde listede görünür.", (Token, En) => "Token", (Token, Tr) => "Belirteç", (TokenCreateFailed, En) => { "The registration token could not be created. Nothing was changed." } (TokenCreateFailed, Tr) => "Kayıt belirteci oluşturulamadı. Hiçbir şey değiştirilmedi.", (TransferOrDeleteFirst, En) => "Transfer or delete these repositories first:", (TransferOrDeleteFirst, Tr) => "Önce bu depoları devredin veya silin:", (UnknownHost, En) => "unknown", (UnknownHost, Tr) => "bilinmiyor", (Users, En) => "Users", (Users, Tr) => "Kullanıcılar", (WhatHappens, En) => "What happens", (WhatHappens, Tr) => "Ne olacak", } } /// "Type alice to confirm", with the username in the middle. pub fn type_to_confirm(lang: Lang, name: &str) -> String { match lang { Lang::En => format!("Type {name} to confirm"), Lang::Tr => format!("Onaylamak için {name} yazın"), } } /// "password must be at least 12 characters" (the message for a short password). pub fn password_min_error(lang: Lang, min: usize) -> String { match lang { Lang::En => format!("password must be at least {min} characters"), Lang::Tr => format!("parola en az {min} karakter olmalı"), } } /// The name of a repo deleted since its last push, pending cleanup on the standby. pub fn deleted_repo_name(lang: Lang, subject: &str) -> String { match lang { Lang::En => format!("{subject} (deleted, pending cleanup)"), Lang::Tr => format!("{subject} (silindi, temizlik bekliyor)"), } } /// "database every 60 min, reconcile every 30 min". pub fn interval_line(lang: Lang, db_minutes: u64, reconcile_minutes: u64) -> String { match lang { Lang::En => { format!("database every {db_minutes} min, reconcile every {reconcile_minutes} min") } Lang::Tr => format!( "veritabanı her {db_minutes} dakikada, uzlaştırma her {reconcile_minutes} dakikada" ), } } /// "1 hour" or "24 hours" for the registration token lifetime. pub fn hours_text(lang: Lang, hours: u32) -> String { match (lang, hours) { (Lang::En, 1) => "1 hour".to_owned(), (Lang::En, _) => format!("{hours} hours"), (Lang::Tr, 1) => "1 saat".to_owned(), (Lang::Tr, _) => format!("{hours} saat"), } } /// "A registration token works once and expires after 24 hours. Creating one shows it on the next /// page only." pub fn token_ttl_note(lang: Lang, ttl: &str) -> String { match lang { Lang::En => format!( "A registration token works once and expires after {ttl}. Creating one shows it on the next page only." ), Lang::Tr => format!( "Kayıt belirteci yalnızca bir kez çalışır ve {ttl} sonra geçerliliğini yitirir. Oluşturulduğunda yalnızca bir sonraki sayfada gösterilir." ), } } /// "It works once and expires in 24 hours." pub fn token_expiry_line(lang: Lang, ttl: &str) -> String { match lang { Lang::En => format!("It works once and expires in {ttl}."), Lang::Tr => format!("Yalnızca bir kez çalışır ve {ttl} içinde sona erer."), } } /// "set (host hc.example.test)" for a healthcheck URL, with the host unknown when it has none. pub fn healthcheck_host(lang: Lang, host: Option<&str>) -> String { let host = host.unwrap_or_else(|| t(lang, K::UnknownHost)); match lang { Lang::En => format!("set (host {host})"), Lang::Tr => format!("ayarlı (sunucu: {host})"), } } /// "every 6 hours". pub fn every_hours(lang: Lang, hours: u64) -> String { match lang { Lang::En => format!("every {hours} hours"), Lang::Tr => format!("her {hours} saatte bir"), } } /// "every 7 days". pub fn every_days(lang: Lang, days: u64) -> String { match lang { Lang::En => format!("every {days} days"), Lang::Tr => format!("her {days} günde bir"), } } /// "2 newest complete sets". pub fn newest_sets(lang: Lang, keep: usize) -> String { match lang { Lang::En => format!("{keep} newest complete sets"), Lang::Tr => format!("en yeni {keep} tam küme"), } } /// The run kind as a table cell: "backup" or "fsck". pub fn kind_name(lang: Lang, kind: RunKind) -> &'static str { match (kind, lang) { (RunKind::Backup, Lang::En) => "backup", (RunKind::Backup, Lang::Tr) => "yedekleme", (RunKind::Fsck, _) => "fsck", } } /// The run trigger as a table cell. pub fn trigger_name(lang: Lang, trigger: RunTrigger) -> &'static str { match (trigger, lang) { (RunTrigger::Schedule, Lang::En) => "schedule", (RunTrigger::Schedule, Lang::Tr) => "zamanlanmış", (RunTrigger::Manual, Lang::En) => "manual", (RunTrigger::Manual, Lang::Tr) => "elle", (RunTrigger::Cli, Lang::En) => "cli", (RunTrigger::Cli, Lang::Tr) => "komut satırı", } } /// "Backup started." or "Fsck started." after a manual run is queued. pub fn started_notice(lang: Lang, kind: RunKind) -> String { match (kind, lang) { (RunKind::Backup, Lang::En) => "Backup started.".to_owned(), (RunKind::Backup, Lang::Tr) => "Yedekleme başlatıldı.".to_owned(), (RunKind::Fsck, Lang::En) => "Fsck started.".to_owned(), (RunKind::Fsck, Lang::Tr) => "Fsck başlatıldı.".to_owned(), } } /// "A backup run is in progress." shown while a run holds the slot. pub fn running_line(lang: Lang, kind: RunKind) -> String { match lang { Lang::En => format!("A {} run is in progress.", kind_name(lang, kind)), Lang::Tr => format!("Bir {} işlemi sürüyor.", kind_name(lang, kind)), } } /// The outbox status of a message: "sent", "queued" or "gave up". pub fn outbox_status(lang: Lang, status: OutboxStatus) -> &'static str { match (status, lang) { (OutboxStatus::Sent, Lang::En) => "sent", (OutboxStatus::Sent, Lang::Tr) => "gönderildi", (OutboxStatus::Queued, Lang::En) => "queued", (OutboxStatus::Queued, Lang::Tr) => "kuyrukta", (OutboxStatus::GaveUp, Lang::En) => "gave up", (OutboxStatus::GaveUp, Lang::Tr) => "vazgeçildi", } } /// "There is no action named nonsense." for an unknown action filter. pub fn no_action_named(lang: Lang, action: &str) -> String { match lang { Lang::En => format!("There is no action named {action}."), Lang::Tr => format!("{action} adında bir işlem yok."), } } /// "There is no user named mallory." for an unknown actor filter. pub fn no_user_named(lang: Lang, actor: &str) -> String { match lang { Lang::En => format!("There is no user named {actor}."), Lang::Tr => format!("{actor} adında bir kullanıcı yok."), } } #[cfg(test)] mod tests { use super::*; const ALL: &[K] = &[ K::ActionLabel, K::ActorUsername, K::AddARunner, K::Administrator, K::AllActions, K::Anonymous, K::AtLeast12Chars, K::AuditIntro, K::AuditLog, K::BackToRunners, K::BackToUsers, K::BackupInterval, K::Backups, K::BackupsIntro, K::CiRunners, K::CopyTokenNow, K::CreateAUser, K::CreateRegistrationToken, K::CreateUser, K::Database, K::DatabaseErrorPrefix, K::DeleteAccountRest, K::DeletesAccount, K::DeleteUser, K::Directory, K::Disable, K::Disabled, K::Enable, K::Enabled, K::ErrAccountCannotBeDeleted, K::ErrBackupsNotConfigured, K::ErrChooseSecurity, K::ErrInvalidUsername, K::ErrNoAddressForTest, K::ErrPasswordTooLong, K::ErrPortRange, K::ErrReplicationNotConfigured, K::ErrTestNeedsMailOn, K::ErrTypeUsernameExactly, K::Filter, K::FromAddress, K::FromName, K::Fsck, K::Healthcheck, K::HealthcheckNotSet, K::HealthcheckSet, K::HealthcheckUrlInvalid, K::HealthError, K::HealthLagging, K::HealthNever, K::HealthOk, K::Interval, K::Invites, K::LastDbAttempt, K::LastDbSnapshotShipped, K::LastSeen, K::LastSuccess, K::Mail, K::MailHost, K::MailIntro, K::MailPort, K::MailSettingsSaved, K::MovedToGhost, K::NoEntries, K::NoPasswordStored, K::NoReposYet, K::NoRunnersYet, K::NoRunnerWithId, K::NoRunsYet, K::NothingQueued, K::Older, K::OwnLogIntro, K::PasswordStoredHint, K::RecentMessages, K::RecentRuns, K::ReconcileNow, K::ReconcileStarted, K::RegisterARunner, K::RegistrationToken, K::RemovedWithAccount, K::ReplacePrefix, K::ReplaceSuffix, K::Replication, K::ReplicationIntro, K::ReplicationOff, K::ReplicationTarget, K::Repos, K::Retention, K::Role, K::RoleAdmin, K::RoleOrganization, K::RoleUser, K::RunBackupNow, K::RunFsckNow, K::RunnerDeletedNotice, K::RunnerDisabledNotice, K::RunnerEnabledNotice, K::Runners, K::ScheduledBackupsOff, K::SecurityLogTitle, K::SecurityNone, K::SendMailCheckbox, K::SendTestMailToMe, K::Settings, K::SmtpServer, K::Standby, K::StatusFailed, K::StatusInProgress, K::StatusOk, K::TableActor, K::TableDetails, K::TableDuration, K::TableError, K::TableKind, K::TableLabels, K::TableLastError, K::TableName, K::TableQueued, K::TableRepo, K::TableResult, K::TableSize, K::TableStarted, K::TableState, K::TableStatus, K::TableSubject, K::TableTarget, K::TableTo, K::TableTries, K::TableTrigger, K::TableWhen, K::TestQueued, K::Token, K::TokenCreateFailed, K::TransferOrDeleteFirst, K::UnknownHost, K::Users, K::WhatHappens, ]; #[test] fn every_variant_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 turkish_differs_from_english_for_translated_variants() { let differing = ALL .iter() .filter(|key| t(Lang::En, **key) != t(Lang::Tr, **key)) .count(); assert!(differing >= 3, "only {differing} variants are translated"); } #[test] fn english_text_matches_the_original_phrases() { assert_eq!(t(Lang::En, K::DeleteUser), "Delete user"); assert!(t(Lang::En, K::ReplicationOff).starts_with("Replication is off.")); assert_eq!(type_to_confirm(Lang::En, "alice"), "Type alice to confirm"); assert_eq!( running_line(Lang::En, RunKind::Backup), "A backup run is in progress." ); } }