rustical_dav/header/
overwrite.rs

1use actix_web::{FromRequest, HttpRequest, ResponseError, http::StatusCode};
2use futures_util::future::{Ready, err, ok};
3use thiserror::Error;
4
5#[derive(Error, Debug)]
6#[error("Invalid Overwrite header")]
7pub struct InvalidOverwriteHeader;
8
9impl ResponseError for InvalidOverwriteHeader {
10    fn status_code(&self) -> actix_web::http::StatusCode {
11        StatusCode::BAD_REQUEST
12    }
13}
14
15#[derive(Debug, PartialEq, Default)]
16pub enum Overwrite {
17    #[default]
18    T,
19    F,
20}
21
22impl Overwrite {
23    pub fn is_true(&self) -> bool {
24        matches!(self, Self::T)
25    }
26}
27
28impl TryFrom<&[u8]> for Overwrite {
29    type Error = InvalidOverwriteHeader;
30
31    fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
32        match value {
33            b"T" => Ok(Overwrite::T),
34            b"F" => Ok(Overwrite::F),
35            _ => Err(InvalidOverwriteHeader),
36        }
37    }
38}
39
40impl FromRequest for Overwrite {
41    type Error = InvalidOverwriteHeader;
42    type Future = Ready<Result<Self, Self::Error>>;
43
44    fn extract(req: &HttpRequest) -> Self::Future {
45        if let Some(overwrite_header) = req.headers().get("Overwrite") {
46            match overwrite_header.as_bytes().try_into() {
47                Ok(depth) => ok(depth),
48                Err(e) => err(e),
49            }
50        } else {
51            // default depth
52            ok(Overwrite::F)
53        }
54    }
55
56    fn from_request(req: &HttpRequest, _payload: &mut actix_web::dev::Payload) -> Self::Future {
57        Self::extract(req)
58    }
59}