Files
harmony/harmony-rs/opnsense-config-xml/src/xml_utils/maybe_string.rs
2024-11-14 23:45:13 -05:00

174 lines
5.5 KiB
Rust

use xml::reader::XmlEvent as ReadEvent;
use xml::writer::XmlEvent as WriteEvent;
use yaserde::{ser, YaDeserialize as YaDeserializeTrait, YaSerialize as YaSerializeTrait};
#[derive(Debug, PartialEq, Default)]
pub struct MaybeString {
field_name: String,
content: Option<String>,
}
impl YaDeserializeTrait for MaybeString {
fn deserialize<R: std::io::Read>(
reader: &mut yaserde::de::Deserializer<R>,
) -> Result<Self, String> {
let field_name = match reader.peek()? {
ReadEvent::StartElement {
name, attributes, ..
} => {
if attributes.len() > 0 {
return Err(String::from(
"Attributes not currently supported by MaybeString",
));
}
name.local_name.clone()
}
_ => return Err(String::from("Unsupporte ReadEvent type")),
};
reader.next_event()?;
let content = match reader.peek()? {
ReadEvent::Characters(content) => Some(content.clone()),
ReadEvent::EndElement { name } => {
if name.local_name != field_name {
return Err(format!(
"Invalid EndElement, expected {field_name} but got {}",
name.local_name
));
}
None
}
_ => return Err(String::from("Unsupporte ReadEvent type")),
};
Ok(Self {
field_name,
content,
})
}
}
impl YaSerializeTrait for MaybeString {
fn serialize<W: std::io::Write>(&self, writer: &mut ser::Serializer<W>) -> Result<(), String> {
let start_element_event = WriteEvent::start_element(self.field_name.as_str());
writer.write(start_element_event).expect("Writer failed");
match &self.content {
Some(content) => {
writer
.write(WriteEvent::characters(content))
.expect("Writer failed");
}
None => {}
};
writer
.write(WriteEvent::end_element())
.expect("Writer failed");
Ok(())
}
fn serialize_attributes(
&self,
_attributes: Vec<xml::attribute::OwnedAttribute>,
_namespace: xml::namespace::Namespace,
) -> Result<
(
Vec<xml::attribute::OwnedAttribute>,
xml::namespace::Namespace,
),
String,
> {
unimplemented!("MaybeString does not currently support attributes")
}
}
#[cfg(test)]
mod test {
use super::*;
use pretty_assertions::assert_eq;
use yaserde_derive::YaDeserialize;
use yaserde_derive::YaSerialize;
#[derive(Debug, PartialEq, Default, YaDeserialize, YaSerialize)]
struct TestStruct {
maybe: MaybeString,
}
#[test]
fn maybe_string_should_deserialize_empty_element() {
let initial_xml = "<struct><maybe/></struct>";
let test_struct: TestStruct =
yaserde::de::from_str(initial_xml).expect("Shoudl deserialize teststruct");
println!("Got test_struct {:?}", test_struct);
assert_eq!(
test_struct,
TestStruct {
maybe: MaybeString {
field_name: String::from("maybe"),
content: None
}
}
);
}
#[test]
fn maybe_string_should_deserialize_content() {
let initial_xml = "<struct><maybe>some content</maybe></struct>";
let test_struct: TestStruct =
yaserde::de::from_str(initial_xml).expect("Shoudl deserialize teststruct");
println!("Got test_struct {:?}", test_struct);
assert_eq!(
test_struct,
TestStruct {
maybe: MaybeString {
field_name: String::from("maybe"),
content: Some(String::from("some content"))
}
}
);
}
#[test]
fn maybe_string_should_deserialize_empty_long_format() {
let initial_xml = "<struct><maybe></maybe></struct>";
let test_struct: TestStruct =
yaserde::de::from_str(initial_xml).expect("Shoudl deserialize teststruct");
println!("Got test_struct {:?}", test_struct);
assert_eq!(
test_struct,
TestStruct {
maybe: MaybeString {
field_name: String::from("maybe"),
content: None
}
}
);
}
#[test]
fn maybe_string_should_serialize_to_empty_element() {
let initial_xml =
r#"<?xml version="1.0" encoding="utf-8"?><TestStruct><maybe /></TestStruct>"#;
let test_struct: TestStruct =
yaserde::de::from_str(initial_xml).expect("Shoudl deserialize teststruct");
println!("Got test_struct {:?}", test_struct);
assert_eq!(
yaserde::ser::to_string(&test_struct).expect("should serialize teststruct"),
initial_xml
);
}
#[test]
fn maybe_string_should_serialize_content() {
let initial_xml = r#"<?xml version="1.0" encoding="utf-8"?><TestStruct><maybe>some content</maybe></TestStruct>"#;
let test_struct: TestStruct =
yaserde::de::from_str(initial_xml).expect("Shoudl deserialize teststruct");
println!("Got test_struct {:?}", test_struct);
assert_eq!(
yaserde::ser::to_string(&test_struct).expect("should serialize teststruct"),
initial_xml
);
}
}