use xml::reader::{EventReader, XmlEvent as ReadEvent}; use xml::writer::{EventWriter, XmlEvent as WriteEvent}; use yaserde::{ser, YaDeserialize as YaDeserializeTrait, YaSerialize as YaSerializeTrait}; use yaserde_derive::{YaDeserialize, YaSerialize}; #[derive(Debug, PartialEq, Default, YaDeserialize)] pub struct Parent { // pub rawxml_child: RawXml, pub string_child: String, pub child_child: Child, } #[derive(Debug, PartialEq, Default, YaDeserialize)] pub struct Child { pub child_val: String, pub child_val2: String, pub child_option: Option, } #[derive(Debug, PartialEq, Default)] pub struct RawXml(String); impl YaDeserializeTrait for RawXml { fn deserialize( reader: &mut yaserde::de::Deserializer, ) -> Result { let mut buffer = String::new(); let mut depth = 0; let own_name = match reader.peek()? { ReadEvent::StartElement { name, .. } => name.local_name.clone(), _ => return Err("RawXml Should start deserializing with StartElement".to_string()), }; println!("RawXml deserialize from root element name : {own_name}"); loop { let current_event = reader.peek()?.to_owned(); match current_event.clone() { ReadEvent::StartElement { name, attributes, .. } => { println!("StartElement {name} depth {depth}"); depth += 1; let mut attr_string = String::new(); attributes.iter().for_each(|a| { attr_string.push_str(&format!(r#" {}="{}""#, &a.name, &a.value)); }); buffer.push_str(&format!("<{}{}>", name, attr_string)); let _event = reader.next_event()?; } ReadEvent::EndElement { name } => { println!("EndElement {name} depth {depth}"); depth -= 1; buffer.push_str(&format!("", name)); println!( "Checking if name.local_name {} matches own_name {} at depth {depth}", &name.local_name, &own_name ); if name.local_name == own_name && depth == 0 { println!( "Found next EndElement is closing my struct, breaking out of loop" ); break; } else { let _event = reader.next_event()?; } } ReadEvent::Characters(content) => { println!("Characters {content} depth {depth}"); buffer.push_str(&content); let _event = reader.next_event()?; } ReadEvent::StartDocument { version, encoding, standalone, } => todo!( "StartDocument {:?} {:?} {:?}", version, encoding, standalone ), ReadEvent::EndDocument => todo!(), ReadEvent::ProcessingInstruction { name, data } => { todo!("ProcessingInstruction {:?}, {:?}", name, data) } ReadEvent::CData(cdata) => todo!("CData, {:?}", cdata), ReadEvent::Comment(comment) => todo!("Comment, {:?}", comment), ReadEvent::Whitespace(whitespace) => todo!("Whitespace, {:?}", whitespace), } let next = reader.peek()?; println!( "Processing done on \ncurrent_event : {:?} \nnext : {:?}", ¤t_event, &next ); } println!("buffered events {buffer}"); Ok(RawXml(buffer)) } } impl YaSerializeTrait for RawXml { fn serialize(&self, writer: &mut ser::Serializer) -> Result<(), String> { let content = self.0.clone(); let content = xml::EventReader::from_str(content.as_str()); let mut reader = yaserde::de::Deserializer::new(content); loop { let e = reader.next_event()?; if let ReadEvent::EndDocument = e { break; } writer .write(e.as_writer_event().unwrap()) .expect("Writer should write write event"); } Ok(()) } fn serialize_attributes( &self, attributes: Vec, namespace: xml::namespace::Namespace, ) -> Result< ( Vec, xml::namespace::Namespace, ), String, > { todo!() } } // impl YaSerializeTrait for RawXml { // fn serialize( // &self, // writer: &mut yaserde::ser::Serializer, // ) -> Result<(), String> { // let mut reader = EventReader::from_str(&self.0); // loop { // match reader.next() { // Ok(ReadEvent::StartElement { // name, // attributes, // namespace, // }) => { // let write = WriteEvent::from(reader.next().unwrap()); // writer // .write(WriteEvent::StartElement { // name: name.clone(), // attributes: attributes.clone(), // namespace: namespace.clone(), // }) // .map_err(|e| e.to_string())?; // } // Ok(ReadEvent::EndElement { name }) => { // writer // .write(WriteEvent::EndElement { name: Some(name) }) // .map_err(|e| e.to_string())?; // } // Ok(ReadEvent::Characters(content)) => { // writer // .write(WriteEvent::Characters(&content)) // .map_err(|e| e.to_string())?; // } // Ok(ReadEvent::Eof) => break, // Err(e) => return Err(e.to_string()), // _ => {} // } // } // Ok(()) // } // } // #[test] fn rawxml_should_buffer_empty_element() { let rawxml: RawXml = yaserde::de::from_str("").unwrap(); assert_eq!(rawxml.0, String::from("")); } #[test] fn rawxml_should_buffer_elements_with_different_case_as_they_are() { let xml = ""; let rawxml: RawXml = yaserde::de::from_str(xml).unwrap(); assert_eq!(rawxml.0, String::from(xml)); } #[test] fn rawxml_should_buffer_elements_with_attributes() { let xml = r#""#; let rawxml: RawXml = yaserde::de::from_str(xml).unwrap(); assert_eq!(rawxml.0, String::from(xml)); } #[test] fn rawxml_should_handle_complex_documents() { let xml = r#"1060s00101024102401ignore204816384"#; let rawxml: RawXml = yaserde::de::from_str(xml).unwrap(); assert_eq!(rawxml.0, String::from(xml)); } #[test] fn rawxml_should_serialize_simple_documents() { let xml = r#""#; let rawxml: RawXml = yaserde::de::from_str(xml).unwrap(); assert_eq!(yaserde::ser::to_string(&rawxml).unwrap(), xml); } #[test] fn rawxml_should_serialize_complex_documents() { let xml = r#"1060s00101024102401ignore204816384"#; let rawxml: RawXml = yaserde::de::from_str(xml).unwrap(); assert_eq!(yaserde::ser::to_string(&rawxml).unwrap(), xml); } #[test] fn rawxml_should_allow_siblings_before() { #[derive(YaDeserialize, YaSerialize)] struct Config { paul: Vec, raw: RawXml, } let xml = r#"bobobpatateallo something"#; let config: Config = yaserde::de::from_str(xml).unwrap(); assert_eq!(yaserde::ser::to_string(&config).unwrap(), xml); } #[test] fn rawxml_should_allow_siblings_after() { #[derive(YaDeserialize, YaSerialize)] struct Config { raw: RawXml, paul: Vec, } let xml = r#"allo somethingbobobpatate"#; let config: Config = yaserde::de::from_str(xml).unwrap(); assert_eq!(config.paul.get(0).unwrap(), "bobob"); assert_eq!(config.paul.get(1).unwrap(), "patate"); assert_eq!(config.paul.len(), 2); assert_eq!(config.raw.0, "allo something"); assert_eq!(yaserde::ser::to_string(&config).unwrap(), xml); } #[test] fn rawxml_should_allow_being_end_of_document() { let xml = r#"allo somethingbobobpatate"#; let config: RawXml = yaserde::de::from_str(xml).unwrap(); assert_eq!(yaserde::ser::to_string(&config).unwrap(), xml); }