Skip to main content

character_service/
admin.rs

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