cruding_axum_api 0.4.2

axum Cruding api wrapper
Documentation
use std::sync::Arc;

use super::state::{CrudableAxumState, CrudableAxumStateListExt, into_owned_vec};
use super::types::CrudableAxum;
use crate::extractors::{AxumListParams, VecOrSingle};
use axum::response::IntoResponse;
use axum::{Json, extract::State};

fn with_ctx<CRUD, S, R>(
    state: S,
    ax_ctx: S::AxumCtx,
    f: impl FnOnce(S, super::types::ReqCtx<S::AxumCtx, S::InnerCtx>, S::SourceHandle) -> R,
) -> R
where
    CRUD: CrudableAxum,
    CRUD::Pkey: From<CRUD::PkeyDe>,
    S: CrudableAxumState<CRUD>,
{
    let sh = state.new_source_handle();
    let ctx = Arc::new((ax_ctx, state.inner_ctx()));
    f(state, ctx, sh)
}

pub async fn create<CRUD, S>(
    State(state): State<S>,
    ax_ctx: S::AxumCtx,
    Json(VecOrSingle(items)): Json<VecOrSingle<CRUD>>,
) -> Result<impl IntoResponse, S::Error>
where
    CRUD: CrudableAxum,
    CRUD::Pkey: From<CRUD::PkeyDe>,
    S: CrudableAxumState<CRUD>,
    S::Error: Send,
    S::AxumCtx: Send + Sync,
    S::InnerCtx: Send + Sync,
{
    with_ctx(state, ax_ctx, |s, ctx, sh| async move {
        let out = s.handler().create(items, ctx, sh).await?;
        Ok(Json(into_owned_vec(out)))
    })
    .await
}

pub async fn read<CRUD, S>(
    State(state): State<S>,
    ax_ctx: S::AxumCtx,
    Json(VecOrSingle(keys)): Json<VecOrSingle<<CRUD as CrudableAxum>::PkeyDe>>,
) -> Result<impl IntoResponse, S::Error>
where
    CRUD: CrudableAxum,
    CRUD::Pkey: From<CRUD::PkeyDe>,
    S: CrudableAxumState<CRUD>,
    S::Error: Send,
    S::AxumCtx: Send + Sync,
    S::InnerCtx: Send + Sync,
{
    let keys = keys.into_iter().map(Into::into).collect();
    with_ctx(state, ax_ctx, |s, ctx, sh| async move {
        let out = s.handler().read(keys, ctx, sh).await?;
        Ok(Json(into_owned_vec(out)))
    })
    .await
}

pub async fn update<CRUD, S>(
    State(state): State<S>,
    ax_ctx: S::AxumCtx,
    Json(VecOrSingle(items)): Json<VecOrSingle<CRUD>>,
) -> Result<impl IntoResponse, S::Error>
where
    CRUD: CrudableAxum,
    CRUD::Pkey: From<CRUD::PkeyDe>,
    S: CrudableAxumState<CRUD>,
    S::Error: Send,
    S::AxumCtx: Send + Sync,
    S::InnerCtx: Send + Sync,
{
    with_ctx(state, ax_ctx, |s, ctx, sh| async move {
        let out = s.handler().update(items, ctx, sh).await?;
        Ok(Json(into_owned_vec(out)))
    })
    .await
}

pub async fn delete<CRUD, S>(
    State(state): State<S>,
    ax_ctx: S::AxumCtx,
    Json(VecOrSingle(keys)): Json<VecOrSingle<<CRUD as CrudableAxum>::PkeyDe>>,
) -> Result<impl IntoResponse, S::Error>
where
    CRUD: CrudableAxum,
    CRUD::Pkey: From<CRUD::PkeyDe>,
    S: CrudableAxumState<CRUD>,
    S::Error: Send,
    S::AxumCtx: Send + Sync,
    S::InnerCtx: Send + Sync,
{
    let keys = keys.into_iter().map(Into::into).collect();
    with_ctx(state, ax_ctx, |s, ctx, sh| async move {
        s.handler().delete(keys, ctx, sh).await?;
        Ok(axum::http::StatusCode::NO_CONTENT)
    })
    .await
}

pub async fn read_list<CRUD, S>(
    State(state): State<S>,
    ax_ctx: S::AxumCtx,
    AxumListParams(params): AxumListParams<S::Column>,
) -> Result<impl IntoResponse, S::Error>
where
    CRUD: CrudableAxum,
    CRUD::Pkey: From<CRUD::PkeyDe>,
    S: CrudableAxumStateListExt<CRUD>,
    S::Error: Send,
    S::AxumCtx: Send + Sync,
    S::InnerCtx: Send + Sync,
{
    with_ctx(state, ax_ctx, |s, ctx, sh| async move {
        let out = s.handler_list().read_list(params, ctx, sh).await?;
        Ok(Json(into_owned_vec(out)))
    })
    .await
}