rustical_dav/xml/
sync_collection.rs1use rustical_xml::{ValueDeserialize, ValueSerialize, XmlDeserialize, XmlRootTag};
2
3use super::PropfindType;
4
5#[derive(Clone, Debug, PartialEq)]
6pub enum SyncLevel {
7 One,
8 Infinity,
9}
10
11impl ValueDeserialize for SyncLevel {
12 fn deserialize(val: &str) -> Result<Self, rustical_xml::XmlError> {
13 Ok(match val {
14 "1" => Self::One,
15 "Infinity" => Self::Infinity,
16 _ => {
17 return Err(rustical_xml::XmlError::InvalidValue(
18 rustical_xml::ParseValueError::Other("Invalid sync-level".to_owned()),
19 ));
20 }
21 })
22 }
23}
24
25impl ValueSerialize for SyncLevel {
26 fn serialize(&self) -> String {
27 match self {
28 SyncLevel::One => "1",
29 SyncLevel::Infinity => "Infinity",
30 }
31 .to_owned()
32 }
33}
34
35#[derive(XmlDeserialize, Clone, Debug, PartialEq)]
37pub struct LimitElement {
38 #[xml(ns = "crate::namespace::NS_DAV")]
39 pub nresults: NresultsElement,
40}
41
42impl From<u64> for LimitElement {
43 fn from(value: u64) -> Self {
44 Self {
45 nresults: NresultsElement(value),
46 }
47 }
48}
49
50impl From<LimitElement> for u64 {
51 fn from(value: LimitElement) -> Self {
52 value.nresults.0
53 }
54}
55
56#[derive(XmlDeserialize, Clone, Debug, PartialEq)]
57pub struct NresultsElement(#[xml(ty = "text")] u64);
58
59#[derive(XmlDeserialize, Clone, Debug, PartialEq, XmlRootTag)]
60#[xml(ns = "crate::namespace::NS_DAV", root = b"sync-collection")]
64pub struct SyncCollectionRequest<PN: XmlDeserialize> {
65 #[xml(ns = "crate::namespace::NS_DAV")]
66 pub sync_token: String,
67 #[xml(ns = "crate::namespace::NS_DAV")]
68 pub sync_level: SyncLevel,
69 #[xml(ns = "crate::namespace::NS_DAV", ty = "untagged")]
70 pub prop: PropfindType<PN>,
71 #[xml(ns = "crate::namespace::NS_DAV")]
72 pub limit: Option<LimitElement>,
73}
74
75#[cfg(test)]
76mod tests {
77 use crate::xml::{
78 PropElement, PropfindType,
79 sync_collection::{SyncCollectionRequest, SyncLevel},
80 };
81 use rustical_xml::{EnumVariants, PropName, XmlDeserialize, XmlDocument};
82
83 const SYNC_COLLECTION_REQUEST: &str = r#"<?xml version="1.0" encoding="UTF-8"?>
84 <sync-collection xmlns="DAV:">
85 <sync-token />
86 <sync-level>1</sync-level>
87 <limit>
88 <nresults>100</nresults>
89 </limit>
90 <prop>
91 <getetag />
92 </prop>
93 </sync-collection>
94 "#;
95
96 #[derive(XmlDeserialize, PropName, EnumVariants, PartialEq)]
97 #[xml(unit_variants_ident = "TestPropName")]
98 enum TestProp {
99 Getetag(String),
100 }
101
102 #[test]
103 fn test_parse_sync_collection_request() {
104 let request =
105 SyncCollectionRequest::<TestPropName>::parse_str(SYNC_COLLECTION_REQUEST).unwrap();
106 assert_eq!(
107 request,
108 SyncCollectionRequest {
109 sync_token: "".to_owned(),
110 sync_level: SyncLevel::One,
111 prop: PropfindType::Prop(PropElement(vec![TestPropName::Getetag], vec![])),
112 limit: Some(100.into())
113 }
114 )
115 }
116}