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), +            )) +        }) +    } +} | 
