From 74c81b6a37930a9278e0d253a45f7f8bd0821e83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Sch=C3=A4fer?= Date: Thu, 3 Oct 2024 12:06:42 +0200 Subject: [PATCH] xso: add `from_reader` --- xso/src/lib.rs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/xso/src/lib.rs b/xso/src/lib.rs index f8f05ce9b54120bc5a993710a29f25233c1da183..1e2a2eacfad089f4a851bb2b5ac440c35418f175 100644 --- a/xso/src/lib.rs +++ b/xso/src/lib.rs @@ -416,6 +416,35 @@ pub fn from_bytes(mut buf: &[u8]) -> Result { Err(self::error::Error::XmlError(rxml::Error::InvalidEof(None))) } +/// Attempt to parse a type implementing [`FromXml`] from a reader. +pub fn from_reader(r: R) -> io::Result { + let mut reader = rxml::Reader::new(r); + let (name, attrs) = + read_start_event(&mut reader).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + let mut builder = match T::from_events(name, attrs) { + Ok(v) => v, + Err(self::error::FromEventsError::Mismatch { .. }) => { + return Err(self::error::Error::TypeMismatch) + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) + } + Err(self::error::FromEventsError::Invalid(e)) => { + return Err(e).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) + } + }; + for ev in reader { + if let Some(v) = builder + .feed(ev?) + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))? + { + return Ok(v); + } + } + Err(io::Error::new( + io::ErrorKind::UnexpectedEof, + self::error::Error::XmlError(rxml::Error::InvalidEof(None)), + )) +} + /// Attempt to serialise a type implementing [`AsXml`] to a vector of bytes. pub fn to_vec(xso: &T) -> Result, self::error::Error> { let iter = xso.as_xml_iter()?;