Login
4 branches 0 tags
Ben (Desktop/Arch) Big code cleanup 5aad292 1 month ago 120 Commits
rubhub / src / extractors / path_user_project.rs
use axum::{
    extract::{FromRef, FromRequestParts, Path},
    http::{StatusCode, request::Parts},
};

use crate::{GlobalState, Project, User};

pub struct PathUserProject(pub User, pub Project);

impl<S> FromRequestParts<S> for PathUserProject
where
    S: Send + Sync,
    GlobalState: FromRef<S>,
{
    type Rejection = (StatusCode, &'static str);

    async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
        let Path((user_slug, project_slug)): Path<(String, String)> =
            Path::from_request_parts(parts, state)
                .await
                .map_err(|_| (StatusCode::BAD_REQUEST, "Invalid path parameter"))?;

        let state = GlobalState::from_ref(state);

        if let Some(user_slug) = user_slug.strip_prefix("~") {
            if let Ok(user) = User::load(&state, user_slug).await {
                if let Ok(project) = Project::load(&state, user_slug, &project_slug).await {
                    return Ok(PathUserProject(user, project));
                };
            }
        };
        Err((StatusCode::NOT_FOUND, "PathUserProject not found"))
    }
}