aopt_shell/
value.rs

1use std::cell::RefCell;
2use std::ffi::OsStr;
3use std::ffi::OsString;
4
5use crate::acore::Error;
6
7pub trait Values<O> {
8    type Err: Into<Error>;
9
10    fn get_values(&self, opt: &O) -> Result<Vec<OsString>, Self::Err>;
11}
12
13impl<O> Values<O> for [&OsStr] {
14    type Err = Error;
15
16    fn get_values(&self, _: &O) -> Result<Vec<OsString>, Self::Err> {
17        Ok(self.iter().map(OsString::from).collect())
18    }
19}
20
21impl<O> Values<O> for [OsString] {
22    type Err = Error;
23
24    fn get_values(&self, _: &O) -> Result<Vec<OsString>, Self::Err> {
25        Ok(self.to_vec())
26    }
27}
28
29impl<O> Values<O> for [&str] {
30    type Err = Error;
31
32    fn get_values(&self, _: &O) -> Result<Vec<OsString>, Self::Err> {
33        Ok(self.iter().map(OsString::from).collect())
34    }
35}
36
37impl<O> Values<O> for [String] {
38    type Err = Error;
39
40    fn get_values(&self, _: &O) -> Result<Vec<OsString>, Self::Err> {
41        Ok(self.iter().map(OsString::from).collect())
42    }
43}
44
45impl<const N: usize, O> Values<O> for [&OsStr; N] {
46    type Err = Error;
47
48    fn get_values(&self, _: &O) -> Result<Vec<OsString>, Self::Err> {
49        Ok(self.iter().map(OsString::from).collect())
50    }
51}
52
53impl<const N: usize, O> Values<O> for [OsString; N] {
54    type Err = Error;
55
56    fn get_values(&self, _: &O) -> Result<Vec<OsString>, Self::Err> {
57        Ok(self.to_vec())
58    }
59}
60
61impl<const N: usize, O> Values<O> for [&str; N] {
62    type Err = Error;
63
64    fn get_values(&self, _: &O) -> Result<Vec<OsString>, Self::Err> {
65        Ok(self.iter().map(OsString::from).collect())
66    }
67}
68
69impl<const N: usize, O> Values<O> for [String; N] {
70    type Err = Error;
71
72    fn get_values(&self, _: &O) -> Result<Vec<OsString>, Self::Err> {
73        Ok(self.iter().map(OsString::from).collect())
74    }
75}
76
77impl<O> Values<O> for Vec<&OsStr> {
78    type Err = Error;
79
80    fn get_values(&self, opt: &O) -> Result<Vec<OsString>, Self::Err> {
81        Values::get_values(self.as_slice(), opt)
82    }
83}
84
85impl<O> Values<O> for Vec<OsString> {
86    type Err = Error;
87
88    fn get_values(&self, opt: &O) -> Result<Vec<OsString>, Self::Err> {
89        Values::get_values(self.as_slice(), opt)
90    }
91}
92
93impl<O> Values<O> for Vec<&str> {
94    type Err = Error;
95
96    fn get_values(&self, opt: &O) -> Result<Vec<OsString>, Self::Err> {
97        Values::get_values(self.as_slice(), opt)
98    }
99}
100
101impl<O> Values<O> for Vec<String> {
102    type Err = Error;
103
104    fn get_values(&self, opt: &O) -> Result<Vec<OsString>, Self::Err> {
105        Values::get_values(self.as_slice(), opt)
106    }
107}
108
109pub fn wrap<O, T: Values<O>>(inner: T) -> Adapter<T> {
110    Adapter { inner }
111}
112
113pub struct Adapter<T> {
114    pub inner: T,
115}
116
117impl<O, T: Values<O>> Values<O> for Adapter<T> {
118    type Err = Error;
119
120    fn get_values(&self, opt: &O) -> Result<Vec<OsString>, Self::Err> {
121        self.inner.get_values(opt).map_err(Into::into)
122    }
123}
124
125/// Calls the given function and initialize the value upon first use.
126pub struct OnceValues<O> {
127    vals: RefCell<Option<Vec<OsString>>>,
128
129    #[allow(clippy::type_complexity)]
130    handler: Box<dyn Fn(&O) -> Result<Vec<OsString>, Error>>,
131}
132
133impl<O> OnceValues<O> {
134    pub fn new<F>(handler: F) -> Self
135    where
136        F: Fn(&O) -> Result<Vec<OsString>, Error> + 'static,
137    {
138        Self {
139            vals: RefCell::new(None),
140            handler: Box::new(handler),
141        }
142    }
143}
144
145/// Calls the given function and initialize the value upon first use.
146pub fn once_values<O, F>(handler: F) -> OnceValues<O>
147where
148    F: Fn(&O) -> Result<Vec<OsString>, Error> + 'static,
149{
150    OnceValues::new(handler)
151}
152
153impl<O> Values<O> for OnceValues<O> {
154    type Err = Error;
155
156    fn get_values(&self, opt: &O) -> Result<Vec<OsString>, Self::Err> {
157        if self.vals.borrow().is_none() {
158            *self.vals.borrow_mut() = Some((self.handler)(opt)?);
159        }
160        self.vals
161            .borrow()
162            .clone()
163            .ok_or_else(|| crate::error!("can not get values in OnceValues"))
164    }
165}
166
167/// Calls the given function and initializes the value each time it is used.
168pub struct RepeatValues<O> {
169    #[allow(clippy::type_complexity)]
170    handler: Box<dyn Fn(&O) -> Result<Vec<OsString>, Error>>,
171}
172
173impl<O> RepeatValues<O> {
174    pub fn new<F>(handler: F) -> Self
175    where
176        F: Fn(&O) -> Result<Vec<OsString>, Error> + 'static,
177    {
178        Self {
179            handler: Box::new(handler),
180        }
181    }
182}
183
184/// Calls the given function and initializes the value each time it is used.
185pub fn repeat_values<O, F>(handler: F) -> RepeatValues<O>
186where
187    F: Fn(&O) -> Result<Vec<OsString>, Error> + 'static,
188{
189    RepeatValues::new(handler)
190}
191
192impl<O> Values<O> for RepeatValues<O> {
193    type Err = Error;
194
195    fn get_values(&self, opt: &O) -> Result<Vec<OsString>, Self::Err> {
196        (self.handler)(opt)
197    }
198}