rustical_dav/header/
depth.rs1use actix_web::{FromRequest, HttpRequest, ResponseError, http::StatusCode};
2use futures_util::future::{Ready, err, ok};
3use rustical_xml::{ValueDeserialize, ValueSerialize, XmlError};
4use thiserror::Error;
5
6#[derive(Error, Debug)]
7#[error("Invalid Depth header")]
8pub struct InvalidDepthHeader;
9
10impl ResponseError for InvalidDepthHeader {
11 fn status_code(&self) -> actix_web::http::StatusCode {
12 StatusCode::BAD_REQUEST
13 }
14}
15
16#[derive(Debug, Clone, PartialEq)]
17pub enum Depth {
18 Zero,
19 One,
20 Infinity,
21}
22
23impl ValueSerialize for Depth {
24 fn serialize(&self) -> String {
25 match self {
26 Depth::Zero => "0",
27 Depth::One => "1",
28 Depth::Infinity => "infinity",
29 }
30 .to_owned()
31 }
32}
33
34impl ValueDeserialize for Depth {
35 fn deserialize(val: &str) -> Result<Self, XmlError> {
36 match val {
37 "0" => Ok(Self::Zero),
38 "1" => Ok(Self::One),
39 "infinity" | "Infinity" => Ok(Self::Infinity),
40 _ => Err(XmlError::InvalidVariant(
41 "Invalid value for depth".to_owned(),
42 )),
43 }
44 }
45}
46
47impl TryFrom<&[u8]> for Depth {
48 type Error = InvalidDepthHeader;
49
50 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
51 match value {
52 b"0" => Ok(Depth::Zero),
53 b"1" => Ok(Depth::One),
54 b"Infinity" | b"infinity" => Ok(Depth::Infinity),
55 _ => Err(InvalidDepthHeader),
56 }
57 }
58}
59
60impl FromRequest for Depth {
61 type Error = InvalidDepthHeader;
62 type Future = Ready<Result<Self, Self::Error>>;
63
64 fn extract(req: &HttpRequest) -> Self::Future {
65 if let Some(depth_header) = req.headers().get("Depth") {
66 match depth_header.as_bytes().try_into() {
67 Ok(depth) => ok(depth),
68 Err(e) => err(e),
69 }
70 } else {
71 ok(Depth::Zero)
73 }
74 }
75
76 fn from_request(req: &HttpRequest, _payload: &mut actix_web::dev::Payload) -> Self::Future {
77 Self::extract(req)
78 }
79}