1use std::borrow::Cow;
4
5use serde::de;
6
7mod file;
8mod string;
9mod tuple;
10mod utils;
11
12pub use self::file::*;
13pub use self::string::*;
14
15pub trait Source {
20 fn expand_bool<E>(&mut self, v: &str) -> Result<Option<bool>, E>
22 where
23 E: de::Error;
24
25 fn expand_i8<E>(&mut self, v: &str) -> Result<Option<i8>, E>
27 where
28 E: de::Error;
29
30 fn expand_i16<E>(&mut self, v: &str) -> Result<Option<i16>, E>
32 where
33 E: de::Error;
34
35 fn expand_i32<E>(&mut self, v: &str) -> Result<Option<i32>, E>
37 where
38 E: de::Error;
39
40 fn expand_i64<E>(&mut self, v: &str) -> Result<Option<i64>, E>
42 where
43 E: de::Error;
44
45 fn expand_u8<E>(&mut self, v: &str) -> Result<Option<u8>, E>
47 where
48 E: de::Error;
49
50 fn expand_u16<E>(&mut self, v: &str) -> Result<Option<u16>, E>
52 where
53 E: de::Error;
54
55 fn expand_u32<E>(&mut self, v: &str) -> Result<Option<u32>, E>
57 where
58 E: de::Error;
59
60 fn expand_u64<E>(&mut self, v: &str) -> Result<Option<u64>, E>
62 where
63 E: de::Error;
64
65 fn expand_f32<E>(&mut self, v: &str) -> Result<Option<f32>, E>
67 where
68 E: de::Error;
69
70 fn expand_f64<E>(&mut self, v: &str) -> Result<Option<f64>, E>
72 where
73 E: de::Error;
74
75 fn expand_str<'a, E>(&mut self, v: Cow<'a, str>) -> Result<Expansion<Cow<'a, str>>, E>
77 where
78 E: de::Error;
79
80 fn expand_bytes<'a, E>(&mut self, v: Cow<'a, [u8]>) -> Result<Expansion<Cow<'a, [u8]>>, E>
85 where
86 E: de::Error;
87
88 fn expand_any<'a, E>(&mut self, v: Cow<'a, str>) -> Result<Expansion<Any<'a>, Cow<'a, str>>, E>
95 where
96 E: de::Error;
97}
98
99pub enum Expansion<T, S = T> {
104 Expanded(T),
106 Original(S),
108}
109
110impl<T> Expansion<T> {
111 pub(crate) fn map<S, F>(self, f: F) -> Expansion<S>
112 where
113 F: FnOnce(T) -> S,
114 {
115 match self {
116 Expansion::Expanded(v) => Expansion::Expanded(f(v)),
117 Expansion::Original(v) => Expansion::Original(f(v)),
118 }
119 }
120
121 pub(crate) fn collapse(self) -> T {
122 match self {
123 Expansion::Expanded(v) => v,
124 Expansion::Original(v) => v,
125 }
126 }
127}
128
129impl<'a> Expansion<Any<'a>, Cow<'a, str>> {
130 pub(crate) fn visit<'de, V, E>(self, visitor: V) -> Result<V::Value, E>
131 where
132 V: de::Visitor<'de>,
133 E: de::Error,
134 {
135 match self {
136 Expansion::Expanded(expanded) => expanded.visit(visitor),
137 Expansion::Original(Cow::Owned(v)) => visitor.visit_string(v),
138 Expansion::Original(Cow::Borrowed(v)) => visitor.visit_str(v),
139 }
140 }
141
142 pub(crate) fn visit_borrowed<V, E>(self, visitor: V) -> Result<V::Value, E>
143 where
144 V: de::Visitor<'a>,
145 E: de::Error,
146 {
147 match self {
148 Expansion::Expanded(expanded) => expanded.visit_borrowed(visitor),
149 Expansion::Original(Cow::Owned(v)) => visitor.visit_string(v),
150 Expansion::Original(Cow::Borrowed(v)) => visitor.visit_borrowed_str(v),
151 }
152 }
153}
154
155pub enum Any<'a> {
159 Bool(bool),
160 I8(i8),
161 I16(i16),
162 I32(i32),
163 I64(i64),
164 U8(u8),
165 U16(u16),
166 U32(u32),
167 U64(u64),
168 F32(f32),
169 F64(f64),
170 Str(Cow<'a, str>),
171 Bytes(Cow<'a, [u8]>),
172}
173
174impl<'a> Any<'a> {
175 pub fn unexpected(&self) -> de::Unexpected<'_> {
177 match self {
178 Any::Bool(v) => de::Unexpected::Bool(*v),
179 Any::I8(v) => de::Unexpected::Signed(i64::from(*v)),
180 Any::I16(v) => de::Unexpected::Signed(i64::from(*v)),
181 Any::I32(v) => de::Unexpected::Signed(i64::from(*v)),
182 Any::I64(v) => de::Unexpected::Signed(*v),
183 Any::U8(v) => de::Unexpected::Unsigned(u64::from(*v)),
184 Any::U16(v) => de::Unexpected::Unsigned(u64::from(*v)),
185 Any::U32(v) => de::Unexpected::Unsigned(u64::from(*v)),
186 Any::U64(v) => de::Unexpected::Unsigned(*v),
187 Any::F32(v) => de::Unexpected::Float(f64::from(*v)),
188 Any::F64(v) => de::Unexpected::Float(*v),
189 Any::Str(v) => de::Unexpected::Str(v),
190 Any::Bytes(v) => de::Unexpected::Bytes(v),
191 }
192 }
193
194 pub(crate) fn visit_borrowed<V, E>(self, visitor: V) -> Result<V::Value, E>
195 where
196 V: de::Visitor<'a>,
197 E: de::Error,
198 {
199 match self {
200 Any::Str(Cow::Borrowed(v)) => visitor.visit_borrowed_str(v),
201 Any::Bytes(Cow::Borrowed(v)) => visitor.visit_borrowed_bytes(v),
202 other => other.visit(visitor),
203 }
204 }
205
206 pub(crate) fn visit<'de, V, E>(self, visitor: V) -> Result<V::Value, E>
207 where
208 V: de::Visitor<'de>,
209 E: de::Error,
210 {
211 match self {
212 Any::Bool(v) => visitor.visit_bool(v),
213 Any::I8(v) => visitor.visit_i8(v),
214 Any::I16(v) => visitor.visit_i16(v),
215 Any::I32(v) => visitor.visit_i32(v),
216 Any::I64(v) => visitor.visit_i64(v),
217 Any::U8(v) => visitor.visit_u8(v),
218 Any::U16(v) => visitor.visit_u16(v),
219 Any::U32(v) => visitor.visit_u32(v),
220 Any::U64(v) => visitor.visit_u64(v),
221 Any::F32(v) => visitor.visit_f32(v),
222 Any::F64(v) => visitor.visit_f64(v),
223 Any::Str(Cow::Owned(v)) => visitor.visit_string(v),
224 Any::Str(Cow::Borrowed(v)) => visitor.visit_str(v),
225 Any::Bytes(Cow::Owned(v)) => visitor.visit_byte_buf(v),
226 Any::Bytes(Cow::Borrowed(v)) => visitor.visit_bytes(v),
227 }
228 }
229}