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
124pub 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
144pub 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
166pub 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
186pub 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}