webdav_xml/elements/
response.rs1use nonempty::NonEmpty;
6
7use crate::{
8 elements::{Href, Propstat, ResponseDescription, Status},
9 utils::NonEmptyExt,
10 value::ValueMap,
11 Element, Error, OptionExt, Value, DAV_NAMESPACE, DAV_PREFIX,
12};
13
14#[derive(Clone, Debug, PartialEq)]
16pub enum Response {
17 Propstat {
18 href: Href,
19 propstat: NonEmpty<Propstat>,
20 responsedescription: Option<ResponseDescription>,
22 },
24 Status {
25 href: NonEmpty<Href>,
26 status: Status,
27 responsedescription: Option<ResponseDescription>,
29 },
31}
32
33impl Element for Response {
34 const NAMESPACE: &'static str = DAV_NAMESPACE;
35 const PREFIX: &'static str = DAV_PREFIX;
36 const LOCAL_NAME: &'static str = "response";
37}
38
39impl TryFrom<&Value> for Response {
40 type Error = Error;
41
42 fn try_from(value: &Value) -> Result<Self, Self::Error> {
43 let map = value.to_map()?;
44
45 match NonEmpty::try_collect(map.iter_all::<Propstat>())? {
46 Some(propstat) => Ok(Self::Propstat {
47 href: map.get().required::<Href>()??,
48 propstat,
49 responsedescription: map.get().transpose()?,
50 }),
51 None => Ok(Self::Status {
52 href: NonEmpty::try_collect(map.iter_all())?.required::<Href>()?,
53 status: map.get().required::<Status>()??,
54 responsedescription: map.get().transpose()?,
55 }),
56 }
57 }
58}
59
60impl From<Response> for Value {
61 fn from(response: Response) -> Value {
62 let mut map = ValueMap::new();
63
64 match response {
65 Response::Propstat {
66 href,
67 propstat,
68 responsedescription,
69 } => {
70 map.insert::<Href>(href.into());
71 map.insert::<Propstat>(Value::List(Box::new(
72 NonEmpty::collect(propstat.into_iter().map(Value::from)).expect(
73 "iterator is created from a `NonEmpty` and is guaranteed to be nonempty",
74 ),
75 )));
76 if let Some(responsedescription) = responsedescription {
77 map.insert::<ResponseDescription>(responsedescription.into())
78 }
79 }
80 Response::Status {
81 href,
82 status,
83 responsedescription,
84 } => {
85 map.insert::<Href>(Value::List(Box::new(
86 NonEmpty::collect(href.into_iter().map(Value::from)).expect(
87 "iterator is created from a `NonEmpty` and is guaranteed to be nonempty",
88 ),
89 )));
90 map.insert::<Status>(status.into());
91 if let Some(responsedescription) = responsedescription {
92 map.insert::<ResponseDescription>(responsedescription.into())
93 }
94 }
95 }
96
97 Value::Map(map)
98 }
99}