orion_conf/
traits.rs

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