aopt/
set.rs

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
37/// An type alias for `<<I as Set>::Ctor as Ctor>::Opt`
38pub type SetOpt<I> = <<I as Set>::Ctor as Ctor>::Opt;
39/// An type alias for `<<I as Set>::Ctor as Ctor>::Config`
40pub type SetCfg<I> = <<I as Set>::Ctor as Ctor>::Config;
41
42#[cfg(feature = "sync")]
43/// Implement [`Ctor`] for `Box<dyn Ctor>`.
44impl<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"))]
72/// Implement [`Ctor`] for `Box<dyn Ctor>`.
73impl<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
106/// Create [`Opt`](crate::set::Ctor::Opt) with given [`Config`](crate::set::Ctor::Config).
107pub 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
117/// A collection of [`Ctor`](Set::Ctor) and [`Opt`](Ctor::Opt).
118pub trait Set {
119    type Ctor: Ctor;
120
121    /// Register a option creator type into option set.
122    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    /// Return the number of options.
135    fn len(&self) -> usize;
136
137    fn is_empty(&self) -> bool {
138        self.len() == 0
139    }
140
141    /// Return all the unique uid of option set.
142    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}