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 WizardActionSkip,
138 WizardPreviousPathLabel,
139 WizardValidationOk,
140 WizardValidationFail,
141 WizardReadyBody,
142 Cancel,
144 Confirm,
145}
146
147pub fn tr(locale: Locale, key: MessageKey) -> &'static str {
150 match locale {
151 Locale::En => en::message(key),
152 Locale::Ja => ja::message(key),
153 }
154}
155
156pub fn files_indexed(locale: Locale, count: u64) -> String {
158 match locale {
159 Locale::En => format!("{count} files indexed"),
160 Locale::Ja => format!("{count} 件のファイルをインデックス済み"),
161 }
162}
163
164pub fn source_summary(locale: Locale, indexed: u64, stale: u64, failed: u64) -> String {
166 match locale {
167 Locale::En => format!("{indexed} indexed · {stale} stale · {failed} failed"),
168 Locale::Ja => format!("インデックス済み {indexed} · 要更新 {stale} · 失敗 {failed}"),
169 }
170}
171
172pub fn search_result_count(locale: Locale, count: usize) -> String {
174 match locale {
175 Locale::En => format!("{count} result{}", if count == 1 { "" } else { "s" }),
176 Locale::Ja => format!("{count} 件の結果"),
177 }
178}