From 8c6a616015e24ee91c4006caf75d78f3561691db Mon Sep 17 00:00:00 2001 From: Lennart <18233294+lennart-k@users.noreply.github.com> Date: Mon, 30 Jun 2025 20:03:36 +0200 Subject: [PATCH] fix sync-collection limit element --- crates/dav/src/xml/sync_collection.rs | 73 +++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 3 deletions(-) diff --git a/crates/dav/src/xml/sync_collection.rs b/crates/dav/src/xml/sync_collection.rs index 2382523..b742d28 100644 --- a/crates/dav/src/xml/sync_collection.rs +++ b/crates/dav/src/xml/sync_collection.rs @@ -1,4 +1,4 @@ -use rustical_xml::{ValueDeserialize, ValueSerialize, XmlDeserialize}; +use rustical_xml::{ValueDeserialize, ValueSerialize, XmlDeserialize, XmlRootTag}; use super::PropfindType; @@ -32,11 +32,35 @@ impl ValueSerialize for SyncLevel { } } +// 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")] +#[xml(ns = "crate::namespace::NS_DAV", root = b"sync-collection")] pub struct SyncCollectionRequest { #[xml(ns = "crate::namespace::NS_DAV")] pub sync_token: String, @@ -45,5 +69,48 @@ pub struct SyncCollectionRequest { #[xml(ns = "crate::namespace::NS_DAV", ty = "untagged")] pub prop: PropfindType, #[xml(ns = "crate::namespace::NS_DAV")] - pub limit: Option, + 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()) + } + ) + } }