webdav_xml/elements/
status.rs1use std::{fmt::Display, str::FromStr};
6
7use crate::{Element, Error, Value, DAV_NAMESPACE, DAV_PREFIX};
8
9#[derive(Clone, Copy, Debug, PartialEq)]
11pub struct Status(pub http::StatusCode);
12
13impl Element for Status {
14 const NAMESPACE: &'static str = DAV_NAMESPACE;
15 const PREFIX: &'static str = DAV_PREFIX;
16 const LOCAL_NAME: &'static str = "status";
17}
18
19impl From<http::StatusCode> for Status {
20 fn from(code: http::StatusCode) -> Self {
21 Self(code)
22 }
23}
24
25impl FromStr for Status {
26 type Err = InvalidStatus;
27
28 fn from_str(s: &str) -> Result<Self, Self::Err> {
29 let mut parts = s.split(' ');
30 parts.next().ok_or_else(|| InvalidStatus(s.into()))?;
31 let status_code = parts
32 .next()
33 .and_then(|code| code.parse().ok())
34 .ok_or_else(|| InvalidStatus(s.into()))?;
35 Ok(Self(status_code))
36 }
37}
38
39impl Display for Status {
40 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
41 f.write_fmt(format_args!("HTTP/1.1 {}", self.0))
42 }
43}
44impl TryFrom<&Value> for Status {
45 type Error = Error;
46
47 fn try_from(value: &Value) -> Result<Self, Self::Error> {
48 value.to_str()?.parse().map_err(Error::other)
49 }
50}
51impl From<Status> for Value {
52 fn from(status: Status) -> Value {
53 status.to_string().into()
54 }
55}
56
57#[derive(Debug, thiserror::Error)]
58#[error("invalid status: {0}")]
59pub struct InvalidStatus(String);
60
61#[cfg(test)]
62#[test]
63fn test() -> eyre::Result<()> {
64 assert_eq!("HTTP/1.1 200 OK", Status(http::StatusCode::OK).to_string());
65 assert_eq!(
66 Status::from_str("HTTP/1.1 200 OK")?,
67 Status(http::StatusCode::OK)
68 );
69
70 Ok(())
71}