forked from NationTech/harmony
wip(opnsense-config): Refactoring to improve usability and features
This commit is contained in:
173
harmony-rs/opnsense-config-xml/src/xml_utils/maybe_string.rs
Normal file
173
harmony-rs/opnsense-config-xml/src/xml_utils/maybe_string.rs
Normal file
@@ -0,0 +1,173 @@
|
||||
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
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user