1pub mod en;
12pub mod ja;
13
14use serde::{Deserialize, Serialize};
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
19#[serde(rename_all = "snake_case")]
20pub enum Locale {
21 #[default]
22 En,
23 Ja,
24}
25
26impl Locale {
27 pub const ALL: &'static [Locale] = &[Locale::En, Locale::Ja];
28
29 pub fn as_str(&self) -> &'static str {
31 match self {
32 Locale::En => "en",
33 Locale::Ja => "ja",
34 }
35 }
36
37 pub fn parse(s: &str) -> Option<Locale> {
38 match s {
39 "en" => Some(Locale::En),
40 "ja" => Some(Locale::Ja),
41 _ => None,
42 }
43 }
44
45 pub fn display_name(&self) -> &'static str {
47 match self {
48 Locale::En => "English",
49 Locale::Ja => "日本語",
50 }
51 }
52}
53
54#[derive(Debug, Clone, Copy, PartialEq, Eq)]
57pub enum MessageKey {
58 AppTitle,
60 LocalOnlyBadge,
61 NavSearch,
63 NavSources,
64 NavIndexing,
65 NavStorage,
66 NavModels,
67 NavAi,
68 NavSettings,
69 SearchPlaceholder,
71 SearchButton,
72 SearchNoSourcesTitle,
73 SearchNoSourcesBody,
74 SearchAddSource,
75 SearchNoResults,
76 SearchKeywordOnlyNotice,
77 SourcesTitle,
79 SourcesEmptyTitle,
80 SourcesEmptyBody,
81 SourcesAddFolder,
82 SourcesStatusActive,
83 SourcesStatusPaused,
84 SourcesStatusMissing,
85 IndexingTitle,
87 IndexingIdle,
88 IndexingHealthIndexed,
89 IndexingHealthStale,
90 IndexingHealthFailed,
91 IndexingHealthQueued,
92 StorageTitle,
94 StorageIntro,
95 StorageGroupSearchIndex,
96 StorageGroupModels,
97 StorageGroupCaches,
98 StorageSafeCleanupHeading,
99 StorageClearSnippets,
100 StorageClearSearchCache,
101 StorageDangerHeading,
102 StorageResetCatalog,
103 StorageResetWarning,
104 ModelsTitle,
106 ModelsEmbeddingRole,
107 ModelsRerankerRole,
108 ModelsStatusAvailable,
109 ModelsStatusMissing,
110 ModelsKeywordOnlyHint,
111 SettingsTitle,
113 SettingsLanguageHeading,
114 SettingsPrivacyHeading,
115 SettingsAdvancedHeading,
116 SettingsAdvancedOn,
117 SettingsAdvancedOff,
118 SettingsAdvancedHint,
119 SettingsPrivacyLocalOnly,
120 SearchModeLabel,
122 SearchModeAuto,
123 SearchModeExact,
124 SearchModeConceptual,
125 SearchModeFast,
126 BadgeKeyword,
128 BadgeSemantic,
129 BadgeFused,
130 WizardTitleNotConfigured,
132 WizardTitleFileMissing,
133 WizardTitleValidating,
134 WizardTitleReady,
135 WizardBodyNotConfigured,
136 WizardBodyFileMissing,
137 WizardFilesNeededLabel,
138 WizardDownloadHint,
139 WizardPathInputPlaceholder,
140 WizardActionLocate,
141 WizardActionValidate,
142 WizardActionUseModel,
143 WizardActionContinue,
144 WizardPathPlaceholder,
145 WizardDownloadAction,
146 WizardDownloadProgress,
147 WizardActionSkip,
148 WizardPreviousPathLabel,
149 WizardValidationOk,
150 WizardValidationFail,
151 WizardReadyBody,
152 NoticeDownloadFailTitle,
154 NoticeDownloadFailBody,
155 NoticeFolderFailTitle,
156 NoticeFolderFailBody,
157 NoticeSearchFailTitle,
158 NoticeSearchFailBody,
159 NoticeFilesMissingTitle,
160 NoticeFilesMissingBody,
161 NoticeFolderAddedTitle,
162 NoticeFolderAddedBody,
163 NoticeSearchReadyTitle,
164 NoticeSearchReadyBody,
165 NoticePreviewsClearedTitle,
166 NoticePreviewsClearedBody,
167 NoticeActionTryAgain,
168 NoticeActionChooseFolder,
169 NoticeDismiss,
170 Cancel,
171 Confirm,
172}
173
174pub fn tr(locale: Locale, key: MessageKey) -> &'static str {
177 match locale {
178 Locale::En => en::message(key),
179 Locale::Ja => ja::message(key),
180 }
181}
182
183pub fn files_indexed(locale: Locale, count: u64) -> String {
185 match locale {
186 Locale::En => format!("{count} files indexed"),
187 Locale::Ja => format!("{count} 件のファイルをインデックス済み"),
188 }
189}
190
191pub fn source_summary(locale: Locale, indexed: u64, stale: u64, failed: u64) -> String {
193 match locale {
194 Locale::En => format!("{indexed} indexed · {stale} stale · {failed} failed"),
195 Locale::Ja => format!("インデックス済み {indexed} · 要更新 {stale} · 失敗 {failed}"),
196 }
197}
198
199pub fn search_result_count(locale: Locale, count: usize) -> String {
201 match locale {
202 Locale::En => format!("{count} result{}", if count == 1 { "" } else { "s" }),
203 Locale::Ja => format!("{count} 件の結果"),
204 }
205}