1#![allow(rustdoc::redundant_explicit_links)]
6
7mod element;
19pub mod elements;
20mod error;
21pub mod properties;
22mod read;
23mod utils;
24mod value;
25mod write;
26
27use bytes::{BufMut, Bytes};
28
29#[doc(no_inline)]
30pub use nonempty;
31
32pub use self::{
33 element::Element,
34 error::{Error, Result},
35 value::{Value, ValueMap},
36};
37
38pub const DAV_NAMESPACE: &str = "DAV:";
40pub const DAV_PREFIX: &str = "d";
42
43pub trait FromXml: Sized {
51 fn from_xml(xml: impl Into<bytes::Bytes>) -> crate::Result<Self>;
52}
53
54impl FromXml for Value {
55 fn from_xml(xml: impl Into<bytes::Bytes>) -> crate::Result<Self> {
56 crate::read::read_xml(xml)
57 }
58}
59
60impl<E> FromXml for E
61where
62 E: Element + for<'v> TryFrom<&'v Value, Error = Error>,
63{
64 fn from_xml(xml: impl Into<bytes::Bytes>) -> crate::Result<Self> {
65 Value::from_xml(xml)?.to_map()?.get::<E>().required::<E>()?
66 }
67}
68
69pub trait IntoXml: Sized {
77 fn write_xml(self, writer: impl std::io::Write) -> crate::Result<()>;
78 fn into_xml(self) -> crate::Result<Bytes> {
79 let mut xml = bytes::BytesMut::new().writer();
80 self.write_xml(&mut xml)?;
81 Ok(xml.into_inner().freeze())
82 }
83}
84
85impl<T> IntoXml for T
86where
87 T: Element + Into<Value>,
88{
89 fn write_xml(self, writer: impl std::io::Write) -> crate::Result<()> {
90 crate::write::write_xml::<T>(writer, self.into())
91 }
92}
93
94#[derive(Clone, Debug, PartialEq)]
98enum Todo {}
99
100pub(crate) trait OptionExt<T> {
101 fn required<E: Element>(self) -> crate::Result<T>;
102}
103impl<T> OptionExt<T> for Option<T> {
104 fn required<E: Element>(self) -> crate::Result<T> {
105 self.ok_or(Error::MissingElement(E::LOCAL_NAME))
106 }
107}