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 Cancel,
154 Confirm,
155}
156
157pub fn tr(locale: Locale, key: MessageKey) -> &'static str {
160 match locale {
161 Locale::En => en::message(key),
162 Locale::Ja => ja::message(key),
163 }
164}
165
166pub fn files_indexed(locale: Locale, count: u64) -> String {
168 match locale {
169 Locale::En => format!("{count} files indexed"),
170 Locale::Ja => format!("{count} 件のファイルをインデックス済み"),
171 }
172}
173
174pub fn source_summary(locale: Locale, indexed: u64, stale: u64, failed: u64) -> String {
176 match locale {
177 Locale::En => format!("{indexed} indexed · {stale} stale · {failed} failed"),
178 Locale::Ja => format!("インデックス済み {indexed} · 要更新 {stale} · 失敗 {failed}"),
179 }
180}
181
182pub fn search_result_count(locale: Locale, count: usize) -> String {
184 match locale {
185 Locale::En => format!("{count} result{}", if count == 1 { "" } else { "s" }),
186 Locale::Ja => format!("{count} 件の結果"),
187 }
188}