meteoritus 0.2.1

A tus server integration for Rocket framework.
Documentation
use std::sync::Arc;

use rocket::{
    http::Status,
    outcome::Outcome,
    request::{self, FromRequest},
    response::{self, Responder},
    Orbit, Request, Rocket, State,
};

use crate::{HandlerContext, Meteoritus, Vault};

#[delete("/<id>")]
pub fn termination_handler(
    id: &str,
    req: TerminationRequest,
    vault: &State<Arc<dyn Vault>>,
    meteoritus: &State<Meteoritus<Orbit>>,
) -> TerminationResponder {
    match vault.terminate_file(id) {
        Err(_) => TerminationResponder::Failure,
        Ok(file) => {
            if let Some(callback) = &meteoritus.on_termination() {
                callback(HandlerContext {
                    rocket: req.rocket,
                    file_info: &file,
                });
            }

            TerminationResponder::Success
        }
    }
}

#[derive(Debug)]
pub struct TerminationRequest<'r> {
    rocket: &'r Rocket<Orbit>,
}

#[rocket::async_trait]
impl<'r> FromRequest<'r> for TerminationRequest<'r> {
    type Error = &'static str;

    async fn from_request(
        req: &'r Request<'_>,
    ) -> request::Outcome<Self, Self::Error> {
        Outcome::Success(TerminationRequest {
            rocket: req.rocket(),
        })
    }
}

pub enum TerminationResponder {
    Success,
    Failure,
}

impl<'r> Responder<'r, 'static> for TerminationResponder {
    fn respond_to(self, req: &'r Request<'_>) -> response::Result<'static> {
        let meteoritus = req.rocket().state::<Meteoritus<Orbit>>().unwrap();

        let mut res = rocket::Response::build();

        res.header(meteoritus.get_protocol_resumable_version());

        match self {
            Self::Success => res.status(Status::NoContent),
            Self::Failure => res.status(Status::Gone),
        };

        res.ok()
    }
}