1pub(crate) mod commit;
2pub(crate) mod filter;
3pub(crate) mod index;
4pub(crate) mod optset;
5pub(crate) mod optvalid;
6
7pub use self::commit::SetCommit;
8pub use self::commit::SetCommitWithValue;
9pub use self::filter::Filter;
10pub use self::filter::FilterMatcher;
11pub use self::filter::FilterMut;
12pub use self::index::SetIndex;
13pub use self::optset::OptSet;
14pub use self::optvalid::OptValidator;
15pub use self::optvalid::PrefixOptValidator;
16pub use self::optvalid::PrefixedValidator;
17
18use std::any::type_name;
19use std::fmt::Debug;
20use std::slice::Iter;
21use std::slice::IterMut;
22
23use crate::error;
24use crate::map::ErasedTy;
25use crate::opt::Action;
26use crate::opt::Cid;
27use crate::opt::ConfigBuild;
28use crate::opt::ConfigValue;
29use crate::opt::Index;
30use crate::opt::Opt;
31use crate::opt::OptValueExt;
32use crate::value::ValInitializer;
33use crate::value::ValStorer;
34use crate::Error;
35use crate::Uid;
36
37pub type SetOpt<I> = <<I as Set>::Ctor as Ctor>::Opt;
39pub type SetCfg<I> = <<I as Set>::Ctor as Ctor>::Config;
41
42#[cfg(feature = "sync")]
43impl<Opt: crate::opt::Opt, Config: Send + Sync, Err: Into<Error>> Ctor
45 for Box<dyn Ctor<Opt = Opt, Config = Config, Error = Err> + Send + Sync>
46{
47 type Opt = Opt;
48
49 type Config = Config;
50
51 type Error = Err;
52
53 fn cid(&self) -> &Cid {
54 Ctor::cid(self.as_ref())
55 }
56
57 fn new_with(&mut self, config: Self::Config) -> Result<Self::Opt, Self::Error> {
58 Ctor::new_with(self.as_mut(), config)
59 }
60}
61
62#[cfg(feature = "sync")]
63impl<Opt: crate::opt::Opt, Config: Send + Sync, Err: Into<Error>> Debug
64 for Box<dyn Ctor<Opt = Opt, Config = Config, Error = Err> + Send + Sync>
65{
66 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
67 f.debug_tuple("Ctor").finish()
68 }
69}
70
71#[cfg(not(feature = "sync"))]
72impl<Opt: crate::opt::Opt, Config, Err: Into<Error>> Ctor
74 for Box<dyn Ctor<Opt = Opt, Config = Config, Error = Err>>
75{
76 type Opt = Opt;
77
78 type Config = Config;
79
80 type Error = Err;
81
82 fn cid(&self) -> &Cid {
83 Ctor::cid(self.as_ref())
84 }
85
86 fn new_with(&mut self, config: Self::Config) -> Result<Self::Opt, Self::Error> {
87 Ctor::new_with(self.as_mut(), config)
88 }
89}
90
91#[cfg(not(feature = "sync"))]
92impl<Opt: crate::opt::Opt, Config, Err: Into<Error>> Debug
93 for Box<dyn Ctor<Opt = Opt, Config = Config, Error = Err>>
94{
95 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
96 f.debug_tuple("Ctor").finish()
97 }
98}
99
100pub const CTOR_DEFAULT: &str = crate::opt::creator::CID_FALLBACK;
101
102pub fn ctor_default_name() -> String {
103 String::from(CTOR_DEFAULT)
104}
105
106pub trait Ctor {
108 type Opt: Opt;
109 type Config;
110 type Error: Into<Error>;
111
112 fn cid(&self) -> &Cid;
113
114 fn new_with(&mut self, config: Self::Config) -> Result<Self::Opt, Self::Error>;
115}
116
117pub trait Set {
119 type Ctor: Ctor;
120
121 fn register(&mut self, ctor: Self::Ctor) -> Option<Self::Ctor>;
123
124 fn contain_ctor(&self, name: &str) -> bool {
125 self.get_ctor(name).is_some()
126 }
127
128 fn get_ctor(&self, name: &str) -> Option<&Self::Ctor>;
129
130 fn get_ctor_mut(&mut self, name: &str) -> Option<&mut Self::Ctor>;
131
132 fn reset(&mut self);
133
134 fn len(&self) -> usize;
136
137 fn is_empty(&self) -> bool {
138 self.len() == 0
139 }
140
141 fn keys(&self) -> Vec<Uid> {
143 self.iter().map(|v| v.uid()).collect()
144 }
145
146 fn iter(&self) -> Iter<'_, SetOpt<Self>>;
147
148 fn iter_mut(&mut self) -> IterMut<'_, SetOpt<Self>>;
149
150 fn contain(&self, uid: Uid) -> bool {
151 self.iter().any(|v| v.uid() == uid)
152 }
153
154 fn insert(&mut self, opt: SetOpt<Self>) -> Uid;
155
156 fn get(&self, uid: Uid) -> Option<&SetOpt<Self>> {
157 self.iter().find(|v| v.uid() == uid)
158 }
159
160 fn get_mut(&mut self, uid: Uid) -> Option<&mut SetOpt<Self>> {
161 self.iter_mut().find(|v| v.uid() == uid)
162 }
163}
164
165pub trait SetExt<C: Ctor> {
166 fn opt(&self, uid: Uid) -> Result<&C::Opt, Error>;
167
168 fn opt_mut(&mut self, uid: Uid) -> Result<&mut C::Opt, Error>;
169
170 fn ctor(&self, name: &str) -> Result<&C, Error>;
171
172 fn ctor_mut(&mut self, name: &str) -> Result<&mut C, Error>;
173}
174
175impl<S: Set> SetExt<S::Ctor> for S {
176 fn opt(&self, uid: Uid) -> Result<&<S::Ctor as Ctor>::Opt, Error> {
177 self.get(uid)
178 .ok_or_else(|| error!("can not find option `{}` by uid", uid).with_uid(uid))
179 }
180
181 fn opt_mut(&mut self, uid: Uid) -> Result<&mut <S::Ctor as Ctor>::Opt, Error> {
182 self.get_mut(uid)
183 .ok_or_else(|| error!("can not find option(mut) `{}` by uid", uid).with_uid(uid))
184 }
185
186 fn ctor(&self, name: &str) -> Result<&S::Ctor, Error> {
187 self.get_ctor(name)
188 .ok_or_else(|| error!("can not find creator `{}` by name", name))
189 }
190
191 fn ctor_mut(&mut self, name: &str) -> Result<&mut S::Ctor, Error> {
192 self.get_ctor_mut(name)
193 .ok_or_else(|| error!("can not find creator(mut) `{}` by name", name))
194 }
195}
196
197pub trait SetValueFindExt
198where
199 Self: Set + Sized,
200 SetCfg<Self>: ConfigValue + Default,
201{
202 fn find_uid(&self, cb: impl ConfigBuild<SetCfg<Self>>) -> Result<Uid, Error>;
203
204 fn find_opt(&self, cb: impl ConfigBuild<SetCfg<Self>>) -> Result<&SetOpt<Self>, Error> {
205 self.opt(self.find_uid(cb)?)
206 }
207
208 fn find_opt_mut(
209 &mut self,
210 cb: impl ConfigBuild<SetCfg<Self>>,
211 ) -> Result<&mut SetOpt<Self>, Error> {
212 self.opt_mut(self.find_uid(cb)?)
213 }
214
215 fn find_val<T: ErasedTy>(&self, cb: impl ConfigBuild<SetCfg<Self>>) -> Result<&T, Error> {
216 self.opt(self.find_uid(cb)?)?.val::<T>()
217 }
218
219 fn find_val_mut<T: ErasedTy>(
220 &mut self,
221 cb: impl ConfigBuild<SetCfg<Self>>,
222 ) -> Result<&mut T, Error> {
223 self.opt_mut(self.find_uid(cb)?)?.val_mut()
224 }
225
226 fn find_vals<T: ErasedTy>(&self, cb: impl ConfigBuild<SetCfg<Self>>) -> Result<&Vec<T>, Error> {
227 self.opt(self.find_uid(cb)?)?.vals()
228 }
229
230 fn find_vals_mut<T: ErasedTy>(
231 &mut self,
232 cb: impl ConfigBuild<SetCfg<Self>>,
233 ) -> Result<&mut Vec<T>, Error> {
234 self.opt_mut(self.find_uid(cb)?)?.vals_mut()
235 }
236
237 fn take_val<T: ErasedTy>(&mut self, cb: impl ConfigBuild<SetCfg<Self>>) -> Result<T, Error> {
238 let opt = self.opt_mut(self.find_uid(cb)?)?;
239 let (name, uid) = (opt.name(), opt.uid());
240 let err = error!(
241 "can not take value({}) of option `{name}`",
242 type_name::<T>(),
243 );
244
245 opt.vals_mut::<T>()?.pop().ok_or_else(|| err.with_uid(uid))
246 }
247
248 fn take_vals<T: ErasedTy>(
249 &mut self,
250 cb: impl ConfigBuild<SetCfg<Self>>,
251 ) -> Result<Vec<T>, Error> {
252 let opt = self.opt_mut(self.find_uid(cb)?)?;
253 let (name, uid) = (opt.name(), opt.uid());
254 let err = error!(
255 "can not take values({}) of option `{name}`",
256 type_name::<T>(),
257 );
258
259 Ok(std::mem::take(
260 opt.vals_mut::<T>()
261 .map_err(|e| err.with_uid(uid).cause_by(e))?,
262 ))
263 }
264}
265
266pub trait Commit<S: Set>
267where
268 Self: Sized,
269 SetCfg<S>: ConfigValue + Default,
270{
271 fn cfg(&self) -> &SetCfg<S>;
272
273 fn cfg_mut(&mut self) -> &mut SetCfg<S>;
274
275 fn set_index(mut self, index: Index) -> Self {
276 self.cfg_mut().set_index(index);
277 self
278 }
279
280 fn set_action(mut self, action: Action) -> Self {
281 self.cfg_mut().set_action(action);
282 self
283 }
284
285 fn set_name(mut self, name: impl Into<String>) -> Self {
286 self.cfg_mut().set_name(name);
287 self
288 }
289
290 fn set_ctor(mut self, ctor: impl Into<String>) -> Self {
291 self.cfg_mut().set_ctor(ctor);
292 self
293 }
294
295 fn clr_alias(mut self) -> Self {
296 self.cfg_mut().clr_alias();
297 self
298 }
299
300 fn rem_alias(mut self, alias: impl AsRef<str>) -> Self {
301 self.cfg_mut().rem_alias(alias);
302 self
303 }
304
305 fn add_alias(mut self, alias: impl Into<String>) -> Self {
306 self.cfg_mut().add_alias(alias);
307 self
308 }
309
310 fn set_force(mut self, force: bool) -> Self {
311 self.cfg_mut().set_force(force);
312 self
313 }
314
315 fn set_hint(mut self, hint: impl Into<String>) -> Self {
316 self.cfg_mut().set_hint(hint);
317 self
318 }
319
320 fn set_help(mut self, help: impl Into<String>) -> Self {
321 self.cfg_mut().set_help(help);
322 self
323 }
324
325 fn set_storer(mut self, storer: ValStorer) -> Self {
326 self.cfg_mut().set_storer(storer);
327 self
328 }
329
330 fn set_initializer<T: Into<ValInitializer>>(mut self, initializer: T) -> Self {
331 self.cfg_mut().set_initializer(initializer.into());
332 self
333 }
334}
335
336pub trait SetChecker<S> {
337 type Error: Into<Error>;
338
339 fn pre_check(&self, set: &mut S) -> Result<bool, Self::Error>;
340
341 fn opt_check(&self, set: &mut S) -> Result<bool, Self::Error>;
342
343 fn pos_check(&self, set: &mut S) -> Result<bool, Self::Error>;
344
345 fn cmd_check(&self, set: &mut S) -> Result<bool, Self::Error>;
346
347 fn post_check(&self, set: &mut S) -> Result<bool, Self::Error>;
348}