forge
ExploreLog in

Tahinli/forge

public
0 watching
★ 0
19.6 KiB
1//! Strings for the community group: discussions, the wiki and snippets. See `super` for the
2//! pattern: one variant per UI phrase, an exhaustive `t` match, and small helpers for sentences
3//! that carry arguments.
4
5use forge_core::discussions::DiscussionCategory;
6
7use super::Lang;
8
9#[derive(Clone, Copy, Debug, PartialEq, Eq)]
10pub enum K {
11 // Discussions: list, new, view and settings.
12 AllCategories,
13 CategoriesNav,
14 NewDiscussion,
15 NoDiscussionsYet,
16 Discussions,
17 Newer,
18 Older,
19 Category,
20 Title,
21 Description,
22 MarkdownSupported,
23 StartDiscussion,
24 Cancel,
25 Save,
26 Delete,
27 Edit,
28 EditComment,
29 CouldNotSave,
30 CommentDeleted,
31 Answer,
32 MarkAsAnswer,
33 UnmarkAnswer,
34 Reply,
35 DeleteDiscussion,
36 Conversation,
37 LockConversation,
38 UnlockConversation,
39 Answered,
40 Locked,
41 OpenedThis,
42 OpenedSeparator,
43 NoDescription,
44 LockedNotice,
45 AddComment,
46 CommentButton,
47 LogInLink,
48 ToCommentSuffix,
49 ArchivedDiscussions,
50 DiscussionsDescription,
51 TurnOffDiscussions,
52 TurnOnDiscussions,
53 CategoryGeneral,
54 CategoryIdeas,
55 CategoryQa,
56 CategoryAnnouncements,
57
58 // Wiki.
59 Wiki,
60 Home,
61 AllPages,
62 NewPage,
63 History,
64 PageNav,
65 WikiNoPages,
66 CreateFirstPage,
67 NoPagesYet,
68 BackToPage,
69 NoChangesYet,
70 PageName,
71 PageNameHint,
72 ContentMarkdown,
73 WikiLinkHint,
74 Summary,
75 SavePage,
76 PageNameRules,
77 PageExists,
78 WikiConflict,
79 WikiSettings,
80 EnableWiki,
81 WikiDisabledHint,
82 WikiPages,
83
84 // Snippets.
85 Snippets,
86 NewSnippet,
87 NoSnippets,
88 Visibility,
89 VisibilityPublic,
90 VisibilityUnlisted,
91 VisibilityPrivate,
92 PublicOption,
93 UnlistedOption,
94 PrivateOption,
95 FileLabel,
96 FileNamePlaceholder,
97 FileName,
98 FileContents,
99 Untitled,
100 Files,
101 SnippetTitlePlaceholder,
102 DescriptionOptional,
103 AddFile,
104 RemoveFile,
105 SaveSnippet,
106 EditSnippet,
107 Raw,
108 SnippetNav,
109 FileNav,
110 OnlyOwnerEdits,
111 Revisions,
112 BackToSnippet,
113 NoRevisions,
114 RevisionLabel,
115 ChooseVisibility,
116}
117
118pub fn t(lang: Lang, key: K) -> &'static str {
119 use K::*;
120 use Lang::*;
121 match (key, lang) {
122 (AllCategories, En) => "All",
123 (AllCategories, Tr) => "Tümü",
124 (CategoriesNav, En) => "Discussion categories",
125 (CategoriesNav, Tr) => "Tartışma kategorileri",
126 (NewDiscussion, En) => "New discussion",
127 (NewDiscussion, Tr) => "Yeni tartışma",
128 (NoDiscussionsYet, En) => "No discussions here yet.",
129 (NoDiscussionsYet, Tr) => "Henüz tartışma yok.",
130 (Discussions, En) => "Discussions",
131 (Discussions, Tr) => "Tartışmalar",
132 (Newer, En) => "Newer",
133 (Newer, Tr) => "Daha yeni",
134 (Older, En) => "Older",
135 (Older, Tr) => "Daha eski",
136 (Category, En) => "Category",
137 (Category, Tr) => "Kategori",
138 (Title, En) => "Title",
139 (Title, Tr) => "Başlık",
140 (Description, En) => "Description",
141 (Description, Tr) => "Açıklama",
142 (MarkdownSupported, En) => "Markdown supported.",
143 (MarkdownSupported, Tr) => "Markdown desteklenir.",
144 (StartDiscussion, En) => "Start discussion",
145 (StartDiscussion, Tr) => "Tartışma başlat",
146 (Cancel, En) => "Cancel",
147 (Cancel, Tr) => "İptal",
148 (Save, En) => "Save",
149 (Save, Tr) => "Kaydet",
150 (Delete, En) => "Delete",
151 (Delete, Tr) => "Sil",
152 (Edit, En) => "Edit",
153 (Edit, Tr) => "Düzenle",
154 (EditComment, En) => "Edit comment",
155 (EditComment, Tr) => "Yorumu düzenle",
156 (CouldNotSave, En) => "Could not save",
157 (CouldNotSave, Tr) => "Kaydedilemedi",
158 (CommentDeleted, En) => "Comment deleted",
159 (CommentDeleted, Tr) => "Yorum silindi",
160 (Answer, En) => "Answer",
161 (Answer, Tr) => "Cevap",
162 (MarkAsAnswer, En) => "Mark as answer",
163 (MarkAsAnswer, Tr) => "Cevap olarak işaretle",
164 (UnmarkAnswer, En) => "Unmark answer",
165 (UnmarkAnswer, Tr) => "Cevap işaretini kaldır",
166 (Reply, En) => "Reply",
167 (Reply, Tr) => "Yanıtla",
168 (DeleteDiscussion, En) => "Delete discussion",
169 (DeleteDiscussion, Tr) => "Tartışmayı sil",
170 (Conversation, En) => "Conversation",
171 (Conversation, Tr) => "Konuşma",
172 (LockConversation, En) => "Lock conversation",
173 (LockConversation, Tr) => "Konuşmayı kilitle",
174 (UnlockConversation, En) => "Unlock conversation",
175 (UnlockConversation, Tr) => "Konuşmanın kilidini aç",
176 (Answered, En) => "Answered",
177 (Answered, Tr) => "Cevaplandı",
178 (Locked, En) => "Locked",
179 (Locked, Tr) => "Kilitli",
180 (OpenedThis, En) => " opened this ",
181 (OpenedThis, Tr) => " tarafından ",
182 (OpenedSeparator, En) => " · ",
183 (OpenedSeparator, Tr) => " açıldı · ",
184 (NoDescription, En) => "_No description provided._",
185 (NoDescription, Tr) => "_Açıklama eklenmedi._",
186 (LockedNotice, En) => {
187 "This conversation is locked. Only people with Triage access can comment."
188 }
189 (LockedNotice, Tr) => {
190 "Bu konuşma kilitli. Yorum yalnızca Triage erişimi olanlar tarafından yapılabilir."
191 }
192 (AddComment, En) => "Add a comment",
193 (AddComment, Tr) => "Yorum ekle",
194 (CommentButton, En) => "Comment",
195 (CommentButton, Tr) => "Yorum yap",
196 (LogInLink, En) => "Log in",
197 (LogInLink, Tr) => "giriş yapın",
198 (ToCommentSuffix, En) => " to comment.",
199 (ToCommentSuffix, Tr) => ".",
200 (ArchivedDiscussions, En) => {
201 "This repository is archived, so its discussions are read-only."
202 }
203 (ArchivedDiscussions, Tr) => "Bu depo arşivlendiği için tartışmalar salt okunur.",
204 (DiscussionsDescription, En) => {
205 "A forum for questions, ideas and announcements, next to issues. Off by default. Turning it off hides the tab; existing discussions are kept."
206 }
207 (DiscussionsDescription, Tr) => {
208 "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."
209 }
210 (TurnOffDiscussions, En) => "Turn off discussions",
211 (TurnOffDiscussions, Tr) => "Tartışmaları kapat",
212 (TurnOnDiscussions, En) => "Turn on discussions",
213 (TurnOnDiscussions, Tr) => "Tartışmaları aç",
214 (CategoryGeneral, En) => "General",
215 (CategoryGeneral, Tr) => "Genel",
216 (CategoryIdeas, En) => "Ideas",
217 (CategoryIdeas, Tr) => "Fikirler",
218 (CategoryQa, En) => "Q&A",
219 (CategoryQa, Tr) => "Soru-cevap",
220 (CategoryAnnouncements, En) => "Announcements",
221 (CategoryAnnouncements, Tr) => "Duyurular",
222
223 (Wiki, En) => "Wiki",
224 (Wiki, Tr) => "Wiki",
225 (Home, En) => "Home",
226 (Home, Tr) => "Ana sayfa",
227 (AllPages, En) => "All pages",
228 (AllPages, Tr) => "Tüm sayfalar",
229 (NewPage, En) => "New page",
230 (NewPage, Tr) => "Yeni sayfa",
231 (History, En) => "History",
232 (History, Tr) => "Geçmiş",
233 (PageNav, En) => "Page",
234 (PageNav, Tr) => "Sayfa",
235 (WikiNoPages, En) => "This wiki has no pages yet.",
236 (WikiNoPages, Tr) => "Bu wiki'de henüz sayfa yok.",
237 (CreateFirstPage, En) => "Create the first page",
238 (CreateFirstPage, Tr) => "İlk sayfayı oluştur",
239 (NoPagesYet, En) => "No pages yet.",
240 (NoPagesYet, Tr) => "Henüz sayfa yok.",
241 (BackToPage, En) => "Back to page",
242 (BackToPage, Tr) => "Sayfaya dön",
243 (NoChangesYet, En) => "No changes yet.",
244 (NoChangesYet, Tr) => "Henüz değişiklik yok.",
245 (PageName, En) => "Page name",
246 (PageName, Tr) => "Sayfa adı",
247 (PageNameHint, En) => "Letters, digits, - and _. Dashes show as spaces in titles.",
248 (PageNameHint, Tr) => "Harfler, rakamlar, - ve _. Başlıkta tireler boşluk olarak görünür.",
249 (ContentMarkdown, En) => "Content (Markdown)",
250 (ContentMarkdown, Tr) => "İçerik (Markdown)",
251 (WikiLinkHint, En) => "Link to another page with [[Page-Name]] or [[Label|Page-Name]].",
252 (WikiLinkHint, Tr) => {
253 "Başka bir sayfaya [[Sayfa-Adı]] ya da [[Etiket|Sayfa-Adı]] biçiminde bağlantı verin."
254 }
255 (Summary, En) => "Summary",
256 (Summary, Tr) => "Özet",
257 (SavePage, En) => "Save page",
258 (SavePage, Tr) => "Sayfayı kaydet",
259 (PageNameRules, En) => "Page names use letters, digits, - and _, up to 100 characters.",
260 (PageNameRules, Tr) => {
261 "Sayfa adları harf, rakam, - ve _ içerebilir; en fazla 100 karakter olabilir."
262 }
263 (PageExists, En) => "A page with that name already exists. Edit it instead.",
264 (PageExists, Tr) => "Bu adla bir sayfa zaten var. Bunun yerine onu düzenleyin.",
265 (WikiConflict, En) => {
266 "Someone else saved this wiki while you were editing. Your text is kept below; copy it, reload the page, and save again."
267 }
268 (WikiConflict, Tr) => {
269 "Siz düzenlerken başka biri bu wiki'yi kaydetti. Metniniz aşağıda duruyor; kopyalayın, sayfayı yenileyin ve yeniden kaydedin."
270 }
271 (WikiSettings, En) => "Wiki settings",
272 (WikiSettings, Tr) => "Wiki ayarları",
273 (EnableWiki, En) => "Enable the wiki",
274 (EnableWiki, Tr) => "Wiki'yi etkinleştir",
275 (WikiDisabledHint, En) => {
276 "A disabled wiki is hidden and refuses edits and pushes. Its pages are kept."
277 }
278 (WikiDisabledHint, Tr) => {
279 "Devre dışı bir wiki gizlenir; düzenlemelerini ve göndermelerini kabul etmez. Sayfaları korunur."
280 }
281 (WikiPages, En) => "Wiki pages",
282 (WikiPages, Tr) => "Wiki sayfaları",
283
284 (Snippets, En) => "Snippets",
285 (Snippets, Tr) => "Parçacıklar",
286 (NewSnippet, En) => "New snippet",
287 (NewSnippet, Tr) => "Yeni parçacık",
288 (NoSnippets, En) => "No snippets to show.",
289 (NoSnippets, Tr) => "Gösterilecek parçacık yok.",
290 (Visibility, En) => "Visibility",
291 (Visibility, Tr) => "Görünürlük",
292 (VisibilityPublic, En) => "Public",
293 (VisibilityPublic, Tr) => "Herkese açık",
294 (VisibilityUnlisted, En) => "Unlisted",
295 (VisibilityUnlisted, Tr) => "Listelenmez",
296 (VisibilityPrivate, En) => "Private",
297 (VisibilityPrivate, Tr) => "Özel",
298 (PublicOption, En) => "Public: listed on /snippets",
299 (PublicOption, Tr) => "Herkese açık: /snippets üzerinde listelenir",
300 (UnlistedOption, En) => "Unlisted: anyone with the link",
301 (UnlistedOption, Tr) => "Listelenmez: bağlantıya sahip herkes",
302 (PrivateOption, En) => "Private: only you",
303 (PrivateOption, Tr) => "Özel: yalnızca siz",
304 (FileLabel, En) => "File ",
305 (FileLabel, Tr) => "Dosya ",
306 (FileNamePlaceholder, En) => "file name, for example notes.md",
307 (FileNamePlaceholder, Tr) => "dosya adı, örneğin notes.md",
308 (FileName, En) => "File name",
309 (FileName, Tr) => "Dosya adı",
310 (FileContents, En) => "File contents",
311 (FileContents, Tr) => "Dosya içeriği",
312 (Untitled, En) => "untitled",
313 (Untitled, Tr) => "adsız",
314 (Files, En) => "Files",
315 (Files, Tr) => "Dosyalar",
316 (SnippetTitlePlaceholder, En) => "Snippet title",
317 (SnippetTitlePlaceholder, Tr) => "Parçacık başlığı",
318 (DescriptionOptional, En) => "Description (optional)",
319 (DescriptionOptional, Tr) => "Açıklama (isteğe bağlı)",
320 (AddFile, En) => "Add file",
321 (AddFile, Tr) => "Dosya ekle",
322 (RemoveFile, En) => "Remove file",
323 (RemoveFile, Tr) => "Dosyayı kaldır",
324 (SaveSnippet, En) => "Save snippet",
325 (SaveSnippet, Tr) => "Parçacığı kaydet",
326 (EditSnippet, En) => "Edit snippet",
327 (EditSnippet, Tr) => "Parçacığı düzenle",
328 (Raw, En) => "Raw",
329 (Raw, Tr) => "Ham",
330 (SnippetNav, En) => "Snippet",
331 (SnippetNav, Tr) => "Parçacık",
332 (FileNav, En) => "File",
333 (FileNav, Tr) => "Dosya",
334 (OnlyOwnerEdits, En) => "Only the owner can edit this snippet.",
335 (OnlyOwnerEdits, Tr) => "Bu parçacığı yalnızca sahibi düzenleyebilir.",
336 (Revisions, En) => "Revisions",
337 (Revisions, Tr) => "Revizyonlar",
338 (BackToSnippet, En) => "Back to the snippet",
339 (BackToSnippet, Tr) => "Parçacığa dön",
340 (NoRevisions, En) => "No revisions.",
341 (NoRevisions, Tr) => "Revizyon yok.",
342 (RevisionLabel, En) => "Revision ",
343 (RevisionLabel, Tr) => "Revizyon ",
344 (ChooseVisibility, En) => "Choose a visibility.",
345 (ChooseVisibility, Tr) => "Bir görünürlük seçin.",
346 }
347}
348
349/// The name of a discussion category, as the list, the form and the discussion show it.
350pub fn category_label(lang: Lang, category: DiscussionCategory) -> &'static str {
351 match category {
352 DiscussionCategory::General => t(lang, K::CategoryGeneral),
353 DiscussionCategory::Ideas => t(lang, K::CategoryIdeas),
354 DiscussionCategory::Qa => t(lang, K::CategoryQa),
355 DiscussionCategory::Announcements => t(lang, K::CategoryAnnouncements),
356 }
357}
358
359/// The byline of a discussion row, split around the author and the time. English reads
360/// `by Ali 3 days ago`; Turkish reads `Ali tarafından 3 gün önce açıldı`. Returns the text
361/// before the author, between the author and the time, and after the time.
362pub fn byline(lang: Lang) -> (&'static str, &'static str, &'static str) {
363 match lang {
364 Lang::En => (" by ", " ", ""),
365 Lang::Tr => ("", " tarafından ", " açıldı"),
366 }
367}
368
369/// `Page 3` / `Sayfa 3`.
370pub fn page_number(lang: Lang, page: u32) -> String {
371 match lang {
372 Lang::En => format!("Page {page}"),
373 Lang::Tr => format!("Sayfa {page}"),
374 }
375}
376
377/// `1 comment` / `3 comments` in a list row, and `3 yorum` in Turkish.
378pub fn comments_count(lang: Lang, count: i64) -> String {
379 match lang {
380 Lang::En => format!("{count} comment{}", if count == 1 { "" } else { "s" }),
381 Lang::Tr => format!("{count} yorum"),
382 }
383}
384
385/// `1 comment` / `3 comments` in a discussion header, and `3 yorum` in Turkish.
386pub fn comments_total(lang: Lang, count: i64) -> String {
387 match lang {
388 Lang::En => format!("{count} comment{}", if count == 1 { "" } else { "s" }),
389 Lang::Tr => format!("{count} yorum"),
390 }
391}
392
393/// The text before the "Log in" link of a sign-in prompt. English has none.
394pub fn comment_login_lead(lang: Lang) -> &'static str {
395 match lang {
396 Lang::En => "",
397 Lang::Tr => "Yorum yapmak için ",
398 }
399}
400
401/// `The page is larger than 1048576 bytes.` / `Sayfa 1048576 bayttan büyük.`
402pub fn page_too_large(lang: Lang, max: usize) -> String {
403 match lang {
404 Lang::En => format!("The page is larger than {max} bytes."),
405 Lang::Tr => format!("Sayfa {max} bayttan büyük."),
406 }
407}
408
409/// `2 file(s) · updated 3 days ago` / `2 dosya · 3 gün önce güncellendi`.
410/// `updated 3 days ago` / `3 gün önce güncellendi`.
411pub fn updated_on(lang: Lang, updated: &str) -> String {
412 match lang {
413 Lang::En => format!("updated {updated}"),
414 Lang::Tr => format!("{updated} güncellendi"),
415 }
416}
417
418pub fn files_updated(lang: Lang, count: u64, updated: &str) -> String {
419 match lang {
420 Lang::En => format!("{count} file(s) · updated {updated}"),
421 Lang::Tr => format!("{count} dosya · {updated} güncellendi"),
422 }
423}
424
425/// `1 of 10 files · 1 MiB max` / `1 / 10 dosya · en fazla 1 MiB`.
426pub fn files_limit(lang: Lang, count: usize, max_files: usize, max_mib: usize) -> String {
427 match lang {
428 Lang::En => format!("{count} of {max_files} files · {max_mib} MiB max"),
429 Lang::Tr => format!("{count} / {max_files} dosya · en fazla {max_mib} MiB"),
430 }
431}
432
433/// `Revisions of Home` / `Home revizyonları`.
434pub fn revisions_of(lang: Lang, title: &str) -> String {
435 match lang {
436 Lang::En => format!("Revisions of {title}"),
437 Lang::Tr => format!("{title} revizyonları"),
438 }
439}
440
441#[cfg(test)]
442mod tests {
443 use super::*;
444
445 const ALL: &[K] = &[
446 K::AllCategories,
447 K::CategoriesNav,
448 K::NewDiscussion,
449 K::NoDiscussionsYet,
450 K::Discussions,
451 K::Newer,
452 K::Older,
453 K::Category,
454 K::Title,
455 K::Description,
456 K::MarkdownSupported,
457 K::StartDiscussion,
458 K::Cancel,
459 K::Save,
460 K::Delete,
461 K::Edit,
462 K::EditComment,
463 K::CouldNotSave,
464 K::CommentDeleted,
465 K::Answer,
466 K::MarkAsAnswer,
467 K::UnmarkAnswer,
468 K::Reply,
469 K::DeleteDiscussion,
470 K::Conversation,
471 K::LockConversation,
472 K::UnlockConversation,
473 K::Answered,
474 K::Locked,
475 K::OpenedThis,
476 K::OpenedSeparator,
477 K::NoDescription,
478 K::LockedNotice,
479 K::AddComment,
480 K::CommentButton,
481 K::LogInLink,
482 K::ToCommentSuffix,
483 K::ArchivedDiscussions,
484 K::DiscussionsDescription,
485 K::TurnOffDiscussions,
486 K::TurnOnDiscussions,
487 K::CategoryGeneral,
488 K::CategoryIdeas,
489 K::CategoryQa,
490 K::CategoryAnnouncements,
491 K::Wiki,
492 K::Home,
493 K::AllPages,
494 K::NewPage,
495 K::History,
496 K::PageNav,
497 K::WikiNoPages,
498 K::CreateFirstPage,
499 K::NoPagesYet,
500 K::BackToPage,
501 K::NoChangesYet,
502 K::PageName,
503 K::PageNameHint,
504 K::ContentMarkdown,
505 K::WikiLinkHint,
506 K::Summary,
507 K::SavePage,
508 K::PageNameRules,
509 K::PageExists,
510 K::WikiConflict,
511 K::WikiSettings,
512 K::EnableWiki,
513 K::WikiDisabledHint,
514 K::WikiPages,
515 K::Snippets,
516 K::NewSnippet,
517 K::NoSnippets,
518 K::Visibility,
519 K::VisibilityPublic,
520 K::VisibilityUnlisted,
521 K::VisibilityPrivate,
522 K::PublicOption,
523 K::UnlistedOption,
524 K::PrivateOption,
525 K::FileLabel,
526 K::FileNamePlaceholder,
527 K::FileName,
528 K::FileContents,
529 K::Untitled,
530 K::Files,
531 K::SnippetTitlePlaceholder,
532 K::DescriptionOptional,
533 K::AddFile,
534 K::RemoveFile,
535 K::SaveSnippet,
536 K::EditSnippet,
537 K::Raw,
538 K::SnippetNav,
539 K::FileNav,
540 K::OnlyOwnerEdits,
541 K::Revisions,
542 K::BackToSnippet,
543 K::NoRevisions,
544 K::RevisionLabel,
545 K::ChooseVisibility,
546 ];
547
548 #[test]
549 fn every_key_has_both_languages() {
550 for key in ALL {
551 assert!(!t(Lang::En, *key).is_empty(), "{key:?} has no English");
552 assert!(!t(Lang::Tr, *key).is_empty(), "{key:?} has no Turkish");
553 }
554 }
555
556 #[test]
557 fn turkish_differs_from_english() {
558 let differing = ALL
559 .iter()
560 .filter(|key| t(Lang::En, **key) != t(Lang::Tr, **key))
561 .count();
562 assert!(differing >= 3, "only {differing} keys differ");
563 assert_eq!(t(Lang::Tr, K::NewDiscussion), "Yeni tartışma");
564 assert_eq!(t(Lang::En, K::NewDiscussion), "New discussion");
565 }
566
567 #[test]
568 fn counts_and_sentences_follow_the_language() {
569 assert_eq!(comments_count(Lang::En, 1), "1 comment");
570 assert_eq!(comments_count(Lang::En, 3), "3 comments");
571 assert_eq!(comments_count(Lang::Tr, 3), "3 yorum");
572 assert_eq!(page_number(Lang::Tr, 2), "Sayfa 2");
573 assert_eq!(files_updated(Lang::En, 2, "now"), "2 file(s) · updated now");
574 }
575}