Skip to main content

contacts_core/
property_status.rs

1use bytes::Bytes;
2
3use crate::{
4    Href,
5    ns::*,
6    PropertyResponse,
7    Status,
8    XmlError,
9    XmlReader,
10};
11
12/// Multi-Status Response [RFC 4918 section 14.3]
13///
14/// Specifically the second distinct format for responses
15/// from `PROPFIND` and `PROPPATCH`.
16///
17/// The response can contain multiple resources when
18/// the `depth` request was `1` or `infinity`.
19///
20/// [RFC 4918 section 14.3]:
21///    https://datatracker.ietf.org/doc/html/rfc4918#section-13
22#[derive(Debug)]
23pub struct PropertyMulti {
24    pub resources: Vec<PropertyResource>,
25    pub description: Option<String>,
26}
27
28#[derive(Debug)]
29pub struct PropertyResource {
30    pub href: Href,
31    pub statuses: Vec<PropertyStatus>,
32    //pub error
33    //pub description: Option<String>,
34    //pub location: Option<Href>
35}
36
37#[derive(Debug)]
38pub struct PropertyStatus {
39    pub responses: Vec<PropertyResponse>,
40    pub status: Status,
41    //pub error
42    //pub description: Option<String>,
43}
44
45impl PropertyMulti {
46    pub fn from_xml(bytes: Bytes) -> Result<Self, XmlError> {
47        let mut reader = XmlReader::new(bytes)?;
48        let mut resources = Vec::new();
49        let description;
50
51        reader.open(DAV, "multistatus")?;
52
53        while reader.is_open(DAV, "response")? {
54            let resource = PropertyResource::from_xml(&mut reader)?;
55            resources.push(resource);
56            reader.close()?;
57        }
58
59        if reader.is_open(DAV, "responsedescription")? {
60            description = Some(reader.text()?);
61            reader.close()?;
62        } else {
63            description = None;
64        }
65
66        reader.close()?;
67
68        Ok(Self {
69            resources,
70            description,
71        })
72    }
73}
74
75impl PropertyResource {
76    pub fn from_xml(reader: &mut XmlReader) -> Result<Self, XmlError> {
77        let href = Href::from_xml(reader)?;
78
79        let mut statuses = Vec::new();
80        reader.open(DAV, "propstat")?;
81        statuses.push(PropertyStatus::from_xml(reader)?);
82        reader.close()?;
83        while reader.is_open(DAV, "propstat")? {
84            statuses.push(PropertyStatus::from_xml(reader)?);
85            reader.close()?;
86        }
87
88        // reader.is_open(DAV, "error")?
89        // reader.is_open(DAV, "responsedescription")?
90        // reader.is_open(DAV, "location")?
91
92        Ok(Self {
93            href,
94            statuses,
95        })
96    }
97}
98
99impl PropertyStatus {
100    pub fn from_xml(reader: &mut XmlReader) -> Result<Self, XmlError> {
101        let mut responses = Vec::new();
102
103        reader.open(DAV, "prop")?;
104        while reader.not_close() {
105            let response = PropertyResponse::from_xml(reader)?;
106            responses.push(response);
107        }
108        reader.close()?;
109
110        let status = Status::from_xml(reader)?;
111
112        // reader.is_open(DAV, "error")?
113        // reader.is_open(DAV, "responsedescription")?
114
115        Ok(Self {
116            responses,
117            status,
118        })
119    }
120}
121