lumeohq / onvif-rs

A native Rust ONVIF client library.
MIT License
114 stars 61 forks source link

Find a way to handle list elements #10

Closed DmitrySamoylov closed 4 years ago

DmitrySamoylov commented 4 years ago

Story details: https://app.clubhouse.io/lumeo/story/373

I've added an example of how to handle list types. As an example I've used FocusOptions20Extension that includes a simple field (not attribute) of type StringAttrList.

#[derive(Default, PartialEq, Debug)]
pub struct StringAttrList(pub Vec<String>);

#[derive(Default, PartialEq, Debug, YaSerialize, YaDeserialize)]
#[yaserde(prefix = "tt", namespace = "tt: http://www.onvif.org/ver10/schema")]
pub struct FocusOptions20Extension {
    // TODO: yaserde macro for any element
    //  pub any: AnyElement,

    // Supported options for auto focus. Options shall be chosen from tt:AFModes.
    #[yaserde(prefix = "tt", rename = "AFModes")]
    pub af_modes: Option<StringAttrList>,
}

Impls for such cases are basically split/join operations:

impl YaDeserialize for StringAttrList {
    fn deserialize<R: Read>(reader: &mut yaserde::de::Deserializer<R>) -> Result<Self, String> {
        utils::yaserde::deserialize(reader, |s| {
            Ok(StringAttrList(
                s.split_whitespace().map(|s| s.to_string()).collect(),
            ))
        })
    }
}

impl YaSerialize for StringAttrList {
    fn serialize<W: Write>(&self, writer: &mut yaserde::ser::Serializer<W>) -> Result<(), String> {
        utils::yaserde::serialize(self, "StringAttrList", writer, |s| Ok(s.0.join(" ")))
    }
}