online Minecraft written book viewer
1use std::{
2 fmt::Display,
3 sync::{Arc, Mutex},
4};
5
6use anyhow::Context as _;
7use axum::{Extension, Router, routing::get};
8use tokio::net::TcpListener;
9use tower_http::compression::CompressionLayer;
10
11use crate::{cli::ServeArgs, library::Library};
12
13pub mod api;
14pub mod assets;
15pub mod pages;
16
17#[derive(Debug, Clone, Copy, clap::ValueEnum)]
18pub enum TextureKind {
19 /// <1.14 textures.
20 Legacy,
21 /// >=1.14 textures.
22 Modern,
23}
24
25impl Display for TextureKind {
26 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27 match self {
28 TextureKind::Legacy => write!(f, "legacy"),
29 TextureKind::Modern => write!(f, "modern"),
30 }
31 }
32}
33
34pub async fn start_webserver(
35 args: &ServeArgs,
36 library: Library,
37) -> anyhow::Result<()> {
38 let library = Arc::new(Mutex::new(library));
39 let app = Router::new()
40 .route("/", get(pages::index))
41 .route("/book/{hash}", get(pages::book))
42 .route("/random", get(pages::random_book))
43 .nest("/api", api::router(library.clone()))
44 .nest("/assets", assets::router())
45 .layer(CompressionLayer::new())
46 .layer(Extension(library))
47 .layer(Extension(args.ui_textures));
48
49 let address = args
50 .webserver_host_address
51 .parse::<std::net::SocketAddr>()
52 .context("Converting addr arg to socketaddr")?;
53
54 let listener = TcpListener::bind(address)
55 .await
56 .context("Binding listener")?;
57
58 tracing::info!("Binding webserver to {0}.", address);
59
60 axum::serve(listener, app)
61 .await
62 .context("Serving webserver")?;
63
64 Ok(())
65}