xml_data/parser/
inner.rs

1use crate::{
2	parser::{
3		Element,
4		ElementParser,
5		Inner,
6		ElementState,
7	},
8	Result,
9};
10use std::borrow::Cow;
11
12/// Result of `InnerState` parse methods to signal whether they successfully parsed the input or
13/// another `InnerState` needs to take a shot.
14#[derive(Debug)]
15pub enum InnerParseResult<Input> {
16	/// Parsed successfully
17	Success,
18	/// Need something else to take the input
19	Next(Input),
20}
21
22/// State to parse multiple elements (on the same level)
23pub trait InnerState: Default {
24	/// Once fully parsed this is the resulting output type.
25	type Output: Sized;
26
27	/// Try parsing an element with the given tag
28	///
29	/// Should not fail if it doesn't recognize the tag; instead it needs to return the parser.
30	fn parse_inner_node<P: ElementParser>(&mut self, tag: &str, parser: P) -> Result<InnerParseResult<P>> {
31		let _ = tag;
32		Ok(InnerParseResult::Next(parser))
33	}
34
35	/// Try parsing inner text
36	///
37	/// Should not fail if it doesn't take text (but may fail if it does but can't parse it).
38	fn parse_inner_text<'t>(&mut self, text: Cow<'t, str>) -> Result<InnerParseResult<Cow<'t, str>>> {
39		Ok(InnerParseResult::Next(text))
40	}
41
42	/// Finish parsing.
43	fn parse_inner_finish(self) -> Result<Self::Output>;
44}
45
46/// Using `String` as `InnerState` to collect all inner text in it (including whitespace in input)
47impl InnerState for String {
48	type Output = Self;
49
50	fn parse_inner_text<'t>(&mut self, text: Cow<'t, str>) -> Result<InnerParseResult<Cow<'t, str>>> {
51		if self.is_empty() {
52			*self = text.into_owned();
53		} else {
54			*self += &text;
55		}
56		Ok(InnerParseResult::Success)
57	}
58
59	fn parse_inner_finish(self) -> Result<Self::Output> {
60		Ok(self)
61	}
62}
63
64impl Inner for String {
65	type ParseState = String;
66}
67
68impl InnerState for Cow<'_, str> {
69	type Output = Self;
70
71	fn parse_inner_text<'t>(&mut self, text: Cow<'t, str>) -> Result<InnerParseResult<Cow<'t, str>>> {
72		if self.is_empty() {
73			*self = Cow::Owned(text.into_owned());
74		} else {
75			match self {
76				Cow::Borrowed(s) => {
77					let t = String::from(*s) + &text;
78					*self = Cow::Owned(t);
79				},
80				Cow::Owned(s) => {
81					*s += &text;
82				},
83			}
84		}
85		Ok(InnerParseResult::Success)
86	}
87
88	fn parse_inner_finish(self) -> Result<Self::Output> {
89		Ok(self)
90	}
91}
92
93/// `InnerState` to parse a single element
94pub struct ParseElementOnce<E: ElementState> {
95	element: Option<E::Output>,
96}
97
98impl<E: ElementState> Default for ParseElementOnce<E> {
99	fn default() -> Self {
100		Self { element: None }
101	}
102}
103
104impl<E: ElementState> InnerState for ParseElementOnce<E> {
105	type Output = E::Output;
106
107	fn parse_inner_node<P: ElementParser>(&mut self, tag: &str, parser: P) -> Result<InnerParseResult<P>> {
108		if self.element.is_none() {
109			if let Some(mut state) = E::parse_element_start(tag) {
110				parser.parse_element_state(&mut state)?;
111				self.element = Some(state.parse_element_finish()?);
112				return Ok(InnerParseResult::Success)
113			}
114		}
115		Ok(InnerParseResult::Next(parser))
116	}
117
118	fn parse_inner_finish(self) -> Result<Self::Output> {
119		if let Some(o) = self.element {
120			Ok(o)
121		} else {
122			E::parse_error_not_found()
123		}
124	}
125}
126
127impl<E: Element> Inner for E {
128	type ParseState = ParseElementOnce<E::ParseState>;
129}
130
131/// `InnerState` to parse a single optional element
132pub struct ParseElementOptional<E: ElementState> {
133	element: Option<E::Output>,
134}
135
136impl<E: ElementState> Default for ParseElementOptional<E> {
137	fn default() -> Self {
138		Self { element: None }
139	}
140}
141
142impl<E: ElementState> InnerState for ParseElementOptional<E> {
143	type Output = Option<E::Output>;
144
145	fn parse_inner_node<P: ElementParser>(&mut self, tag: &str, parser: P) -> Result<InnerParseResult<P>> {
146		if self.element.is_none() {
147			if let Some(mut state) = E::parse_element_start(tag) {
148				parser.parse_element_state(&mut state)?;
149				self.element = Some(state.parse_element_finish()?);
150				return Ok(InnerParseResult::Success)
151			}
152		}
153		Ok(InnerParseResult::Next(parser))
154	}
155
156	fn parse_inner_finish(self) -> Result<Self::Output> {
157		Ok(self.element)
158	}
159}
160
161impl<E: Element> Inner for Option<E> {
162	type ParseState = ParseElementOptional<E::ParseState>;
163}
164
165/// `InnerState` to parse multiple occurences of a single element
166pub struct ParseElementList<E: ElementState> {
167	elements: Vec<E::Output>,
168}
169
170impl<E: ElementState> Default for ParseElementList<E> {
171	fn default() -> Self {
172		Self {
173			elements: Vec::new(),
174		}
175	}
176}
177
178impl<E: ElementState> InnerState for ParseElementList<E> {
179	type Output = Vec<E::Output>;
180
181	fn parse_inner_node<P: ElementParser>(&mut self, tag: &str, parser: P) -> Result<InnerParseResult<P>> {
182		if let Some(mut state) = E::parse_element_start(tag) {
183			parser.parse_element_state(&mut state)?;
184			self.elements.push(state.parse_element_finish()?);
185			Ok(InnerParseResult::Success)
186		} else {
187			Ok(InnerParseResult::Next(parser))
188		}
189	}
190
191	fn parse_inner_finish(self) -> Result<Self::Output> {
192		Ok(self.elements)
193	}
194}
195
196impl<E: Element> Inner for Vec<E> {
197	type ParseState = ParseElementList<E::ParseState>;
198}
199
200/// `InnerState` to parse optional inner data; if it parsed anything it needs to finish
201pub struct ParseInnerOptional<I: InnerState> {
202	inner: Option<I>,
203}
204
205impl<I: InnerState> Default for ParseInnerOptional<I> {
206	fn default() -> Self {
207		Self { inner: None }
208	}
209}
210
211impl<I: InnerState> InnerState for ParseInnerOptional<I> {
212	type Output = Option<I::Output>;
213
214	fn parse_inner_node<P: ElementParser>(&mut self, tag: &str, parser: P) -> Result<InnerParseResult<P>> {
215		if self.inner.is_none() {
216			let mut state = I::default();
217			match state.parse_inner_node(tag, parser)? {
218				InnerParseResult::Success => (),
219				InnerParseResult::Next(parser) => return Ok(InnerParseResult::Next(parser)),
220			}
221			// matched something successfully, remember state
222			self.inner = Some(state);
223			Ok(InnerParseResult::Success)
224		} else if let Some(inner) = &mut self.inner {
225			inner.parse_inner_node(tag, parser)
226		} else {
227			unreachable!()
228		}
229	}
230
231	fn parse_inner_text<'t>(&mut self, text: Cow<'t, str>) -> Result<InnerParseResult<Cow<'t, str>>> {
232		if self.inner.is_none() {
233			let mut state = I::default();
234			match state.parse_inner_text(text)? {
235				InnerParseResult::Success => (),
236				InnerParseResult::Next(text) => return Ok(InnerParseResult::Next(text)),
237			}
238			// matched something successfully, remember state
239			self.inner = Some(state);
240			Ok(InnerParseResult::Success)
241		} else if let Some(inner) = &mut self.inner {
242			inner.parse_inner_text(text)
243		} else {
244			unreachable!()
245		}
246	}
247
248	fn parse_inner_finish(self) -> Result<Self::Output> {
249		Ok(if let Some(inner) = self.inner {
250			Some(inner.parse_inner_finish()?)
251		} else {
252			None
253		})
254	}
255}