prehnite_core/settings/
value.rs1#![doc = "設定の項目値"]
2use crate::db::query;
3use crate::settings::SettingKey;
4use sqlx::SqliteConnection;
5
6#[derive(Clone, Debug)]
7pub enum SettingValueType {
9 Bool(Option<bool>),
10 Int(Option<i64>),
11 Float(Option<f64>),
12 String(Option<String>),
13}
14
15impl From<SettingValueType> for Option<bool> {
16 fn from(value: SettingValueType) -> Self {
17 value.bool()
18 }
19}
20
21impl From<SettingValueType> for Option<i64> {
22 fn from(value: SettingValueType) -> Self {
23 value.int()
24 }
25}
26
27impl From<SettingValueType> for Option<String> {
28 fn from(value: SettingValueType) -> Self {
29 value.string()
30 }
31}
32
33impl From<SettingValueType> for Option<f64> {
34 fn from(value: SettingValueType) -> Self {
35 value.float()
36 }
37}
38
39macro_rules! setting_value_type_to_string(
40 ($v:ident) => {
41 $v.map(|v| v.to_string())
42 }
43);
44
45macro_rules! auto_impl_from_non_option(
46 ($($t:ty),*) => {
47 $(
48 impl From<$t> for SettingValueType {
49 fn from(value: $t) -> Self {
50 Some(value).into()
51 }
52 }
53 )*
54 }
55);
56
57auto_impl_from_non_option!(bool, i64, i32, i16, i8, f64, f32, String, &str);
58
59macro_rules! auto_impl_from_option {
60 ($(($t:ty, $req_t:ty, $p:path)),*) => {
61 $(impl From<Option<$t>> for SettingValueType {
62 fn from(value: Option<$t>) -> Self {
63 $p(value.map(|v| v as $req_t))
64 }
65 })*
66 };
67 ($(($t:ty, $p:path)),*)=>{
68 auto_impl_from_option!($(($t, $t, $p)),*);
69 };
70}
71
72auto_impl_from_option!(
73 (bool, SettingValueType::Bool),
74 (i64, SettingValueType::Int),
75 (f64, SettingValueType::Float),
76 (String, SettingValueType::String)
77);
78
79auto_impl_from_option!(
80 (i32, i64, SettingValueType::Int),
81 (i16, i64, SettingValueType::Int),
82 (i8, i64, SettingValueType::Int),
83 (f32, f64, SettingValueType::Float)
84);
85
86impl From<Option<&str>> for SettingValueType {
87 fn from(value: Option<&str>) -> Self {
88 value.map(|v| v.to_string()).into()
89 }
90}
91
92impl SettingValueType {
93 pub fn converter(&self, value: Option<String>) -> Self {
95 match self {
96 SettingValueType::Bool(_) => value.and_then(|v| v.parse::<bool>().ok()).into(),
97 SettingValueType::Int(_) => value.and_then(|v| v.parse::<i64>().ok()).into(),
98 SettingValueType::Float(_) => value.and_then(|v| v.parse::<f64>().ok()).into(),
99 SettingValueType::String(_) => value.into(),
100 }
101 }
102
103 pub fn set(mut self, v: SettingValueType) {
105 self = v;
106 }
107
108 #[tracing::instrument]
109 pub async fn save(
111 &self,
112 conn: &mut SqliteConnection,
113 setting_key: SettingKey,
114 ) -> sqlx::Result<()> {
115 query::update_setting(conn, setting_key, self.clone().to_opt_string()).await
116 }
117
118 pub fn get<T>(self) -> Option<T>
120 where
121 Option<T>: From<SettingValueType>,
122 {
123 Option::<T>::from(self)
124 }
125
126 pub fn to_opt_string(self) -> Option<String> {
128 match self {
129 SettingValueType::Bool(v) => setting_value_type_to_string!(v),
130 SettingValueType::Int(v) => setting_value_type_to_string!(v),
131 SettingValueType::Float(v) => setting_value_type_to_string!(v),
132 SettingValueType::String(v) => v,
133 }
134 }
135
136 fn bool(self) -> Option<bool> {
138 if let Self::Bool(v) = self { v } else { None }
139 }
140
141 fn int(self) -> Option<i64> {
143 if let Self::Int(v) = self { v } else { None }
144 }
145
146 fn string(self) -> Option<String> {
148 if let Self::String(v) = self { v } else { None }
149 }
150
151 fn float(self) -> Option<f64> {
153 if let Self::Float(v) = self { v } else { None }
154 }
155}