quick_xml/de/resolver.rs
1//! Entity resolver module
2
3use std::convert::Infallible;
4use std::error::Error;
5
6use crate::events::BytesText;
7
8/// Used to resolve unknown entities while parsing
9///
10/// # Example
11///
12/// ```
13/// # use serde::Deserialize;
14/// # use pretty_assertions::assert_eq;
15/// use regex::bytes::Regex;
16/// use std::collections::BTreeMap;
17/// use std::string::FromUtf8Error;
18/// use quick_xml::de::{Deserializer, EntityResolver};
19/// use quick_xml::events::BytesText;
20///
21/// struct DocTypeEntityResolver {
22/// re: Regex,
23/// map: BTreeMap<String, String>,
24/// }
25///
26/// impl Default for DocTypeEntityResolver {
27/// fn default() -> Self {
28/// Self {
29/// // We do not focus on true parsing in this example
30/// // You should use special libraries to parse DTD
31/// re: Regex::new(r#"<!ENTITY\s+([^ \t\r\n]+)\s+"([^"]*)"\s*>"#).unwrap(),
32/// map: BTreeMap::new(),
33/// }
34/// }
35/// }
36///
37/// impl EntityResolver for DocTypeEntityResolver {
38/// type Error = FromUtf8Error;
39///
40/// fn capture(&mut self, doctype: BytesText) -> Result<(), Self::Error> {
41/// for cap in self.re.captures_iter(&doctype) {
42/// self.map.insert(
43/// String::from_utf8(cap[1].to_vec())?,
44/// String::from_utf8(cap[2].to_vec())?,
45/// );
46/// }
47/// Ok(())
48/// }
49///
50/// fn resolve(&self, entity: &str) -> Option<&str> {
51/// self.map.get(entity).map(|s| s.as_str())
52/// }
53/// }
54///
55/// let xml_reader = br#"
56/// <!DOCTYPE dict[ <!ENTITY e1 "entity 1"> ]>
57/// <root>
58/// <entity_one>&e1;</entity_one>
59/// </root>
60/// "#.as_ref();
61///
62/// let mut de = Deserializer::with_resolver(
63/// xml_reader,
64/// DocTypeEntityResolver::default(),
65/// );
66/// let data: BTreeMap<String, String> = BTreeMap::deserialize(&mut de).unwrap();
67///
68/// assert_eq!(data.get("entity_one"), Some(&"entity 1".to_string()));
69/// ```
70pub trait EntityResolver {
71 /// The error type that represents DTD parse error
72 type Error: Error;
73
74 /// Called on contents of [`Event::DocType`] to capture declared entities.
75 /// Can be called multiple times, for each parsed `<!DOCTYPE >` declaration.
76 ///
77 /// [`Event::DocType`]: crate::events::Event::DocType
78 fn capture(&mut self, doctype: BytesText) -> Result<(), Self::Error>;
79
80 /// Called when an entity needs to be resolved.
81 ///
82 /// `None` is returned if a suitable value can not be found.
83 /// In that case an [`EscapeError::UnrecognizedSymbol`] will be returned by
84 /// a deserializer.
85 ///
86 /// [`EscapeError::UnrecognizedSymbol`]: crate::escape::EscapeError::UnrecognizedSymbol
87 fn resolve(&self, entity: &str) -> Option<&str>;
88}
89
90/// An `EntityResolver` that does nothing and always returns `None`.
91#[derive(Default, Copy, Clone)]
92pub struct NoEntityResolver;
93
94impl EntityResolver for NoEntityResolver {
95 type Error = Infallible;
96
97 fn capture(&mut self, _doctype: BytesText) -> Result<(), Self::Error> {
98 Ok(())
99 }
100
101 fn resolve(&self, _entity: &str) -> Option<&str> {
102 None
103 }
104}