1use std::borrow::Cow;
2
3use crate::{
4 DeXml, DeXmlError,
5 de::{AppendPath, Reader},
6};
7
8macro_rules! num {
9 ($ty: ty, $label: literal) => {
10 impl<'de> DeXml<'de> for $ty {
11 fn dexml_reader(reader: &mut Reader<'de>) -> Result<Self, DeXmlError> {
12 reader.append_path(AppendPath::Custom($label));
13 let text = reader.text()?;
14 let value = text
15 .parse::<$ty>()
16 .map_err(|err| reader.err(Cow::Owned(err.to_string())))?;
17 reader.exit_path();
18 Ok(value)
19 }
20 }
21 };
22}
23
24num!(i8, "i8");
25num!(i16, "i16");
26num!(i32, "i32");
27num!(i64, "i64");
28num!(isize, "isize");
29
30num!(u8, "u8");
31num!(u16, "u16");
32num!(u32, "u32");
33num!(u64, "u64");
34num!(usize, "usize");
35
36num!(f32, "f32");
37num!(f64, "f64");
38
39impl<'de> DeXml<'de> for &'de str {
40 fn dexml_reader(reader: &mut Reader<'de>) -> Result<Self, DeXmlError> {
41 reader.append_path(AppendPath::Text);
42 let text = reader.text()?;
43 reader.exit_path();
44 Ok(text.trim())
45 }
46}
47
48impl<'de> DeXml<'de> for bool {
49 fn dexml_reader(reader: &mut Reader<'de>) -> Result<Self, DeXmlError> {
50 reader.append_path(AppendPath::Custom("bool"));
51 let text = reader.text()?.trim();
52 let res = if text.eq_ignore_ascii_case("true") || text == "1" {
53 true
54 } else if text.eq_ignore_ascii_case("false") || text == "0" {
55 false
56 } else {
57 return Err(reader.err(Cow::Owned(format!(
58 "Expected Boolean Such As `true` Or `false` Saw: `{text}`"
59 ))));
60 };
61 reader.exit_path();
62 Ok(res)
63 }
64}
65
66impl<'de> DeXml<'de> for String {
67 fn dexml_reader(reader: &mut Reader<'de>) -> Result<Self, DeXmlError> {
68 <&str>::dexml_reader(reader).map(str::to_owned)
69 }
70}
71
72impl<'de> DeXml<'de> for Box<str> {
73 fn dexml_reader(reader: &mut Reader<'de>) -> Result<Self, DeXmlError> {
74 <&str>::dexml_reader(reader).map(Into::into)
75 }
76}