#[cfg(feature = "macros")]
pub use ::avosetta_macros::html;
pub mod prelude {
pub use crate::Html;
#[cfg(feature = "macros")]
pub use crate::html;
}
pub trait Html {
fn write(self, s: &mut String);
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Raw<T>(pub T);
#[inline]
pub const fn raw<T>(x: T) -> Raw<T> {
Raw(x)
}
impl Html for () {
#[inline]
fn write(self, _: &mut String) {}
}
impl Html for bool {
#[inline]
fn write(self, s: &mut String) {
if self {
s.push_str("true");
} else {
s.push_str("false");
}
}
}
impl Html for char {
#[inline]
fn write(self, s: &mut String) {
match self {
'&' => s.push_str("&"),
'<' => s.push_str("<"),
'>' => s.push_str(">"),
'\'' => s.push_str("'"),
'\"' => s.push_str("""),
ch => {
s.push(ch);
}
}
}
}
impl Html for &str {
#[inline]
fn write(self, s: &mut String) {
for ch in self.chars() {
ch.write(s);
}
}
}
impl Html for String {
#[inline]
fn write(self, s: &mut String) {
self.as_str().write(s);
}
}
impl Html for Box<str> {
#[inline]
fn write(self, s: &mut String) {
self.as_ref().write(s);
}
}
impl Html for std::rc::Rc<str> {
#[inline]
fn write(self, s: &mut String) {
self.as_ref().write(s);
}
}
impl Html for std::sync::Arc<str> {
#[inline]
fn write(self, s: &mut String) {
self.as_ref().write(s);
}
}
impl Html for Raw<&str> {
#[inline]
fn write(self, s: &mut String) {
s.push_str(self.0);
}
}
impl Html for Raw<String> {
#[inline]
fn write(self, s: &mut String) {
Raw(self.0.as_str()).write(s);
}
}
impl Html for Raw<Box<str>> {
#[inline]
fn write(self, s: &mut String) {
Raw(self.0.as_ref()).write(s);
}
}
impl Html for Raw<std::rc::Rc<str>> {
#[inline]
fn write(self, s: &mut String) {
Raw(self.0.as_ref()).write(s);
}
}
impl Html for Raw<std::sync::Arc<str>> {
#[inline]
fn write(self, s: &mut String) {
Raw(self.0.as_ref()).write(s);
}
}
impl<T> Html for Option<T>
where
T: Html,
{
#[inline]
fn write(self, s: &mut String) {
if let Some(x) = self {
x.write(s);
}
}
}
impl<T> Html for T
where
T: FnOnce(&mut String),
{
#[inline]
fn write(self, s: &mut String) {
(self)(s)
}
}
macro_rules! __impl_html_integer {
($ty:ty) => {
impl $crate::Html for $ty {
#[inline]
fn write(self, s: &mut ::std::string::String) {
s.push_str(::itoa::Buffer::new().format(self));
}
}
};
}
__impl_html_integer!(usize);
__impl_html_integer!(isize);
__impl_html_integer!(u8);
__impl_html_integer!(i8);
__impl_html_integer!(u16);
__impl_html_integer!(i16);
__impl_html_integer!(u32);
__impl_html_integer!(i32);
__impl_html_integer!(u64);
__impl_html_integer!(i64);
__impl_html_integer!(u128);
__impl_html_integer!(i128);
macro_rules! __impl_html_float {
($ty:ty) => {
impl $crate::Html for $ty {
#[inline]
fn write(self, s: &mut ::std::string::String) {
s.push_str(::ryu::Buffer::new().format(self));
}
}
};
}
__impl_html_float!(f32);
__impl_html_float!(f64);
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Attr<K, V>(pub K, pub V);
impl Html for Attr<&str, &str> {
#[inline]
fn write(self, s: &mut String) {
s.push_str(self.0);
s.push_str("=\"");
self.1.write(s);
s.push_str("\"");
}
}
impl Html for Attr<&str, String> {
#[inline]
fn write(self, s: &mut String) {
Attr(self.0, self.1.as_str()).write(s);
}
}
impl Html for Attr<&str, Box<str>> {
#[inline]
fn write(self, s: &mut String) {
Attr(self.0, self.1.as_ref()).write(s);
}
}
impl Html for Attr<&str, std::rc::Rc<str>> {
#[inline]
fn write(self, s: &mut String) {
Attr(self.0, self.1.as_ref()).write(s);
}
}
impl Html for Attr<&str, std::sync::Arc<str>> {
#[inline]
fn write(self, s: &mut String) {
Attr(self.0, self.1.as_ref()).write(s);
}
}
impl Html for Attr<&str, Raw<&str>> {
#[inline]
fn write(self, s: &mut String) {
s.push_str(self.0);
s.push_str("=\"");
self.1.write(s);
s.push_str("\"");
}
}
impl Html for Attr<&str, Raw<String>> {
#[inline]
fn write(self, s: &mut String) {
Attr(self.0, Raw(self.1.0.as_str())).write(s);
}
}
impl Html for Attr<&str, Raw<Box<str>>> {
#[inline]
fn write(self, s: &mut String) {
Attr(self.0, Raw(self.1.0.as_ref())).write(s);
}
}
impl Html for Attr<&str, Raw<std::rc::Rc<str>>> {
#[inline]
fn write(self, s: &mut String) {
Attr(self.0, Raw(self.1.0.as_ref())).write(s);
}
}
impl Html for Attr<&str, Raw<std::sync::Arc<str>>> {
#[inline]
fn write(self, s: &mut String) {
Attr(self.0, Raw(self.1.0.as_ref())).write(s);
}
}
impl Html for Attr<&str, char> {
#[inline]
fn write(self, s: &mut String) {
s.push_str(self.0);
s.push_str("=\"");
self.1.write(s);
s.push_str("\"");
}
}
impl Html for Attr<&str, bool> {
#[inline]
fn write(self, s: &mut String) {
if self.1 {
s.push_str(self.0);
}
}
}
impl<T> Html for Attr<&str, Option<T>>
where
for<'a> Attr<&'a str, T>: Html,
{
#[inline]
fn write(self, s: &mut String) {
if let Some(x) = self.1 {
Attr(self.0, x).write(s);
}
}
}
impl<T> Html for Attr<&str, T>
where
T: FnOnce(&mut String),
{
#[inline]
fn write(self, s: &mut String) {
s.push_str(self.0);
s.push_str("=\"");
(self.1)(s);
s.push_str("\"");
}
}
macro_rules! __impl_attr_integer {
($ty:ty) => {
impl $crate::Html for $crate::Attr<&str, $ty> {
#[inline]
fn write(self, s: &mut ::std::string::String) {
s.push_str(self.0);
s.push_str("=\"");
s.push_str(::itoa::Buffer::new().format(self.1));
s.push_str("\"");
}
}
};
}
__impl_attr_integer!(usize);
__impl_attr_integer!(isize);
__impl_attr_integer!(u8);
__impl_attr_integer!(i8);
__impl_attr_integer!(u16);
__impl_attr_integer!(i16);
__impl_attr_integer!(u32);
__impl_attr_integer!(i32);
__impl_attr_integer!(u64);
__impl_attr_integer!(i64);
__impl_attr_integer!(u128);
__impl_attr_integer!(i128);
macro_rules! __impl_attr_float {
($ty:ty) => {
impl $crate::Html for $crate::Attr<&str, $ty> {
#[inline]
fn write(self, s: &mut ::std::string::String) {
s.push_str(self.0);
s.push_str("=\"");
s.push_str(::ryu::Buffer::new().format(self.1));
s.push_str("\"");
}
}
};
}
__impl_attr_float!(f32);
__impl_attr_float!(f64);