diff --git a/examples/read_nodes_serde.rs b/examples/read_nodes_serde.rs index 3c111168..34c6329e 100644 --- a/examples/read_nodes_serde.rs +++ b/examples/read_nodes_serde.rs @@ -2,7 +2,7 @@ // run example with: // cargo run --example read_nodes_serde --features="serialize" -use quick_xml::de::from_str; +use quick_xml::de::{from_str, Trimmer}; use serde::Deserialize; #[derive(Debug, PartialEq, Default, Deserialize)] @@ -66,12 +66,12 @@ const ONE_TRANSLATION_XML: &str = r#" "#; fn main() -> Result<(), quick_xml::DeError> { - let t: Translation = from_str(ONE_TRANSLATION_XML)?; + let t: Translation = from_str(ONE_TRANSLATION_XML, Trimmer::default())?; assert_eq!(t.tag, "HELLO"); assert_eq!(t.lang, "ja"); assert_eq!(t.text, "こんにちは"); - let config: Config = from_str(XML)?; + let config: Config = from_str(XML, Trimmer::default())?; dbg!("{:?}", &config); assert_eq!(config.settings.language, "es"); diff --git a/src/de/mod.rs b/src/de/mod.rs index b9ca4ae0..94fab20d 100644 --- a/src/de/mod.rs +++ b/src/de/mod.rs @@ -1926,6 +1926,8 @@ impl<'a> PayloadEvent<'a> { struct XmlReader<'i, R: XmlRead<'i>> { /// A source of low-level XML events reader: R, + /// A config for trimming options + trimmer: Trimmer, /// Intermediate event, that could be returned by the next call to `next()`. /// If that is the `Text` event then leading spaces already trimmed, but /// trailing spaces is not. Before the event will be returned, trimming of @@ -1934,12 +1936,16 @@ struct XmlReader<'i, R: XmlRead<'i>> { } impl<'i, R: XmlRead<'i>> XmlReader<'i, R> { - fn new(mut reader: R) -> Self { + fn new(mut reader: R, trimmer: Trimmer) -> Self { // Lookahead by one event immediately, so we do not need to check in the // loop if we need lookahead or not let lookahead = reader.next(); - Self { reader, lookahead } + Self { + reader, + lookahead, + trimmer, + } } /// Read next event and put it in lookahead, return the current lookahead @@ -1951,10 +1957,11 @@ impl<'i, R: XmlRead<'i>> XmlReader<'i, R> { #[inline(always)] fn need_trim_end(&self) -> bool { // If next event is a text or CDATA, we should not trim trailing spaces - !matches!( - self.lookahead, - Ok(PayloadEvent::Text(_)) | Ok(PayloadEvent::CData(_)) - ) + self.trimmer.trim_end + && !matches!( + self.lookahead, + Ok(PayloadEvent::Text(_)) | Ok(PayloadEvent::CData(_)) + ) } /// Read all consequent [`Text`] and [`CData`] events until non-text event @@ -1992,6 +1999,7 @@ impl<'i, R: XmlRead<'i>> XmlReader<'i, R> { fn next_text(&mut self) -> Result, DeError> { match self.next_impl()? { PayloadEvent::Text(mut e) => { + println!("Here: {:?}", e); if self.need_trim_end() { e.inplace_trim_end(); } @@ -2011,6 +2019,7 @@ impl<'i, R: XmlRead<'i>> XmlReader<'i, R> { PayloadEvent::Start(e) => Ok(DeEvent::Start(e)), PayloadEvent::End(e) => Ok(DeEvent::End(e)), PayloadEvent::Text(mut e) => { + println!("This: {:?}", e); if self.need_trim_end() && e.inplace_trim_end() { continue; } @@ -2103,11 +2112,12 @@ where } /// Deserialize an instance of type `T` from a string of XML text. -pub fn from_str<'de, T>(s: &'de str) -> Result +/// Specifying trimming options with `[Trimmer]` +pub fn from_str<'de, T>(s: &'de str, trimmer: Trimmer) -> Result where T: Deserialize<'de>, { - let mut de = Deserializer::from_str(s); + let mut de = Deserializer::from_str(s, trimmer); T::deserialize(&mut de) } @@ -2176,9 +2186,9 @@ where /// /// - [`Deserializer::from_str`] /// - [`Deserializer::from_reader`] - fn new(reader: R) -> Self { + fn new(reader: R, trimmer: Trimmer) -> Self { Self { - reader: XmlReader::new(reader), + reader: XmlReader::new(reader, trimmer), #[cfg(feature = "overlapped-lists")] read: VecDeque::new(), @@ -2502,13 +2512,17 @@ where impl<'de> Deserializer<'de, SliceReader<'de>> { /// Create new deserializer that will borrow data from the specified string #[allow(clippy::should_implement_trait)] - pub fn from_str(s: &'de str) -> Self { + pub fn from_str(s: &'de str, trimmer: Trimmer) -> Self { let mut reader = Reader::from_str(s); reader.expand_empty_elements(true).check_end_names(true); - Self::new(SliceReader { - reader, - start_trimmer: StartTrimmer::default(), - }) + // TODO ARTHUR + Self::new( + SliceReader { + reader, + trimmer: trimmer.clone(), + }, + trimmer, + ) } } @@ -2524,11 +2538,15 @@ where let mut reader = Reader::from_reader(reader); reader.expand_empty_elements(true).check_end_names(true); - Self::new(IoReader { - reader, - start_trimmer: StartTrimmer::default(), - buf: Vec::new(), - }) + // TODO ARTHUR + Self::new( + IoReader { + reader, + trimmer: Trimmer::default(), + buf: Vec::new(), + }, + Trimmer::default(), + ) } } @@ -2694,15 +2712,24 @@ where /// Helper struct that contains a state for an algorithm of converting events /// from raw events to semi-trimmed events that is independent from a way of /// events reading. -struct StartTrimmer { +#[derive(Clone)] +pub struct Trimmer { /// If `true`, then leading whitespace will be removed from next returned /// [`Event::Text`]. This field is set to `true` after reading each event /// except [`Event::Text`] and [`Event::CData`], so [`Event::Text`] events /// read right after them does not trimmed. trim_start: bool, + /// If `true`, then trailing whitespace in [`Event::Text`] will be removed + trim_end: bool, } -impl StartTrimmer { +impl Trimmer { + fn new(end_option: bool) -> Self { + Self { + trim_start: true, + trim_end: end_option, + } + } /// Converts raw reader's event into a payload event. /// Returns `None`, if event should be skipped. #[inline(always)] @@ -2729,10 +2756,13 @@ impl StartTrimmer { } } -impl Default for StartTrimmer { +impl Default for Trimmer { #[inline] fn default() -> Self { - Self { trim_start: true } + Self { + trim_start: true, + trim_end: true, + } } } @@ -2762,7 +2792,7 @@ pub trait XmlRead<'i> { /// [`Deserializer::from_reader`] pub struct IoReader { reader: Reader, - start_trimmer: StartTrimmer, + trimmer: Trimmer, buf: Vec, } @@ -2772,7 +2802,7 @@ impl<'i, R: BufRead> XmlRead<'i> for IoReader { self.buf.clear(); let event = self.reader.read_event_into(&mut self.buf)?; - if let Some(event) = self.start_trimmer.trim(event) { + if let Some(event) = self.trimmer.trim(event) { return Ok(event.into_owned()); } } @@ -2797,14 +2827,14 @@ impl<'i, R: BufRead> XmlRead<'i> for IoReader { /// [`Deserializer::from_str`]. pub struct SliceReader<'de> { reader: Reader<&'de [u8]>, - start_trimmer: StartTrimmer, + trimmer: Trimmer, } impl<'de> XmlRead<'de> for SliceReader<'de> { fn next(&mut self) -> Result, DeError> { loop { let event = self.reader.read_event()?; - if let Some(event) = self.start_trimmer.trim(event) { + if let Some(event) = self.trimmer.trim(event) { return Ok(event); } } @@ -2849,6 +2879,7 @@ mod tests { "#, + Trimmer::default(), ); // Initial conditions - both are empty @@ -2981,6 +3012,7 @@ mod tests { "#, + Trimmer::default(), ); // Initial conditions - both are empty @@ -3075,6 +3107,7 @@ mod tests { "#, + Trimmer::default(), ); // Initial conditions - both are empty @@ -3280,6 +3313,7 @@ mod tests { "#, + Trimmer::default(), ); de.event_buffer_size(NonZeroUsize::new(3)); @@ -3294,7 +3328,7 @@ mod tests { fn invalid_xml() { use crate::de::DeEvent::*; - let mut de = Deserializer::from_str(""); + let mut de = Deserializer::from_str("", Trimmer::default()); // Cache all events let checkpoint = de.skip_checkpoint(); @@ -3319,6 +3353,7 @@ mod tests { "#, + Trimmer::default(), ); assert_eq!(de.next().unwrap(), Start(BytesStart::new("root"))); @@ -3345,7 +3380,7 @@ mod tests { #[test] fn invalid_xml1() { - let mut de = Deserializer::from_str(""); + let mut de = Deserializer::from_str("", Trimmer::default()); assert_eq!(de.next().unwrap(), Start(BytesStart::new("tag"))); assert_eq!(de.peek().unwrap(), &Start(BytesStart::new("tag"))); @@ -3359,7 +3394,7 @@ mod tests { #[test] fn invalid_xml2() { - let mut de = Deserializer::from_str(""); + let mut de = Deserializer::from_str("", Trimmer::default()); assert_eq!(de.next().unwrap(), Start(BytesStart::new("tag"))); assert_eq!(de.peek().unwrap(), &Text(Cow::Borrowed(""))); @@ -3380,14 +3415,15 @@ mod tests { "#; + // TODO ARTHUR let mut reader1 = IoReader { reader: Reader::from_reader(s.as_bytes()), - start_trimmer: StartTrimmer::default(), + trimmer: Trimmer::default(), buf: Vec::new(), }; let mut reader2 = SliceReader { reader: Reader::from_str(s), - start_trimmer: StartTrimmer::default(), + trimmer: Trimmer::default(), }; loop { @@ -3411,9 +3447,10 @@ mod tests { "#; + // TODO ARTHUR let mut reader = SliceReader { reader: Reader::from_str(s), - start_trimmer: StartTrimmer::default(), + trimmer: Trimmer::default(), }; reader @@ -3456,7 +3493,7 @@ mod tests { /// because parser reports error early #[test] fn read_string() { - match from_str::(r#""#) { + match from_str::(r#""#, Trimmer::default()) { Err(DeError::InvalidXml(Error::EndEventMismatch { expected, found })) => { assert_eq!(expected, ""); assert_eq!(found, "root"); @@ -3467,10 +3504,10 @@ mod tests { ), } - let s: String = from_str(r#""#).unwrap(); + let s: String = from_str(r#""#, Trimmer::default()).unwrap(); assert_eq!(s, ""); - match from_str::(r#""#) { + match from_str::(r#""#, Trimmer::default()) { Err(DeError::InvalidXml(Error::EndEventMismatch { expected, found })) => { assert_eq!(expected, "root"); assert_eq!(found, "other"); @@ -3492,19 +3529,19 @@ mod tests { #[test] fn text() { - let mut de = Deserializer::from_str("text"); + let mut de = Deserializer::from_str("text", Trimmer::default()); assert_eq!(de.next().unwrap(), DeEvent::Text(Cow::Borrowed("text"))); } #[test] fn cdata() { - let mut de = Deserializer::from_str(""); + let mut de = Deserializer::from_str("", Trimmer::default()); assert_eq!(de.next().unwrap(), DeEvent::Text(Cow::Borrowed("cdata"))); } #[test] fn text_and_cdata() { - let mut de = Deserializer::from_str("text and "); + let mut de = Deserializer::from_str("text and ", Trimmer::default()); assert_eq!( de.next().unwrap(), DeEvent::Text(Cow::Borrowed("text and cdata")) @@ -3513,7 +3550,7 @@ mod tests { #[test] fn text_and_empty_cdata() { - let mut de = Deserializer::from_str("text and "); + let mut de = Deserializer::from_str("text and ", Trimmer::default()); assert_eq!( de.next().unwrap(), DeEvent::Text(Cow::Borrowed("text and ")) @@ -3522,7 +3559,7 @@ mod tests { #[test] fn cdata_and_text() { - let mut de = Deserializer::from_str(" and text"); + let mut de = Deserializer::from_str(" and text", Trimmer::default()); assert_eq!( de.next().unwrap(), DeEvent::Text(Cow::Borrowed("cdata and text")) @@ -3531,7 +3568,7 @@ mod tests { #[test] fn empty_cdata_and_text() { - let mut de = Deserializer::from_str(" and text"); + let mut de = Deserializer::from_str(" and text", Trimmer::default()); assert_eq!( de.next().unwrap(), DeEvent::Text(Cow::Borrowed(" and text")) @@ -3545,6 +3582,7 @@ mod tests { \ cdata]]>\ ", + Trimmer::default(), ); assert_eq!( de.next().unwrap(), @@ -3558,13 +3596,13 @@ mod tests { #[test] fn text() { - let mut de = Deserializer::from_str( - "\ + let xml = "\ text \ \ text\ - ", - ); + "; + println!("{}", xml); + let mut de = Deserializer::from_str(xml, Trimmer::default()); assert_eq!( de.next().unwrap(), DeEvent::Text(Cow::Borrowed("text text")) @@ -3579,6 +3617,7 @@ mod tests { \ cdata]]>\ ", + Trimmer::default(), ); assert_eq!( de.next().unwrap(), @@ -3594,6 +3633,7 @@ mod tests { \ \ ", + Trimmer::default(), ); assert_eq!( de.next().unwrap(), @@ -3609,6 +3649,7 @@ mod tests { \ \ ", + Trimmer::default(), ); assert_eq!(de.next().unwrap(), DeEvent::Text(Cow::Borrowed("text "))); } @@ -3621,6 +3662,7 @@ mod tests { \ text \ ", + Trimmer::default(), ); assert_eq!( de.next().unwrap(), @@ -3636,6 +3678,7 @@ mod tests { \ text \ ", + Trimmer::default(), ); assert_eq!(de.next().unwrap(), DeEvent::Text(Cow::Borrowed(" text"))); } @@ -3648,6 +3691,7 @@ mod tests { \ cdata]]>\ ", + Trimmer::default(), ); assert_eq!( de.next().unwrap(), @@ -3668,6 +3712,7 @@ mod tests { \ text\ ", + Trimmer::default(), ); assert_eq!( de.next().unwrap(), @@ -3683,6 +3728,7 @@ mod tests { \ cdata]]>\ ", + Trimmer::default(), ); assert_eq!( de.next().unwrap(), @@ -3698,6 +3744,7 @@ mod tests { \ \ ", + Trimmer::default(), ); assert_eq!( de.next().unwrap(), @@ -3713,6 +3760,7 @@ mod tests { \ \ ", + Trimmer::default(), ); assert_eq!(de.next().unwrap(), DeEvent::Text(Cow::Borrowed("text "))); } @@ -3725,6 +3773,7 @@ mod tests { \ text \ ", + Trimmer::default(), ); assert_eq!( de.next().unwrap(), @@ -3740,6 +3789,7 @@ mod tests { \ text \ ", + Trimmer::default(), ); assert_eq!(de.next().unwrap(), DeEvent::Text(Cow::Borrowed(" text"))); } @@ -3752,6 +3802,7 @@ mod tests { \ cdata]]>\ ", + Trimmer::default(), ); assert_eq!( de.next().unwrap(), @@ -3779,7 +3830,7 @@ mod tests { #[test] fn start() { - let mut de = Deserializer::from_str(""); + let mut de = Deserializer::from_str("", Trimmer::default()); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag1"))); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag2"))); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag3"))); @@ -3789,7 +3840,7 @@ mod tests { /// Not matching end tag will result to error #[test] fn end() { - let mut de = Deserializer::from_str(""); + let mut de = Deserializer::from_str("", Trimmer::default()); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag1"))); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag2"))); assert_eq!(de.next().unwrap(), DeEvent::End(BytesEnd::new("tag2"))); @@ -3798,7 +3849,7 @@ mod tests { #[test] fn text() { - let mut de = Deserializer::from_str(" text "); + let mut de = Deserializer::from_str(" text ", Trimmer::default()); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag1"))); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag2"))); // Text is trimmed from both sides @@ -3808,7 +3859,10 @@ mod tests { #[test] fn cdata() { - let mut de = Deserializer::from_str(""); + let mut de = Deserializer::from_str( + "", + Trimmer::default(), + ); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag1"))); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag2"))); assert_eq!(de.next().unwrap(), DeEvent::Text(Cow::Borrowed(" cdata "))); @@ -3817,7 +3871,7 @@ mod tests { #[test] fn eof() { - let mut de = Deserializer::from_str(""); + let mut de = Deserializer::from_str("", Trimmer::default()); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag1"))); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag2"))); assert_eq!(de.next().unwrap(), DeEvent::Eof); @@ -3832,7 +3886,7 @@ mod tests { #[test] fn start() { - let mut de = Deserializer::from_str(""); + let mut de = Deserializer::from_str("", Trimmer::default()); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag"))); assert_eq!(de.next().unwrap(), DeEvent::End(BytesEnd::new("tag"))); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag2"))); @@ -3841,7 +3895,7 @@ mod tests { #[test] fn end() { - let mut de = Deserializer::from_str(""); + let mut de = Deserializer::from_str("", Trimmer::default()); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag"))); assert_eq!(de.next().unwrap(), DeEvent::End(BytesEnd::new("tag"))); match de.next() { @@ -3856,7 +3910,7 @@ mod tests { #[test] fn text() { - let mut de = Deserializer::from_str(" text "); + let mut de = Deserializer::from_str(" text ", Trimmer::default()); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag"))); assert_eq!(de.next().unwrap(), DeEvent::End(BytesEnd::new("tag"))); // Text is trimmed from both sides @@ -3866,7 +3920,10 @@ mod tests { #[test] fn cdata() { - let mut de = Deserializer::from_str(""); + let mut de = Deserializer::from_str( + "", + Trimmer::default(), + ); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag"))); assert_eq!(de.next().unwrap(), DeEvent::End(BytesEnd::new("tag"))); assert_eq!(de.next().unwrap(), DeEvent::Text(Cow::Borrowed(" cdata "))); @@ -3875,7 +3932,7 @@ mod tests { #[test] fn eof() { - let mut de = Deserializer::from_str(""); + let mut de = Deserializer::from_str("", Trimmer::default()); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag"))); assert_eq!(de.next().unwrap(), DeEvent::End(BytesEnd::new("tag"))); assert_eq!(de.next().unwrap(), DeEvent::Eof); @@ -3890,7 +3947,7 @@ mod tests { #[test] fn start() { - let mut de = Deserializer::from_str(" text "); + let mut de = Deserializer::from_str(" text ", Trimmer::default()); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag"))); // Text is trimmed from both sides assert_eq!(de.next().unwrap(), DeEvent::Text(Cow::Borrowed("text"))); @@ -3900,7 +3957,7 @@ mod tests { #[test] fn end() { - let mut de = Deserializer::from_str(" text "); + let mut de = Deserializer::from_str(" text ", Trimmer::default()); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag"))); // Text is trimmed from both sides assert_eq!(de.next().unwrap(), DeEvent::Text(Cow::Borrowed("text"))); @@ -3912,7 +3969,10 @@ mod tests { #[test] fn cdata() { - let mut de = Deserializer::from_str(" text "); + let mut de = Deserializer::from_str( + " text ", + Trimmer::default(), + ); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag"))); // Text is trimmed from the start assert_eq!( @@ -3924,7 +3984,7 @@ mod tests { #[test] fn eof() { - let mut de = Deserializer::from_str(" text "); + let mut de = Deserializer::from_str(" text ", Trimmer::default()); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag"))); // Text is trimmed from both sides assert_eq!(de.next().unwrap(), DeEvent::Text(Cow::Borrowed("text"))); @@ -3940,7 +4000,10 @@ mod tests { #[test] fn start() { - let mut de = Deserializer::from_str(""); + let mut de = Deserializer::from_str( + "", + Trimmer::default(), + ); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag"))); assert_eq!(de.next().unwrap(), DeEvent::Text(Cow::Borrowed(" cdata "))); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag2"))); @@ -3949,7 +4012,10 @@ mod tests { #[test] fn end() { - let mut de = Deserializer::from_str(""); + let mut de = Deserializer::from_str( + "", + Trimmer::default(), + ); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag"))); assert_eq!(de.next().unwrap(), DeEvent::Text(Cow::Borrowed(" cdata "))); assert_eq!(de.next().unwrap(), DeEvent::End(BytesEnd::new("tag"))); @@ -3958,7 +4024,10 @@ mod tests { #[test] fn text() { - let mut de = Deserializer::from_str(" text "); + let mut de = Deserializer::from_str( + " text ", + Trimmer::default(), + ); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag"))); // Text is trimmed from the end assert_eq!( @@ -3970,8 +4039,10 @@ mod tests { #[test] fn cdata() { - let mut de = - Deserializer::from_str(""); + let mut de = Deserializer::from_str( + "", + Trimmer::default(), + ); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag"))); assert_eq!( de.next().unwrap(), @@ -3982,7 +4053,8 @@ mod tests { #[test] fn eof() { - let mut de = Deserializer::from_str(""); + let mut de = + Deserializer::from_str("", Trimmer::default()); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag"))); assert_eq!(de.next().unwrap(), DeEvent::Text(Cow::Borrowed(" cdata "))); assert_eq!(de.next().unwrap(), DeEvent::Eof); @@ -3994,7 +4066,7 @@ mod tests { /// Start from End event will always generate an error #[test] fn end() { - let mut de = Deserializer::from_str(""); + let mut de = Deserializer::from_str("", Trimmer::default()); match de.next() { Err(DeError::InvalidXml(Error::EndEventMismatch { expected, found })) => { assert_eq!(expected, ""); @@ -4015,7 +4087,7 @@ mod tests { #[test] fn start() { - let mut de = Deserializer::from_str(" text "); + let mut de = Deserializer::from_str(" text ", Trimmer::default()); // Text is trimmed from both sides assert_eq!(de.next().unwrap(), DeEvent::Text(Cow::Borrowed("text"))); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag1"))); @@ -4026,7 +4098,7 @@ mod tests { /// Not matching end tag will result in error #[test] fn end() { - let mut de = Deserializer::from_str(" text "); + let mut de = Deserializer::from_str(" text ", Trimmer::default()); // Text is trimmed from both sides assert_eq!(de.next().unwrap(), DeEvent::Text(Cow::Borrowed("text"))); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag"))); @@ -4036,7 +4108,7 @@ mod tests { #[test] fn text() { - let mut de = Deserializer::from_str(" text text2 "); + let mut de = Deserializer::from_str(" text text2 ", Trimmer::default()); // Text is trimmed from both sides assert_eq!(de.next().unwrap(), DeEvent::Text(Cow::Borrowed("text"))); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag"))); @@ -4047,7 +4119,10 @@ mod tests { #[test] fn cdata() { - let mut de = Deserializer::from_str(" text "); + let mut de = Deserializer::from_str( + " text ", + Trimmer::default(), + ); // Text is trimmed from both sides assert_eq!(de.next().unwrap(), DeEvent::Text(Cow::Borrowed("text"))); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag"))); @@ -4058,7 +4133,7 @@ mod tests { #[test] fn eof() { // Text is trimmed from both sides - let mut de = Deserializer::from_str(" text "); + let mut de = Deserializer::from_str(" text ", Trimmer::default()); assert_eq!(de.next().unwrap(), DeEvent::Text(Cow::Borrowed("text"))); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag"))); assert_eq!(de.next().unwrap(), DeEvent::Eof); @@ -4069,7 +4144,7 @@ mod tests { /// End event without corresponding start event will always generate an error #[test] fn end() { - let mut de = Deserializer::from_str(" text "); + let mut de = Deserializer::from_str(" text ", Trimmer::default()); // Text is trimmed from both sides assert_eq!(de.next().unwrap(), DeEvent::Text(Cow::Borrowed("text"))); match de.next() { @@ -4090,7 +4165,10 @@ mod tests { #[test] fn start() { - let mut de = Deserializer::from_str(" text "); + let mut de = Deserializer::from_str( + " text ", + Trimmer::default(), + ); // Text is trimmed from the start assert_eq!( de.next().unwrap(), @@ -4102,7 +4180,10 @@ mod tests { #[test] fn end() { - let mut de = Deserializer::from_str(" text "); + let mut de = Deserializer::from_str( + " text ", + Trimmer::default(), + ); // Text is trimmed from the start assert_eq!( de.next().unwrap(), @@ -4120,7 +4201,10 @@ mod tests { #[test] fn text() { - let mut de = Deserializer::from_str(" text text2 "); + let mut de = Deserializer::from_str( + " text text2 ", + Trimmer::default(), + ); // Text is trimmed from the start and from the end assert_eq!( de.next().unwrap(), @@ -4131,8 +4215,10 @@ mod tests { #[test] fn cdata() { - let mut de = - Deserializer::from_str(" text "); + let mut de = Deserializer::from_str( + " text ", + Trimmer::default(), + ); // Text is trimmed from the start assert_eq!( de.next().unwrap(), @@ -4143,7 +4229,8 @@ mod tests { #[test] fn eof() { - let mut de = Deserializer::from_str(" text "); + let mut de = + Deserializer::from_str(" text ", Trimmer::default()); // Text is trimmed from the start assert_eq!( de.next().unwrap(), @@ -4165,7 +4252,10 @@ mod tests { #[test] fn start() { - let mut de = Deserializer::from_str(""); + let mut de = Deserializer::from_str( + "", + Trimmer::default(), + ); assert_eq!(de.next().unwrap(), DeEvent::Text(Cow::Borrowed(" cdata "))); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag1"))); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag2"))); @@ -4175,7 +4265,10 @@ mod tests { /// Not matching end tag will result in error #[test] fn end() { - let mut de = Deserializer::from_str(""); + let mut de = Deserializer::from_str( + "", + Trimmer::default(), + ); assert_eq!(de.next().unwrap(), DeEvent::Text(Cow::Borrowed(" cdata "))); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag"))); assert_eq!(de.next().unwrap(), DeEvent::End(BytesEnd::new("tag"))); @@ -4184,7 +4277,10 @@ mod tests { #[test] fn text() { - let mut de = Deserializer::from_str(" text "); + let mut de = Deserializer::from_str( + " text ", + Trimmer::default(), + ); assert_eq!(de.next().unwrap(), DeEvent::Text(Cow::Borrowed(" cdata "))); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag"))); // Text is trimmed from both sides @@ -4194,8 +4290,10 @@ mod tests { #[test] fn cdata() { - let mut de = - Deserializer::from_str(""); + let mut de = Deserializer::from_str( + "", + Trimmer::default(), + ); assert_eq!(de.next().unwrap(), DeEvent::Text(Cow::Borrowed(" cdata "))); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag"))); assert_eq!(de.next().unwrap(), DeEvent::Text(Cow::Borrowed(" cdata2 "))); @@ -4204,7 +4302,8 @@ mod tests { #[test] fn eof() { - let mut de = Deserializer::from_str(""); + let mut de = + Deserializer::from_str("", Trimmer::default()); assert_eq!(de.next().unwrap(), DeEvent::Text(Cow::Borrowed(" cdata "))); assert_eq!(de.next().unwrap(), DeEvent::Start(BytesStart::new("tag"))); assert_eq!(de.next().unwrap(), DeEvent::Eof); @@ -4215,7 +4314,8 @@ mod tests { /// End event without corresponding start event will always generate an error #[test] fn end() { - let mut de = Deserializer::from_str(""); + let mut de = + Deserializer::from_str("", Trimmer::default()); assert_eq!(de.next().unwrap(), DeEvent::Text(Cow::Borrowed(" cdata "))); match de.next() { Err(DeError::InvalidXml(Error::EndEventMismatch { expected, found })) => { @@ -4233,7 +4333,10 @@ mod tests { #[test] fn start() { - let mut de = Deserializer::from_str(" text "); + let mut de = Deserializer::from_str( + " text ", + Trimmer::default(), + ); // Text is trimmed from the end assert_eq!( de.next().unwrap(), @@ -4245,7 +4348,10 @@ mod tests { #[test] fn end() { - let mut de = Deserializer::from_str(" text "); + let mut de = Deserializer::from_str( + " text ", + Trimmer::default(), + ); // Text is trimmed from the end assert_eq!( de.next().unwrap(), @@ -4265,8 +4371,10 @@ mod tests { #[test] fn cdata() { - let mut de = - Deserializer::from_str(" text "); + let mut de = Deserializer::from_str( + " text ", + Trimmer::default(), + ); assert_eq!( de.next().unwrap(), DeEvent::Text(Cow::Borrowed(" cdata text cdata2 ")) @@ -4276,7 +4384,8 @@ mod tests { #[test] fn eof() { - let mut de = Deserializer::from_str(" text "); + let mut de = + Deserializer::from_str(" text ", Trimmer::default()); // Text is trimmed from the end assert_eq!( de.next().unwrap(), @@ -4293,8 +4402,10 @@ mod tests { #[test] fn start() { - let mut de = - Deserializer::from_str(""); + let mut de = Deserializer::from_str( + "", + Trimmer::default(), + ); assert_eq!( de.next().unwrap(), DeEvent::Text(Cow::Borrowed(" cdata cdata2 ")) @@ -4305,8 +4416,10 @@ mod tests { #[test] fn end() { - let mut de = - Deserializer::from_str(""); + let mut de = Deserializer::from_str( + "", + Trimmer::default(), + ); assert_eq!( de.next().unwrap(), DeEvent::Text(Cow::Borrowed(" cdata cdata2 ")) @@ -4323,8 +4436,10 @@ mod tests { #[test] fn text() { - let mut de = - Deserializer::from_str(" text "); + let mut de = Deserializer::from_str( + " text ", + Trimmer::default(), + ); // Text is trimmed from the end assert_eq!( de.next().unwrap(), @@ -4337,6 +4452,7 @@ mod tests { fn cdata() { let mut de = Deserializer::from_str( "", + Trimmer::default(), ); assert_eq!( de.next().unwrap(), @@ -4347,7 +4463,10 @@ mod tests { #[test] fn eof() { - let mut de = Deserializer::from_str(""); + let mut de = Deserializer::from_str( + "", + Trimmer::default(), + ); assert_eq!( de.next().unwrap(), DeEvent::Text(Cow::Borrowed(" cdata cdata2 ")) @@ -4358,4 +4477,14 @@ mod tests { } } } + + #[test] + fn trimmer_options() { + let mut de = Deserializer::from_str(" text text text text ", Trimmer::new(false)); + assert_eq!( + de.next().unwrap(), + DeEvent::Text(Cow::Borrowed("text text text text ")) + ); + assert_eq!(de.next().unwrap(), DeEvent::Eof); + } } diff --git a/tests/serde-de.rs b/tests/serde-de.rs index fa926941..5a3f4664 100644 --- a/tests/serde-de.rs +++ b/tests/serde-de.rs @@ -1,4 +1,4 @@ -use quick_xml::de::Deserializer; +use quick_xml::de::{Deserializer, Trimmer}; use quick_xml::utils::{ByteBuf, Bytes}; use quick_xml::DeError; @@ -16,7 +16,7 @@ where { // Log XML that we try to deserialize to see it in the failed tests output dbg!(s); - let mut de = Deserializer::from_str(s); + let mut de = Deserializer::from_str(s, Trimmer::default()); let result = T::deserialize(&mut de); // If type was deserialized, the whole XML document should be consumed diff --git a/tests/serde-issues.rs b/tests/serde-issues.rs index 1d33b168..82a4e9e9 100644 --- a/tests/serde-issues.rs +++ b/tests/serde-issues.rs @@ -3,7 +3,7 @@ //! Name each module / test as `issue` and keep sorted by issue number use pretty_assertions::assert_eq; -use quick_xml::de::from_str; +use quick_xml::de::{from_str, Trimmer}; use quick_xml::se::{to_string, to_string_with_root}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -102,7 +102,7 @@ fn issue343() { \ \ "; - let users: Users = from_str(xml).unwrap(); + let users: Users = from_str(xml, Trimmer::default()).unwrap(); assert_eq!( users, @@ -133,7 +133,7 @@ fn issue349() { } assert_eq!( - from_str::("Id").unwrap(), + from_str::("Id", Trimmer::default()).unwrap(), Entity { id: Id { content: Enum::A("Id".to_string()), @@ -164,7 +164,7 @@ fn issue429() { } assert_eq!( - from_str::("B").unwrap(), + from_str::("B", Trimmer::default()).unwrap(), Root { state: StateOuter { state: State::B } } @@ -208,6 +208,7 @@ fn issue500() { \ \ ", + Trimmer::default(), ) .unwrap(); @@ -228,6 +229,7 @@ fn issue500() { \ \ ", + Trimmer::default(), ) .unwrap(); @@ -265,6 +267,7 @@ fn issue510() { \ \ ", + Trimmer::default(), ) .unwrap(); @@ -311,7 +314,8 @@ mod issue537 { fn de() { assert_eq!( from_str::( - r#""# + r#""#, + Trimmer::default() ) .unwrap(), Bindings { diff --git a/tests/serde-migrated.rs b/tests/serde-migrated.rs index 6033d167..3e39dc10 100644 --- a/tests/serde-migrated.rs +++ b/tests/serde-migrated.rs @@ -1,6 +1,6 @@ use std::fmt::Debug; -use quick_xml::de::from_str; +use quick_xml::de::{from_str, Trimmer}; use serde::{de, ser}; use serde::{Deserialize, Serialize}; @@ -20,7 +20,7 @@ where T: PartialEq + Debug + ser::Serialize + for<'de> de::Deserialize<'de>, { for (i, &(s, ref value)) in errors.iter().enumerate() { - match from_str::(s) { + match from_str::(s, Trimmer::default()) { Ok(v) => assert_eq!( v, *value, "{} error, expected: {:?}, found: {:?}", @@ -44,7 +44,7 @@ where T: PartialEq + Debug + ser::Serialize + for<'de> de::Deserialize<'de>, { for &s in errors { - assert!(from_str::(s).is_err()); + assert!(from_str::(s, Trimmer::default()).is_err()); } } diff --git a/tests/serde_roundtrip.rs b/tests/serde_roundtrip.rs index c14eaaf5..4e902950 100644 --- a/tests/serde_roundtrip.rs +++ b/tests/serde_roundtrip.rs @@ -1,4 +1,7 @@ -use quick_xml::{de::from_str, se::to_string}; +use quick_xml::{ + de::{from_str, Trimmer}, + se::to_string, +}; use serde::{Deserialize, Serialize}; use pretty_assertions::assert_eq; @@ -48,6 +51,7 @@ fn round_trip_list_of_enums() { // Then turn it back into a `Nodes` struct and make sure it's the same // as the original - let deserialized_nodes: Nodes = from_str(serialized_nodes.as_str()).unwrap(); + let deserialized_nodes: Nodes = + from_str(serialized_nodes.as_str(), Trimmer::default()).unwrap(); assert_eq!(deserialized_nodes, nodes); }