Skip to main content

monster_service/
lib.rs

1//! Monster service: stat blocks, and the full text of spells and
2//! conditions, in a shared library (the SRD, imported by an admin) plus
3//! each campaign's own. Every request needs a token from the auth service;
4//! a campaign sees the shared ones of its edition and its own, and can
5//! change only its own.
6
7/// Errors, as responses.
8/// What whoever runs the service asks of it over HTTP.
9pub mod admin;
10pub mod error;
11mod export;
12/// The HTTP routes.
13pub mod routes;
14pub mod store;
15pub mod texts;
16
17use std::sync::Arc;
18
19use axum::{Extension, Router};
20use edda_auth::server::TokenVerifier;
21use edda_server::{Limits, openapi::Conventions};
22use sqlx::PgPool;
23
24pub use store::MonsterStore;
25
26/// The service's `OpenAPI` description.
27#[derive(utoipa::OpenApi)]
28#[openapi(
29    paths(
30        edda_server::health,
31        edda_server::ready,
32        routes::list,
33        routes::create,
34        routes::fetch,
35        routes::replace,
36        routes::remove,
37        routes::spells::list,
38        routes::spells::create,
39        routes::spells::fetch,
40        routes::spells::replace,
41        routes::spells::remove,
42        routes::conditions::list,
43        routes::conditions::create,
44        routes::conditions::fetch,
45        routes::conditions::replace,
46        routes::conditions::remove,
47    ),
48    modifiers(&Conventions),
49    tags(
50        (name = "monsters", description = "Stat blocks: the shared library of the campaign's edition, and the campaign's own. Only DM devices change them."),
51        (name = "spells", description = "The text of spells, shared and the campaign's own, like monsters."),
52        (name = "conditions", description = "The text of conditions, shared and the campaign's own, like monsters."),
53    )
54)]
55pub struct ApiDoc;
56
57/// Opens (creating if needed) the database and applies migrations.
58pub async fn connect(database_url: &str) -> Result<PgPool, sqlx::Error> {
59    edda_server::open_database(database_url, &sqlx::migrate!()).await
60}
61
62/// The service, accepting tokens that `verifier` vouches for, within
63/// `limits` (how many monsters, spells and conditions of its own a campaign
64/// may keep).
65pub fn app(pool: PgPool, verifier: TokenVerifier, limits: Limits) -> Router {
66    let ready = edda_server::readiness(pool.clone());
67    Router::new()
68        .merge(routes::router())
69        .with_state(MonsterStore::new(pool))
70        .layer(Extension(Arc::new(verifier)))
71        .layer(Extension(Arc::new(limits)))
72        .merge(ready)
73}