From 074a84860ec66e3c3bc0d0962cb2f3b20a74dd77 Mon Sep 17 00:00:00 2001 From: Avril Date: Fri, 18 Sep 2020 19:16:47 +0100 Subject: [PATCH] html shit --- src/html/mod.rs | 113 ++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 25 +++++++++++ src/web/mod.rs | 10 +++++ 3 files changed, 148 insertions(+) create mode 100644 src/html/mod.rs diff --git a/src/html/mod.rs b/src/html/mod.rs new file mode 100644 index 0000000..33b3ba2 --- /dev/null +++ b/src/html/mod.rs @@ -0,0 +1,113 @@ +//! HTML rendering +use super::*; +use std::{ + fmt::{ + self, + Display, + }, +}; + +/// Coerce a `DisplayHtml` value into an opaque implementor of `fmt::Display`. +#[inline] pub fn display_html<'a, T: DisplayHtml+?Sized>(from: &'a T) -> impl fmt::Display +'a +{ + struct Wrap<'a, T: DisplayHtml+?Sized>(&'a T); + + impl<'a,T> fmt::Display for Wrap<'a,T> + where T: DisplayHtml+?Sized + { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result + { + DisplayHtml::fmt(self.0, f) + } + } + + Wrap(from) +} + +/// Coerse a `Display` value into a `DisplayHtml` by HTML-escaping its output. +/// +/// To output raw HTML, see `Safe`. +#[inline] pub fn escape_html<'a, T: Display+?Sized>(from: &'a T) -> impl DisplayHtml +'a +{ + struct Wrap<'a, T: Display+?Sized>(&'a T); + + impl<'a,T> DisplayHtml for Wrap<'a,T> + where T: Display +?Sized + { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result + { + //TODO: Escape HTML the string + } + } + + Wrap(from) +} + +/// HTML-safe wrapper around +#[derive(Debug, PartialEq, Eq)] +pub struct Safe(T); + +impl Safe +{ + /// Create a new instance with this value + #[inline] pub fn new(value: T) -> Self + { + Self(value) + } + + /// Consume this instance into its inner value + pub fn into_inner(self) -> T + { + self.0 + } + + /// Gets a reference to the inner value + pub fn display(&self) -> &T + { + &self.0 + } +} + +impl From for Safe +{ + #[inline] fn from(from: T) -> Self + { + Self(from) + } +} + +/// A trait for displaying as html. +/// +/// Any type implementing `Display` will implement `DisplayHtml` by HTML-escaping the output from it's display formatter. +/// You can also use `Safe` to render as raw HTML. +pub trait DisplayHtml +{ + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result; + + #[inline] fn to_html(&self) -> String + { + display_html(self).to_string() + } +} +impl DisplayHtml for Safe +{ + #[inline] fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result + { + self.0.fmt(fmt) + } + + #[inline] fn to_html(&self) -> String + { + self.0.to_string() + } +} + + +impl DisplayHtml for T +where T: Display +{ + #[inline] fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result + { + escape_html(self).fmt(fmt) + } +} diff --git a/src/main.rs b/src/main.rs index fc6c0c9..4b3c6fb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,6 +24,30 @@ use futures::{ }; use hex_literal::hex; +macro_rules! cfg_debug { + (if {$($if:tt)*} else {$($else:tt)*}) => { + { + #[cfg(debug_assertions)] { + $($if)* + } + #[cfg(not(debug_assertions))] { + $($else)* + } + } + }; + (if $if:expr) => { + { + #[cfg(debug_assertions)] $if + } + }; + (else $else:expr) => { + { + #[cfg(not(debug_assertions))] $else + } + }; +} + + mod ext; use ext::*; mod bytes; @@ -38,6 +62,7 @@ mod identity; mod post; mod state; +mod html; mod web; #[tokio::main] diff --git a/src/web/mod.rs b/src/web/mod.rs index f6b0549..b7d9015 100644 --- a/src/web/mod.rs +++ b/src/web/mod.rs @@ -212,6 +212,16 @@ async fn handle_conn(state: Arc, req: Request) -> Result Result<(), eyre::Report> { + cfg_debug!(if { + if &state.config != config::get() { + panic!("Our config is not the same as global? This is unsound."); + } + } else { + + if &state.config != config::get() { + warn!("Our config is not the same as global? This is unsound."); + } + }); let h = { let state = Arc::new(state);