html-pipe 0.1.1

A basic html component builder
Documentation
use std::fmt::Write;

pub const DOCTYPE: &str = "<!DOCTYPE html>";
pub type Buffer = String;
pub type Result<T> = std::result::Result<T, std::fmt::Error>;

pub fn node<'tag, Attrs, Children>(
    tag: &'tag str,
    attrs: Attrs,
    children: Children,
) -> impl FnOnce(&mut Buffer) -> Result<&mut Buffer> + 'tag
where
    Attrs: FnOnce(&mut Buffer) -> Result<&mut Buffer> + 'tag,
    Children: FnOnce(&mut Buffer) -> Result<&mut Buffer> + 'tag,
{
    |buf| {
        buf.push('<');
        buf.push_str(tag);
        attrs(buf)?;
        buf.push('>');
        children(buf)?;
        buf.push_str("</");
        buf.push_str(tag);
        buf.push('>');
        Ok(buf)
    }
}

pub fn node_empty<'tag, Attrs>(
    tag: &'tag str,
    attrs: Attrs,
) -> impl FnOnce(&mut Buffer) -> Result<&mut Buffer> + 'tag
where
    Attrs: FnOnce(&mut Buffer) -> Result<&mut Buffer> + 'tag,
{
    |buf| {
        buf.push('<');
        buf.push_str(tag);
        attrs(buf)?;
        buf.push_str("/>");
        Ok(buf)
    }
}

pub fn text(value: &str) -> impl FnOnce(&mut Buffer) -> Result<&mut Buffer> + '_ {
    |buf| {
        buf.push_str(value);
        Ok(buf)
    }
}

pub fn attr<'txt>(
    key: &'txt str,
    value: &'txt str,
) -> impl FnOnce(&mut Buffer) -> Result<&mut Buffer> + 'txt {
    move |buf| {
        write!(buf, " {key}={value:?}")?;
        Ok(buf)
    }
}

pub fn noop(buf: &mut Buffer) -> Result<&mut Buffer> {
    Ok(buf)
}

pub trait Component {
    fn render<'b>(&self, buf: &'b mut Buffer) -> Result<&'b mut Buffer> {
        Ok(buf)
    }
}