diff options
author | metamuffin <metamuffin@disroot.org> | 2024-09-20 21:36:22 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2024-09-20 21:36:36 +0200 |
commit | a294ea6772b1bf1bccc6f43dad026e5574de15af (patch) | |
tree | 8a47e08c81d6e5ebe0968a9a9c53952b4b368232 /server/registry/src/list.rs | |
parent | 44e90c75d10815633edaf979847c89b5d62242a3 (diff) | |
download | hurrycurry-a294ea6772b1bf1bccc6f43dad026e5574de15af.tar hurrycurry-a294ea6772b1bf1bccc6f43dad026e5574de15af.tar.bz2 hurrycurry-a294ea6772b1bf1bccc6f43dad026e5574de15af.tar.zst |
html listing
Diffstat (limited to 'server/registry/src/list.rs')
-rw-r--r-- | server/registry/src/list.rs | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/server/registry/src/list.rs b/server/registry/src/list.rs new file mode 100644 index 00000000..eb1ddfbf --- /dev/null +++ b/server/registry/src/list.rs @@ -0,0 +1,84 @@ +use crate::{PublicEntry, Registry}; +use anyhow::Result; +use rocket::{ + get, + http::MediaType, + request::{self, FromRequest, Outcome}, + response::content::{RawHtml, RawJson}, + Either, Request, State, +}; +use std::sync::Arc; +use tokio::sync::RwLock; + +#[get("/v1/list")] +pub(super) async fn r_list( + registry: &State<Arc<RwLock<Registry>>>, + json: AcceptJson, +) -> Either<RawJson<Arc<str>>, RawHtml<Arc<str>>> { + if json.0 { + Either::Left(RawJson(registry.read().await.json_response.clone())) + } else { + Either::Right(RawHtml(registry.read().await.html_response.clone())) + } +} + +pub(super) fn generate_json_list(entries: &[PublicEntry]) -> Result<Arc<str>> { + Ok(serde_json::to_string(&entries)?.into()) +} +pub(super) fn generate_html_list(entries: &[PublicEntry]) -> Result<Arc<str>> { + Ok(ListPage { entries }.to_string().into()) +} + +markup::define!( + ListPage<'a>(entries: &'a [PublicEntry]) { + @markup::doctype() + html { + head { + title { + "Hurry Curry! Server Registry" + } + } + body { + table { + tr { th {"Server"} th { "Players" } th { "Protocol" } } + @for e in *entries { tr { + td { details { + summary { @e.name } + ul { @for a in &e.address { li { @a } }} + } } + td { @e.players_online } + td { @e.version.0 "." @e.version.1 } + }} + } + } + } + } +); + +pub struct AcceptJson(bool); +impl<'r> FromRequest<'r> for AcceptJson { + type Error = (); + fn from_request<'life0, 'async_trait>( + request: &'r Request<'life0>, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future<Output = request::Outcome<Self, Self::Error>> + + ::core::marker::Send + + 'async_trait, + >, + > + where + 'r: 'async_trait, + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + Outcome::Success(AcceptJson( + request + .accept() + .map(|a| a.preferred().exact_eq(&MediaType::JSON)) + .unwrap_or(false), + )) + }) + } +} |