use crate::attributes::Attributes;
use crate::html_container::HtmlContainer;
use crate::Html;
mod header_content;
mod version;
pub use version::HtmlVersion;
#[derive(Debug, Default)]
pub struct HtmlPage {
version: version::HtmlVersion,
head: String,
body: String,
}
impl Html for HtmlPage {
fn to_html_string(&self) -> String {
format!(
"{}<html{}><head>{}</head><body>{}</body></html>",
self.version.doctype(),
self.version.html_attrs(),
self.head,
self.body,
)
}
}
impl HtmlContainer for HtmlPage {
#[inline]
fn add_html<H: Html>(&mut self, html: H) {
self.body.push_str(html.to_html_string().as_str());
}
}
impl HtmlPage {
pub fn new() -> Self {
Self::with_version(HtmlVersion::HTML5)
}
pub fn with_version(version: HtmlVersion) -> Self {
HtmlPage {
version,
head: String::new(),
body: String::new(),
}
}
#[inline]
fn add_html_head<H: Html>(&mut self, html: H) {
self.head.push_str(html.to_html_string().as_str());
}
#[inline]
fn with_html_head<H: Html>(mut self, html: H) -> Self {
self.add_html_head(html);
self
}
pub fn add_head_link(&mut self, href: impl ToString, rel: impl ToString) {
self.add_html_head(header_content::Link {
href: href.to_string(),
rel: rel.to_string(),
attr: Attributes::default(),
})
}
pub fn with_head_link(self, href: impl ToString, rel: impl ToString) -> Self {
self.with_html_head(header_content::Link {
href: href.to_string(),
rel: rel.to_string(),
attr: Attributes::default(),
})
}
pub fn add_head_link_attr<A, S>(&mut self, href: impl ToString, rel: impl ToString, attr: A)
where
A: IntoIterator<Item = (S, S)>,
S: ToString,
{
self.add_html_head(header_content::Link {
href: href.to_string(),
rel: rel.to_string(),
attr: attr.into(),
})
}
pub fn with_head_link_attr<A, S>(self, href: impl ToString, rel: impl ToString, attr: A) -> Self
where
A: IntoIterator<Item = (S, S)>,
S: ToString,
{
self.with_html_head(header_content::Link {
href: href.to_string(),
rel: rel.to_string(),
attr: attr.into(),
})
}
pub fn add_meta<A, S>(&mut self, attributes: A)
where
A: IntoIterator<Item = (S, S)>,
S: ToString,
{
self.add_html_head(header_content::Meta {
attr: attributes.into(),
})
}
pub fn with_meta<A, S>(self, attributes: A) -> Self
where
A: IntoIterator<Item = (S, S)>,
S: ToString,
{
self.with_html_head(header_content::Meta {
attr: attributes.into(),
})
}
pub fn add_script_link(&mut self, src: impl ToString) {
self.add_html_head(header_content::ScriptLink {
src: src.to_string(),
attr: Attributes::default(),
})
}
pub fn with_script_link(self, src: impl ToString) -> Self {
self.with_html_head(header_content::ScriptLink {
src: src.to_string(),
attr: Attributes::default(),
})
}
pub fn add_script_link_attr<A, S>(&mut self, src: impl ToString, attributes: A)
where
A: IntoIterator<Item = (S, S)>,
S: ToString,
{
self.add_html_head(header_content::ScriptLink {
src: src.to_string(),
attr: attributes.into(),
})
}
pub fn with_script_link_attr<A, S>(self, src: impl ToString, attributes: A) -> Self
where
A: IntoIterator<Item = (S, S)>,
S: ToString,
{
self.with_html_head(header_content::ScriptLink {
src: src.to_string(),
attr: attributes.into(),
})
}
pub fn add_script_literal(&mut self, code: impl ToString) {
self.add_html_head(header_content::ScriptLiteral {
code: code.to_string(),
})
}
pub fn with_script_literal(self, code: impl ToString) -> Self {
self.with_html_head(header_content::ScriptLiteral {
code: code.to_string(),
})
}
pub fn add_style(&mut self, css: impl ToString) {
self.add_html_head(header_content::Style {
css: css.to_string(),
attr: Attributes::default(),
})
}
pub fn with_style(self, css: impl ToString) -> Self {
self.with_html_head(header_content::Style {
css: css.to_string(),
attr: Attributes::default(),
})
}
pub fn add_style_attr<A, S>(&mut self, css: impl ToString, attributes: A)
where
A: IntoIterator<Item = (S, S)>,
S: ToString,
{
self.add_html_head(header_content::Style {
css: css.to_string(),
attr: attributes.into(),
})
}
pub fn with_style_attr<A, S>(self, css: impl ToString, attributes: A) -> Self
where
A: IntoIterator<Item = (S, S)>,
S: ToString,
{
self.with_html_head(header_content::Style {
css: css.to_string(),
attr: attributes.into(),
})
}
#[inline]
pub fn add_stylesheet(&mut self, source: impl ToString) {
self.add_head_link(source, "stylesheet")
}
#[inline]
pub fn with_stylesheet(self, source: impl ToString) -> Self {
self.with_head_link(source, "stylesheet")
}
pub fn add_title(&mut self, title_text: impl ToString) {
self.add_html_head(header_content::Title {
content: title_text.to_string(),
})
}
pub fn with_title(self, title_text: impl ToString) -> Self {
self.with_html_head(header_content::Title {
content: title_text.to_string(),
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default() {
let sut = HtmlPage::default();
let html_string = sut.to_html_string();
assert_eq!(
html_string,
"<!DOCTYPE html><html><head></head><body></body></html>"
)
}
}