diff --git a/src/html/elements.rs b/src/html/elements.rs new file mode 100644 index 0000000..e2ece82 --- /dev/null +++ b/src/html/elements.rs @@ -0,0 +1,151 @@ +use crate::html::Render; + +#[allow(non_camel_case_types)] +pub(crate) struct h1 { + text: String, +} + +impl Render for h1 { + fn render(&self) -> String { + format!("

{}

", self.text) + } +} + +impl h1 { + pub(crate) fn new(text: String) -> Self { + Self { text } + } +} + +#[allow(non_camel_case_types)] +pub(crate) struct h2 { + text: String, +} + +impl Render for h2 { + fn render(&self) -> String { + format!("

{}

", self.text) + } +} + +impl h2 { + pub(crate) fn new(text: String) -> Self { + Self { text } + } +} + +#[allow(non_camel_case_types)] +pub(crate) struct link { + rel: String, + href: String, +} + +impl Render for link { + fn render(&self) -> String { + format!("", self.rel, self.href) + } +} + +impl link { + pub(crate) fn new(rel: String, href: String) -> Self { + Self { rel, href } + } +} + +#[allow(non_camel_case_types)] +pub(crate) struct div { + id: String, + classes: Vec, + content: Vec>, +} + +impl Render for div { + fn render(&self) -> String { + let classes = self.classes.join(" "); + format!( + "
{}
", + self.id, + classes, + self.content.render() + ) + } +} + +impl div { + pub(crate) fn new(id: String, classes: Vec) -> Self { + Self { + id, + classes, + content: vec![], + } + } + + pub(crate) fn append_element(&mut self, element: impl Render + 'static) { + self.content.push(Box::new(element)); + } +} + +#[allow(non_camel_case_types)] +pub(crate) struct p { + id: String, + classes: Vec, + text: String +} + +impl Render for p { + fn render(&self) -> String { + let classes = self.classes.join(" "); + format!("

{}

", self.id, classes, self.text) + } +} + +impl p { + pub(crate) fn new(id: String, classes: Vec, text: String) -> Self { + Self { + id, + classes, + text + } + } +} + +#[allow(non_camel_case_types)] +pub(crate) struct img { + id: String, + classes: Vec, + src: String, +} + +impl Render for img { + fn render(&self) -> String { + let classes = self.classes.join(" "); + format!("", self.id, classes, self.src) + } +} + +impl img { + pub(crate) fn new(id: String, classes: Vec, src: String) -> Self { + Self { id, classes, src } + } +} + +#[allow(non_camel_case_types)] +pub(crate) struct a { + id: String, + classes: Vec, + href: String, + text: String, +} + +impl Render for a { + fn render(&self) -> String { + let classes = self.classes.join(" "); + format!("{}", self.id, classes, self.href, self.text) + } +} + +impl a { + pub(crate) fn new(id: String, classes: Vec, href: String, text: String) -> Self { + Self { id, classes, href, text } + } +} \ No newline at end of file diff --git a/src/html/mod.rs b/src/html/mod.rs new file mode 100644 index 0000000..80260ae --- /dev/null +++ b/src/html/mod.rs @@ -0,0 +1,63 @@ +pub(crate) mod elements; + +pub(crate) trait Render { + fn render(&self) -> String; +} + +pub(crate) struct Page { + title: String, + head: Vec>, + body: Vec>, +} + +impl Render for Vec> { + fn render(&self) -> String { + let mut result = String::new(); + for element in self { + let render = element.render(); + result.push_str(&render); + } + result + } +} + +impl Render for Page { + fn render(&self) -> String { + format!( + "\ + + + + + {} + +{} + + +{} + +", + self.title, + self.head.render(), + self.body.render() + ) + } +} + +impl Page { + pub(crate) fn new(title: String) -> Self { + Page { + title, + head: vec![], + body: vec![], + } + } + + pub(crate) fn append_element_to_body(&mut self, element: impl Render + 'static) { + self.body.push(Box::new(element)); + } + + pub(crate) fn append_element_to_head(&mut self, element: impl Render + 'static) { + self.head.push(Box::new(element)); + } +}