1use crate::{XmlDeserialize, XmlError, XmlSerialize};
2use quick_xml::events::{BytesEnd, BytesStart, BytesText, Event};
3use quick_xml::name::{Namespace, QName};
4use std::collections::HashMap;
5use std::num::{ParseFloatError, ParseIntError};
6use std::{convert::Infallible, io::BufRead};
7use thiserror::Error;
8
9pub trait ValueSerialize {
10 fn serialize(&self) -> String;
11}
12
13pub trait ValueDeserialize: Sized {
14 fn deserialize(val: &str) -> Result<Self, XmlError>;
15}
16
17#[derive(Debug, Error)]
18pub enum ParseValueError {
19 #[error(transparent)]
20 Infallible(#[from] Infallible),
21 #[error(transparent)]
22 ParseIntError(#[from] ParseIntError),
23 #[error(transparent)]
24 ParseFloatError(#[from] ParseFloatError),
25 #[error("{0}")]
26 Other(String),
27}
28
29macro_rules! impl_value_parse {
30 ($t:ty) => {
31 impl ValueSerialize for $t {
32 fn serialize(&self) -> String {
33 self.to_string()
34 }
35 }
36
37 impl ValueDeserialize for $t {
38 fn deserialize(val: &str) -> Result<Self, XmlError> {
39 val.parse()
40 .map_err(ParseValueError::from)
41 .map_err(XmlError::from)
42 }
43 }
44 };
45}
46
47impl_value_parse!(String);
48impl_value_parse!(i8);
49impl_value_parse!(u8);
50impl_value_parse!(i16);
51impl_value_parse!(u16);
52impl_value_parse!(f32);
53impl_value_parse!(i32);
54impl_value_parse!(u32);
55impl_value_parse!(f64);
56impl_value_parse!(i64);
57impl_value_parse!(u64);
58impl_value_parse!(isize);
59impl_value_parse!(usize);
60
61impl ValueSerialize for &str {
62 fn serialize(&self) -> String {
63 self.to_string()
64 }
65}
66
67impl<T: ValueDeserialize> XmlDeserialize for T {
68 fn deserialize<R: BufRead>(
69 reader: &mut quick_xml::NsReader<R>,
70 _start: &BytesStart,
71 empty: bool,
72 ) -> Result<Self, XmlError> {
73 let mut string = String::new();
74
75 if !empty {
76 let mut buf = Vec::new();
77 loop {
78 match reader.read_event_into(&mut buf)? {
79 Event::Text(bytes_text) => {
80 let text = bytes_text.unescape()?;
81 if !string.is_empty() {
82 return Err(XmlError::UnsupportedEvent("content already written"));
84 }
85 string = text.to_string();
86 }
87 Event::CData(cdata) => {
88 let text = String::from_utf8(cdata.to_vec())?;
89 if !string.is_empty() {
90 return Err(XmlError::UnsupportedEvent("content already written"));
92 }
93 string = text;
94 }
95 Event::End(_) => break,
96 Event::Eof => return Err(XmlError::Eof),
97 _ => return Err(XmlError::UnsupportedEvent("todo")),
98 };
99 }
100 }
101
102 ValueDeserialize::deserialize(&string)
103 }
104}
105
106impl<T: ValueSerialize> XmlSerialize for T {
107 fn serialize<W: std::io::Write>(
108 &self,
109 ns: Option<Namespace>,
110 tag: Option<&[u8]>,
111 namespaces: &HashMap<Namespace, &[u8]>,
112 writer: &mut quick_xml::Writer<W>,
113 ) -> std::io::Result<()> {
114 let prefix = ns
115 .map(|ns| namespaces.get(&ns))
116 .unwrap_or(None)
117 .map(|prefix| {
118 if !prefix.is_empty() {
119 [*prefix, b":"].concat()
120 } else {
121 Vec::new()
122 }
123 });
124 let has_prefix = prefix.is_some();
125 let tagname = tag.map(|tag| [&prefix.unwrap_or_default(), tag].concat());
126 let qname = tagname.as_ref().map(|tagname| QName(tagname));
127 if let Some(qname) = &qname {
128 let mut bytes_start = BytesStart::from(qname.to_owned());
129 if !has_prefix {
130 if let Some(ns) = &ns {
131 bytes_start.push_attribute((b"xmlns".as_ref(), ns.as_ref()));
132 }
133 }
134 writer.write_event(Event::Start(bytes_start))?;
135 }
136 writer.write_event(Event::Text(BytesText::new(&self.serialize())))?;
137 if let Some(qname) = &qname {
138 writer.write_event(Event::End(BytesEnd::from(qname.to_owned())))?;
139 }
140 Ok(())
141 }
142
143 #[allow(refining_impl_trait)]
144 fn attributes<'a>(&self) -> Option<Vec<quick_xml::events::attributes::Attribute<'a>>> {
145 None
146 }
147}