1use crate::{
4 DeserError, Deserialize, Error, ErrorKind, Span,
5 span::Spanned,
6 value::{self, Table, Value, ValueInner},
7};
8use std::{fmt::Display, str::FromStr};
9
10#[inline]
12pub fn expected(expected: &'static str, found: ValueInner<'_>, span: Span) -> Error {
13 Error {
14 kind: ErrorKind::Wanted {
15 expected,
16 found: found.type_str(),
17 },
18 span,
19 line_info: None,
20 }
21}
22
23#[inline]
26pub fn parse<T, E>(value: &mut Value<'_>) -> Result<T, Error>
27where
28 T: FromStr<Err = E>,
29 E: Display,
30{
31 let s = value.take_string(None)?;
32 match s.parse() {
33 Ok(v) => Ok(v),
34 Err(err) => Err(Error {
35 kind: ErrorKind::Custom(format!("failed to parse string: {err}").into()),
36 span: value.span,
37 line_info: None,
38 }),
39 }
40}
41
42pub struct TableHelper<'de> {
44 pub table: Table<'de>,
46 pub errors: Vec<Error>,
48 expected: Vec<&'static str>,
52 span: Span,
54}
55
56impl<'de> From<(Table<'de>, Span)> for TableHelper<'de> {
57 fn from((table, span): (Table<'de>, Span)) -> Self {
58 Self {
59 table,
60 span,
61 expected: Vec::new(),
62 errors: Vec::new(),
63 }
64 }
65}
66
67impl<'de> TableHelper<'de> {
68 pub fn new(value: &mut Value<'de>) -> Result<Self, DeserError> {
70 let table = match value.take() {
71 ValueInner::Table(table) => table,
72 other => return Err(expected("a table", other, value.span).into()),
73 };
74
75 Ok(Self {
76 errors: Vec::new(),
77 table,
78 expected: Vec::new(),
79 span: value.span,
80 })
81 }
82
83 #[inline]
85 pub fn contains(&self, name: &str) -> bool {
86 self.table.contains_key(name)
87 }
88
89 #[inline]
91 pub fn take(&mut self, name: &'static str) -> Option<(value::Key<'de>, Value<'de>)> {
92 self.expected.push(name);
93 self.table.remove_entry(name)
94 }
95
96 #[inline]
106 pub fn required<T: Deserialize<'de>>(&mut self, name: &'static str) -> Result<T, Error> {
107 Ok(self.required_s(name)?.value)
108 }
109
110 pub fn required_s<T: Deserialize<'de>>(
112 &mut self,
113 name: &'static str,
114 ) -> Result<Spanned<T>, Error> {
115 self.expected.push(name);
116
117 let Some(mut val) = self.table.remove(name) else {
118 let missing = Error {
119 kind: ErrorKind::MissingField(name),
120 span: self.span,
121 line_info: None,
122 };
123 self.errors.push(missing.clone());
124 return Err(missing);
125 };
126
127 Spanned::<T>::deserialize(&mut val).map_err(|mut errs| {
128 let err = errs.errors.last().unwrap().clone();
129 self.errors.append(&mut errs.errors);
130 err
131 })
132 }
133
134 #[inline]
140 pub fn optional<T: Deserialize<'de>>(&mut self, name: &'static str) -> Option<T> {
141 self.optional_s(name).map(|v| v.value)
142 }
143
144 pub fn optional_s<T: Deserialize<'de>>(&mut self, name: &'static str) -> Option<Spanned<T>> {
146 self.expected.push(name);
147
148 let mut val = self.table.remove(name)?;
149
150 match Spanned::<T>::deserialize(&mut val) {
151 Ok(v) => Some(v),
152 Err(mut err) => {
153 self.errors.append(&mut err.errors);
154 None
155 }
156 }
157 }
158
159 pub fn finalize(mut self, original: Option<&mut Value<'de>>) -> Result<(), DeserError> {
171 if let Some(original) = original {
172 original.set(ValueInner::Table(self.table));
173 } else if !self.table.is_empty() {
174 let keys = self
175 .table
176 .into_keys()
177 .map(|key| (key.name.into(), key.span))
178 .collect();
179
180 self.errors.push(
181 (
182 ErrorKind::UnexpectedKeys {
183 keys,
184 expected: self.expected.into_iter().map(String::from).collect(),
185 },
186 self.span,
187 )
188 .into(),
189 );
190 }
191
192 if self.errors.is_empty() {
193 Ok(())
194 } else {
195 Err(DeserError {
196 errors: self.errors,
197 })
198 }
199 }
200}
201
202impl<'de> Deserialize<'de> for String {
203 fn deserialize(value: &mut Value<'de>) -> Result<Self, DeserError> {
204 value
205 .take_string(None)
206 .map(|s| s.into())
207 .map_err(DeserError::from)
208 }
209}
210
211impl<'de> Deserialize<'de> for std::borrow::Cow<'de, str> {
212 fn deserialize(value: &mut Value<'de>) -> Result<Self, DeserError> {
213 value.take_string(None).map_err(DeserError::from)
214 }
215}
216
217impl<'de> Deserialize<'de> for bool {
218 fn deserialize(value: &mut Value<'de>) -> Result<Self, DeserError> {
219 match value.take() {
220 ValueInner::Boolean(b) => Ok(b),
221 other => Err(expected("a bool", other, value.span).into()),
222 }
223 }
224}
225
226macro_rules! integer {
227 ($num:ty) => {
228 impl<'de> Deserialize<'de> for $num {
229 fn deserialize(value: &mut Value<'de>) -> Result<Self, DeserError> {
230 match value.take() {
231 ValueInner::Integer(i) => {
232 let i = i.try_into().map_err(|_| {
233 DeserError::from(Error {
234 kind: ErrorKind::OutOfRange(stringify!($num)),
235 span: value.span,
236 line_info: None,
237 })
238 })?;
239
240 Ok(i)
241 }
242 other => Err(expected(stringify!($num), other, value.span).into()),
243 }
244 }
245 }
246 };
247}
248
249integer!(u8);
250integer!(u16);
251integer!(u32);
252integer!(u64);
253integer!(i8);
254integer!(i16);
255integer!(i32);
256integer!(i64);
257integer!(usize);
258integer!(isize);
259
260impl<'de> Deserialize<'de> for f32 {
261 fn deserialize(value: &mut Value<'de>) -> Result<Self, DeserError> {
262 match value.take() {
263 ValueInner::Float(f) => Ok(f as f32),
264 other => Err(expected("a float", other, value.span).into()),
265 }
266 }
267}
268
269impl<'de> Deserialize<'de> for f64 {
270 fn deserialize(value: &mut Value<'de>) -> Result<Self, DeserError> {
271 match value.take() {
272 ValueInner::Float(f) => Ok(f),
273 other => Err(expected("a float", other, value.span).into()),
274 }
275 }
276}
277
278impl<'de, T> Deserialize<'de> for Vec<T>
279where
280 T: Deserialize<'de>,
281{
282 fn deserialize(value: &mut value::Value<'de>) -> Result<Self, DeserError> {
283 match value.take() {
284 ValueInner::Array(arr) => {
285 let mut errors = Vec::new();
286 let mut s = Vec::new();
287 for mut v in arr {
288 match T::deserialize(&mut v) {
289 Ok(v) => s.push(v),
290 Err(mut err) => errors.append(&mut err.errors),
291 }
292 }
293
294 if errors.is_empty() {
295 Ok(s)
296 } else {
297 Err(DeserError { errors })
298 }
299 }
300 other => Err(expected("an array", other, value.span).into()),
301 }
302 }
303}