aopt_shell/
value.rs

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