prehnite_core/settings/
mod.rs

1#![doc = "アプリの設定関連"]
2pub mod registry;
3pub mod value;
4
5use crate::db::{acquire_or_log, DBType};
6use log::error;
7use sqlx::pool::PoolConnection;
8use sqlx::Sqlite;
9use std::fmt::{Display, Formatter};
10use strum::{EnumString, IntoStaticStr};
11
12// G: global
13#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Copy, Hash, EnumString, IntoStaticStr)]
14/// グローバル設定のキー
15pub enum GlobalSettingKey {
16    #[strum(serialize = "locale")]
17    /// 言語と地域
18    Locale,
19    #[strum(serialize = "font")]
20    /// フォント
21    Font,
22    #[strum(serialize = "last-opened-file")]
23    /// 最後に開いたファイルのパス
24    LastOpened,
25    #[strum(serialize = "auto-open-last-opened-file")]
26    /// 最後に開いたファイルを自動で開く
27    AutoOpenLastOpened,
28}
29
30// B: book
31
32#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Copy, Hash, EnumString, IntoStaticStr)]
33/// ブック設定のキー
34pub enum BookSettingKey {
35    #[strum(serialize = "locked")]
36    /// 使用されません
37    Todo,
38}
39
40#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Copy, Hash)]
41/// アプリケーション全体の設定キー
42pub enum SettingKey {
43    /// グローバル設定
44    Global(GlobalSettingKey),
45    /// ブック設定
46    Book(BookSettingKey),
47}
48
49impl Into<DBType> for SettingKey {
50    fn into(self) -> DBType {
51        match self {
52            SettingKey::Global(_) => DBType::AppGlobal,
53            SettingKey::Book(_) => DBType::PrehniteBook,
54        }
55    }
56}
57
58impl SettingKey {
59    /// 設定キーからdbコネクションを取得します。
60    pub async fn get_conn(self) -> Option<PoolConnection<Sqlite>> {
61        acquire_or_log(self.into()).await
62    }
63}
64
65impl From<GlobalSettingKey> for SettingKey {
66    fn from(value: GlobalSettingKey) -> Self {
67        Self::Global(value)
68    }
69}
70
71impl From<BookSettingKey> for SettingKey {
72    fn from(value: BookSettingKey) -> Self {
73        Self::Book(value)
74    }
75}
76
77impl SettingKey {
78    fn as_str(&self) -> &'static str {
79        match self {
80            SettingKey::Global(g_key) => g_key.into(),
81            SettingKey::Book(b_key) => b_key.into(),
82        }
83    }
84}
85
86impl Display for SettingKey {
87    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
88        write!(f, "{}", self.as_str())
89    }
90}
91
92use crate::i18n::i18n;
93use crate::settings::value::SettingValueType;
94
95#[derive(Default, Debug, Clone)]
96/// 設定のカテゴリ
97pub struct SettingCategory {
98    category_name_i18n_key: &'static str,
99    entries: Vec<SettingEntry>,
100}
101
102impl SettingCategory {
103    /// カテゴリ名を取得します。
104    #[inline]
105    pub fn category_name(&self) -> String {
106        i18n(self.category_name_i18n_key)
107    }
108
109    /// 設定項目のリストを取得します。
110    #[inline]
111    pub fn entries(&self) -> &'_ Vec<SettingEntry> {
112        &self.entries
113    }
114
115    fn new(category_name_i18n_key: &'static str) -> Self {
116        Self {
117            category_name_i18n_key,
118            ..Default::default()
119        }
120    }
121
122    fn add(mut self, entry: SettingEntry) -> Self {
123        self.entries.push(entry);
124        self
125    }
126}
127
128#[derive(Debug, Clone)]
129/// 設定項目
130pub struct SettingEntry {
131    setting_key: SettingKey,
132    display_key: &'static str,
133    /// 初期値
134    ///
135    /// この値によって設定値の型が決定されます。
136    default_value: SettingValueType,
137    /// 設定画面での可視性
138    is_visible: bool,
139    /// 選択可能な値リスト
140    selectable_values: Option<Vec<String>>,
141}
142
143impl From<SettingEntry> for String {
144    fn from(value: SettingEntry) -> Self {
145        value.get_display()
146    }
147}
148
149impl Display for SettingEntry {
150    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
151        write!(f, "{}", self.get_display())
152    }
153}
154
155impl SettingEntry {
156    fn new(setting_key: SettingKey, default_value: SettingValueType) -> Self {
157        SettingEntry {
158            setting_key,
159            display_key: setting_key.as_str(),
160            default_value,
161            is_visible: true,
162            selectable_values: None,
163        }
164    }
165
166    /// 設定キーを取得する。
167    #[inline]
168    pub fn get_setting_key(&self) -> SettingKey {
169        self.setting_key
170    }
171
172    /// 設定名を取得する。
173    #[inline]
174    pub fn get_display(&self) -> String {
175        i18n(self.display_key)
176    }
177
178    //noinspection RsUnnecessaryReturn
179    /// 設定画面での可視性を取得する。
180    #[inline]
181    pub fn get_is_visible(&self) -> bool {
182        #[cfg(feature = "debug")]
183        return true;
184        #[cfg(not(feature = "debug"))]
185        return self.is_visible;
186    }
187
188    /// コンボボックス用の値リストを取得する。
189    #[inline]
190    pub fn get_selectable_values(&self) -> Option<Vec<String>> {
191        self.selectable_values.clone()
192    }
193
194    /// 初期値を取得する。
195    #[inline]
196    pub fn default_value(&self) -> &SettingValueType {
197        &self.default_value
198    }
199
200    fn visibility(mut self, is_visible: bool) -> Self {
201        self.is_visible = is_visible;
202        self
203    }
204
205    fn display_key(mut self, display_key: &'static str) -> Self {
206        self.display_key = display_key;
207        self
208    }
209
210    #[tracing::instrument]
211    fn selectable_values(mut self, values: &'static [&str]) -> Self {
212        if let SettingValueType::String(_) = self.default_value {
213            self.selectable_values = Some(values.iter().map(|v| v.to_string()).collect());
214        } else {
215            error!("Selectable Values Not Allowed!!");
216            panic!("Selectable Values Not Allowed!!")
217        }
218        self
219    }
220}