Skip to main content

monster_service/
admin.rs

1//! The monster service's admin API (see [`edda_server::admin`]):
2//! exporting, importing and deleting a campaign's own monsters, spells and
3//! conditions.
4
5use axum::{
6    Json, Router,
7    extract::{Path, State},
8    http::StatusCode,
9    routing::{delete, get, put},
10};
11use edda_types::admin::{Deleted, Imported, MonstersExport};
12use sqlx::PgPool;
13use uuid::Uuid;
14
15use crate::{MonsterStore, error::ApiError};
16
17/// The admin API's routes.
18pub fn router(pool: PgPool) -> Router {
19    Router::new()
20        .route("/admin/campaigns/{id}", delete(remove))
21        .route("/admin/campaigns/{id}/export", get(export))
22        .route("/admin/campaigns/{id}/import", put(import))
23        .with_state(MonsterStore::new(pool))
24}
25
26/// Deletes a campaign's own monsters, spells and conditions; nothing, if there are none.
27async fn remove(
28    State(store): State<MonsterStore>,
29    Path(campaign): Path<Uuid>,
30) -> Result<Json<Deleted>, ApiError> {
31    let deleted = store.delete_campaign(campaign).await?;
32    Ok(Json(Deleted { deleted }))
33}
34
35/// The campaign's own, to keep or to move to another server.
36async fn export(
37    State(store): State<MonsterStore>,
38    Path(campaign): Path<Uuid>,
39) -> Result<Json<MonstersExport>, ApiError> {
40    Ok(Json(store.export_campaign(campaign).await?))
41}
42
43/// Takes in a campaign's own exported from another server; `409` if it
44/// has some here.
45async fn import(
46    State(store): State<MonsterStore>,
47    Path(campaign): Path<Uuid>,
48    Json(export): Json<MonstersExport>,
49) -> Result<(StatusCode, Json<Imported>), ApiError> {
50    let imported = store.import_campaign(campaign, &export).await?;
51    Ok((StatusCode::CREATED, Json(Imported { imported })))
52}