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 StorageSafeCleanupHeading,
96 StorageClearSnippets,
97 StorageClearSearchCache,
98 StorageDangerHeading,
99 StorageResetCatalog,
100 StorageResetWarning,
101 ModelsTitle,
103 ModelsEmbeddingRole,
104 ModelsRerankerRole,
105 ModelsStatusAvailable,
106 ModelsStatusMissing,
107 ModelsKeywordOnlyHint,
108 SettingsTitle,
110 SettingsLanguageHeading,
111 SettingsPrivacyHeading,
112 SettingsPrivacyLocalOnly,
113 SearchModeLabel,
115 SearchModeAuto,
116 SearchModeExact,
117 SearchModeConceptual,
118 SearchModeFast,
119 BadgeKeyword,
121 BadgeSemantic,
122 BadgeFused,
123 WizardTitleNotConfigured,
125 WizardTitleFileMissing,
126 WizardTitleValidating,
127 WizardTitleReady,
128 WizardBodyNotConfigured,
129 WizardBodyFileMissing,
130 WizardFilesNeededLabel,
131 WizardDownloadHint,
132 WizardPathInputPlaceholder,
133 WizardActionLocate,
134 WizardActionValidate,
135 WizardActionUseModel,
136 WizardActionContinue,
137 WizardPathPlaceholder,
138 WizardDownloadAction,
139 WizardDownloadProgress,
140 WizardActionSkip,
141 WizardPreviousPathLabel,
142 WizardValidationOk,
143 WizardValidationFail,
144 WizardReadyBody,
145 Cancel,
147 Confirm,
148}
149
150pub fn tr(locale: Locale, key: MessageKey) -> &'static str {
153 match locale {
154 Locale::En => en::message(key),
155 Locale::Ja => ja::message(key),
156 }
157}
158
159pub fn files_indexed(locale: Locale, count: u64) -> String {
161 match locale {
162 Locale::En => format!("{count} files indexed"),
163 Locale::Ja => format!("{count} 件のファイルをインデックス済み"),
164 }
165}
166
167pub fn source_summary(locale: Locale, indexed: u64, stale: u64, failed: u64) -> String {
169 match locale {
170 Locale::En => format!("{indexed} indexed · {stale} stale · {failed} failed"),
171 Locale::Ja => format!("インデックス済み {indexed} · 要更新 {stale} · 失敗 {failed}"),
172 }
173}
174
175pub fn search_result_count(locale: Locale, count: usize) -> String {
177 match locale {
178 Locale::En => format!("{count} result{}", if count == 1 { "" } else { "s" }),
179 Locale::Ja => format!("{count} 件の結果"),
180 }
181}