use rustical_xml::{ValueDeserialize, ValueSerialize, XmlDeserialize, XmlRootTag}; use super::PropfindType; #[derive(Clone, Debug, PartialEq)] pub enum SyncLevel { One, Infinity, } impl ValueDeserialize for SyncLevel { fn deserialize(val: &str) -> Result { Ok(match val { "1" => Self::One, "Infinity" => Self::Infinity, _ => { return Err(rustical_xml::XmlError::InvalidValue( rustical_xml::ParseValueError::Other("Invalid sync-level".to_owned()), )); } }) } } impl ValueSerialize for SyncLevel { fn serialize(&self) -> String { match self { SyncLevel::One => "1", SyncLevel::Infinity => "Infinity", } .to_owned() } } // https://datatracker.ietf.org/doc/html/rfc5323#section-5.17 #[derive(XmlDeserialize, Clone, Debug, PartialEq)] pub struct LimitElement { #[xml(ns = "crate::namespace::NS_DAV")] pub nresults: NresultsElement, } impl From for LimitElement { fn from(value: u64) -> Self { Self { nresults: NresultsElement(value), } } } impl From for u64 { fn from(value: LimitElement) -> Self { value.nresults.0 } } #[derive(XmlDeserialize, Clone, Debug, PartialEq)] pub struct NresultsElement(#[xml(ty = "text")] u64); #[derive(XmlDeserialize, Clone, Debug, PartialEq, XmlRootTag)] // // // #[xml(ns = "crate::namespace::NS_DAV", root = "sync-collection")] pub struct SyncCollectionRequest { #[xml(ns = "crate::namespace::NS_DAV")] pub sync_token: String, #[xml(ns = "crate::namespace::NS_DAV")] pub sync_level: SyncLevel, #[xml(ns = "crate::namespace::NS_DAV", ty = "untagged")] pub prop: PropfindType, #[xml(ns = "crate::namespace::NS_DAV")] pub limit: Option, } #[cfg(test)] mod tests { use crate::xml::{ PropElement, PropfindType, sync_collection::{SyncCollectionRequest, SyncLevel}, }; use rustical_xml::{EnumVariants, PropName, XmlDeserialize, XmlDocument}; const SYNC_COLLECTION_REQUEST: &str = r#" 1 100 "#; #[derive(XmlDeserialize, PropName, EnumVariants, PartialEq)] #[xml(unit_variants_ident = "TestPropName")] enum TestProp { Getetag(String), } #[test] fn test_parse_sync_collection_request() { let request = SyncCollectionRequest::::parse_str(SYNC_COLLECTION_REQUEST).unwrap(); assert_eq!( request, SyncCollectionRequest { sync_token: "".to_owned(), sync_level: SyncLevel::One, prop: PropfindType::Prop(PropElement(vec![TestPropName::Getetag], vec![])), limit: Some(100.into()) } ) } }