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
125pub 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
145pub 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
167pub 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
184pub 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}