ms_autodiscover/types/
protocol.rs

1use std::{fmt::Display, io, path::Path};
2
3use bytes::Bytes;
4use log::debug;
5use surf::Url;
6
7#[cfg(feature = "pox")]
8use super::pox::Autodiscover as PoxAutodiscover;
9
10use super::response::AutodiscoverResult;
11use crate::error::{err, ErrorKind, Result};
12
13pub enum Protocol {
14    // SOAP,
15    #[cfg(feature = "pox")]
16    POX,
17}
18
19impl Display for Protocol {
20    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21        write!(f, "{}", self.file_extension())
22    }
23}
24
25impl Protocol {
26    /// Create the corresponding file extension for the current protocol.
27    pub fn file_extension(&self) -> String {
28        let ext = match self {
29            #[cfg(feature = "pox")]
30            Protocol::POX => "xml",
31            // CandidateType::SOAP => "svc",
32            _ => "",
33        };
34
35        ext.to_string()
36    }
37
38    /// Detects the protocol from a given url.
39    pub fn from_url<U: AsRef<str>>(url: U) -> Option<Self> {
40        let url = Url::parse(url.as_ref()).ok()?;
41
42        let path = Path::new(url.path());
43
44        if let Some(ext) = path.extension() {
45            if let Some(ext_str) = ext.to_str() {
46                return Self::from_ext(ext_str);
47            }
48        }
49
50        None
51    }
52
53    pub fn from_ext<E: AsRef<str>>(ext: E) -> Option<Self> {
54        match ext.as_ref() {
55            // "svc" => Some(Self::SOAP),
56            #[cfg(feature = "pox")]
57            "xml" => Some(Self::POX),
58            _ => None,
59        }
60    }
61
62    pub fn create_request_body<E: AsRef<str>>(&self, email_address: E) -> Result<Bytes> {
63        match &self {
64            #[cfg(feature = "pox")]
65            Protocol::POX => {
66                let request_config = PoxAutodiscover::create_request(email_address.as_ref());
67
68                let config_string = serde_xml_rs::to_string(&request_config)?;
69
70                debug!("Request configuration: {}", config_string);
71
72                Ok(config_string.into())
73            }
74            _ => Ok(Bytes::new()),
75        }
76    }
77
78    pub fn parse_response<B: AsRef<[u8]>>(&self, bytes: B) -> Result<AutodiscoverResult> {
79        let reader = io::Cursor::new(bytes);
80
81        match &self {
82            #[cfg(feature = "pox")]
83            Protocol::POX => {
84                let config = PoxAutodiscover::from_xml(reader)?;
85
86                Ok(config.into())
87            } // CandidateType::SOAP => {
88            //     let config: SoapConfig = serde_xml_rs::from_reader(xml)?;
89
90            //     Ok(config.into())
91            // }
92            _ => err!(
93                ErrorKind::InvalidProtocol,
94                "There is valid protocol to handle the response"
95            ),
96        }
97    }
98}