Skip to main content

orion_conf/
traits.rs

1pub use derive_getters::Getters;
2pub use orion_error::UvsFrom as UvsConfFrom;
3pub use orion_error::{ErrorOwe, ErrorWith, StructError, ToStructError, UvsFrom};
4use orion_variate::EnvDict;
5pub use serde_derive::{Deserialize, Serialize};
6use std::path::Path;
7
8use crate::error::OrionConfResult;
9
10// 核心持久化 trait - 不依赖任何特定格式
11pub trait FilePersist<T> {
12    fn save_to(&self, path: &Path, name: Option<String>) -> OrionConfResult<()>;
13    fn load_from(path: &Path) -> OrionConfResult<T>;
14}
15
16// 通用配置 trait - 默认行为基于可用特性
17pub trait ConfigIO<T>
18where
19    T: serde::de::DeserializeOwned + serde::Serialize,
20{
21    fn load_conf(path: &Path) -> OrionConfResult<T>;
22    fn save_conf(&self, path: &Path) -> OrionConfResult<()>;
23}
24
25// 通用配置 trait - 默认行为基于可用特性
26pub trait EnvLoadable<T>
27where
28    T: serde::de::DeserializeOwned,
29{
30    // 推荐方法名
31    fn env_load_conf(path: &Path, dict: &EnvDict) -> OrionConfResult<T>;
32}
33
34// 格式特定的 trait - 每个都使用条件编译
35
36#[cfg(feature = "ini")]
37pub trait IniIO<T>
38where
39    T: serde::de::DeserializeOwned + serde::Serialize,
40{
41    fn load_ini(path: &Path) -> OrionConfResult<T>;
42    fn save_ini(&self, path: &Path) -> OrionConfResult<()>;
43}
44
45#[cfg(feature = "ini")]
46pub trait EnvIniLoad<T>
47where
48    T: serde::de::DeserializeOwned,
49{
50    fn env_load_ini(path: &Path, dict: &EnvDict) -> OrionConfResult<T>;
51    fn env_parse_ini(content: &str, dict: &EnvDict) -> OrionConfResult<T>;
52}
53
54#[cfg(feature = "json")]
55pub trait JsonIO<T>
56where
57    T: serde::de::DeserializeOwned + serde::Serialize,
58{
59    fn load_json(path: &Path) -> OrionConfResult<T>;
60    fn save_json(&self, path: &Path) -> OrionConfResult<()>;
61}
62
63#[cfg(feature = "json")]
64pub trait EnvJsonLoad<T>
65where
66    T: serde::de::DeserializeOwned,
67{
68    fn env_load_json(path: &Path, dict: &EnvDict) -> OrionConfResult<T>;
69    fn env_parse_json(content: &str, dict: &EnvDict) -> OrionConfResult<T>;
70}
71
72#[cfg(feature = "toml")]
73pub trait TomlIO<T>
74where
75    T: serde::de::DeserializeOwned + serde::Serialize,
76{
77    fn load_toml(path: &Path) -> OrionConfResult<T>;
78    fn save_toml(&self, path: &Path) -> OrionConfResult<()>;
79}
80
81#[cfg(feature = "toml")]
82pub trait EnvTomlLoad<T>
83where
84    T: serde::de::DeserializeOwned,
85{
86    fn env_load_toml(path: &Path, dict: &EnvDict) -> OrionConfResult<T>;
87    fn env_parse_toml(content: &str, dict: &EnvDict) -> OrionConfResult<T>;
88}
89
90#[cfg(feature = "toml")]
91pub trait TextConfigIO<T>
92where
93    T: serde::de::DeserializeOwned + serde::Serialize,
94{
95    fn load_valconf(path: &Path) -> OrionConfResult<T>;
96    fn save_valconf(&self, path: &Path) -> OrionConfResult<()>;
97}
98
99#[cfg(feature = "yaml")]
100pub trait YamlIO<T>
101where
102    T: serde::de::DeserializeOwned + serde::Serialize,
103{
104    fn load_yaml(path: &Path) -> OrionConfResult<T>;
105    fn save_yaml(&self, path: &Path) -> OrionConfResult<()>;
106}
107
108#[cfg(feature = "yaml")]
109pub trait EnvYamlLoad<T>
110where
111    T: serde::de::DeserializeOwned,
112{
113    fn env_load_yaml(path: &Path, dict: &EnvDict) -> OrionConfResult<T>;
114    fn env_parse_yaml(content: &str, dict: &EnvDict) -> OrionConfResult<T>;
115}
116
117pub trait LoadHook {
118    fn loaded_event_do(&mut self) {}
119}
120
121// 默认实现选择逻辑 - 基于特性优先级
122impl<T> ConfigIO<T> for T
123where
124    T: serde::de::DeserializeOwned + serde::Serialize,
125{
126    #[cfg(feature = "yaml")]
127    fn load_conf(path: &Path) -> OrionConfResult<T> {
128        T::load_yaml(path)
129    }
130
131    #[cfg(all(feature = "toml", not(feature = "yaml")))]
132    fn load_conf(path: &Path) -> OrionConfResult<T> {
133        T::load_toml(path)
134    }
135
136    #[cfg(all(feature = "json", not(any(feature = "yaml", feature = "toml"))))]
137    fn load_conf(path: &Path) -> OrionConfResult<T> {
138        T::load_json(path)
139    }
140
141    #[cfg(all(
142        feature = "ini",
143        not(any(feature = "yaml", feature = "toml", feature = "json"))
144    ))]
145    fn load_conf(path: &Path) -> OrionConfResult<T> {
146        T::load_ini(path)
147    }
148
149    #[cfg(not(any(feature = "yaml", feature = "toml", feature = "json", feature = "ini")))]
150    fn load_conf(_path: &Path) -> OrionConfResult<T> {
151        use crate::error::ConfIOReason;
152        Err(ConfIOReason::NoFormatEnabled.to_err())
153    }
154
155    #[cfg(feature = "yaml")]
156    fn save_conf(&self, path: &Path) -> OrionConfResult<()> {
157        self.save_yaml(path)
158    }
159
160    #[cfg(all(feature = "toml", not(feature = "yaml")))]
161    fn save_conf(&self, path: &Path) -> OrionConfResult<()> {
162        self.save_toml(path)
163    }
164
165    #[cfg(all(feature = "json", not(any(feature = "yaml", feature = "toml"))))]
166    fn save_conf(&self, path: &Path) -> OrionConfResult<()> {
167        self.save_json(path)
168    }
169
170    #[cfg(all(
171        feature = "ini",
172        not(any(feature = "yaml", feature = "toml", feature = "json"))
173    ))]
174    fn save_conf(&self, path: &Path) -> OrionConfResult<()> {
175        self.save_ini(path)
176    }
177
178    #[cfg(not(any(feature = "yaml", feature = "toml", feature = "json", feature = "ini")))]
179    fn save_conf(&self, _path: &Path) -> OrionConfResult<()> {
180        use crate::error::ConfIOReason;
181        Err(ConfIOReason::NoFormatEnabled.to_err())
182    }
183}
184
185// TextConfigIO 的默认实现 - 委托给 YAML 或 TOML
186#[cfg(feature = "toml")]
187impl<T> TextConfigIO<T> for T
188where
189    T: serde::de::DeserializeOwned + serde::Serialize,
190{
191    #[cfg(feature = "yaml")]
192    fn load_valconf(path: &Path) -> OrionConfResult<T> {
193        T::load_yaml(path)
194    }
195
196    #[cfg(not(feature = "yaml"))]
197    fn load_valconf(path: &Path) -> OrionConfResult<T> {
198        T::load_toml(path)
199    }
200
201    #[cfg(feature = "yaml")]
202    fn save_valconf(&self, path: &Path) -> OrionConfResult<()> {
203        self.save_yaml(path)
204    }
205
206    #[cfg(not(feature = "yaml"))]
207    fn save_valconf(&self, path: &Path) -> OrionConfResult<()> {
208        self.save_toml(path)
209    }
210}