ms_autodiscover/types/
protocol.rs1use 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 #[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 pub fn file_extension(&self) -> String {
28 let ext = match self {
29 #[cfg(feature = "pox")]
30 Protocol::POX => "xml",
31 _ => "",
33 };
34
35 ext.to_string()
36 }
37
38 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 #[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 } _ => err!(
93 ErrorKind::InvalidProtocol,
94 "There is valid protocol to handle the response"
95 ),
96 }
97 }
98}