Skip to main content

combat_service/
admin.rs

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