use axum::extract::{FromRequest, Request};
use serde::de::DeserializeOwned;

use crate::status::api_err::ApiErr;

pub struct Json<T>(pub T);

impl<S, T> FromRequest<S> for Json<T>
where
    S: Send + Sync,
    T: DeserializeOwned,
{
    type Rejection = ApiErr;

    async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
        let axum::Json(value) = axum::Json::<T>::from_request(req, state)
            .await
            .map_err(|rejection| ApiErr::Params(rejection.body_text()))?;

        Ok(Json(value))
    }
}
