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 NavSettings,
68 SearchPlaceholder,
70 SearchButton,
71 SearchNoSourcesTitle,
72 SearchNoSourcesBody,
73 SearchAddSource,
74 SearchNoResults,
75 SearchKeywordOnlyNotice,
76 SourcesTitle,
78 SourcesEmptyTitle,
79 SourcesEmptyBody,
80 SourcesAddFolder,
81 SourcesStatusActive,
82 SourcesStatusPaused,
83 SourcesStatusMissing,
84 IndexingTitle,
86 IndexingIdle,
87 IndexingHealthIndexed,
88 IndexingHealthStale,
89 IndexingHealthFailed,
90 IndexingHealthQueued,
91 StorageTitle,
93 StorageIntro,
94 StorageSafeCleanupHeading,
95 StorageClearSnippets,
96 StorageClearSearchCache,
97 StorageDangerHeading,
98 StorageResetCatalog,
99 StorageResetWarning,
100 ModelsTitle,
102 ModelsEmbeddingRole,
103 ModelsRerankerRole,
104 ModelsStatusAvailable,
105 ModelsStatusMissing,
106 ModelsKeywordOnlyHint,
107 SettingsTitle,
109 SettingsLanguageHeading,
110 SettingsPrivacyHeading,
111 SettingsPrivacyLocalOnly,
112 SearchModeLabel,
114 SearchModeAuto,
115 SearchModeExact,
116 SearchModeConceptual,
117 SearchModeFast,
118 BadgeKeyword,
120 BadgeSemantic,
121 BadgeFused,
122 WizardTitleNotConfigured,
124 WizardTitleFileMissing,
125 WizardTitleValidating,
126 WizardTitleReady,
127 WizardBodyNotConfigured,
128 WizardBodyFileMissing,
129 WizardFilesNeededLabel,
130 WizardDownloadHint,
131 WizardPathInputPlaceholder,
132 WizardActionLocate,
133 WizardActionValidate,
134 WizardActionUseModel,
135 WizardActionContinue,
136 WizardActionSkip,
137 WizardPreviousPathLabel,
138 WizardValidationOk,
139 WizardValidationFail,
140 WizardReadyBody,
141 Cancel,
143 Confirm,
144}
145
146pub fn tr(locale: Locale, key: MessageKey) -> &'static str {
149 match locale {
150 Locale::En => en::message(key),
151 Locale::Ja => ja::message(key),
152 }
153}
154
155pub fn files_indexed(locale: Locale, count: u64) -> String {
157 match locale {
158 Locale::En => format!("{count} files indexed"),
159 Locale::Ja => format!("{count} 件のファイルをインデックス済み"),
160 }
161}
162
163pub fn source_summary(locale: Locale, indexed: u64, stale: u64, failed: u64) -> String {
165 match locale {
166 Locale::En => format!("{indexed} indexed · {stale} stale · {failed} failed"),
167 Locale::Ja => format!("インデックス済み {indexed} · 要更新 {stale} · 失敗 {failed}"),
168 }
169}
170
171pub fn search_result_count(locale: Locale, count: usize) -> String {
173 match locale {
174 Locale::En => format!("{count} result{}", if count == 1 { "" } else { "s" }),
175 Locale::Ja => format!("{count} 件の結果"),
176 }
177}