Added html elements

This commit is contained in:
2025-10-05 23:29:00 +02:00
parent 59305ce83c
commit af6fb8fd68
2 changed files with 214 additions and 0 deletions

151
src/html/elements.rs Normal file
View File

@@ -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!("<h1>{}</h1>", 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!("<h2>{}</h2>", 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!("<link rel=\"{}\" href=\"{}\">", 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<String>,
content: Vec<Box<dyn Render>>,
}
impl Render for div {
fn render(&self) -> String {
let classes = self.classes.join(" ");
format!(
"<div id=\"{}\" class=\"{}\">{}</div>",
self.id,
classes,
self.content.render()
)
}
}
impl div {
pub(crate) fn new(id: String, classes: Vec<String>) -> 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<String>,
text: String
}
impl Render for p {
fn render(&self) -> String {
let classes = self.classes.join(" ");
format!("<p id=\"{}\" class=\"{}\">{}</p>", self.id, classes, self.text)
}
}
impl p {
pub(crate) fn new(id: String, classes: Vec<String>, text: String) -> Self {
Self {
id,
classes,
text
}
}
}
#[allow(non_camel_case_types)]
pub(crate) struct img {
id: String,
classes: Vec<String>,
src: String,
}
impl Render for img {
fn render(&self) -> String {
let classes = self.classes.join(" ");
format!("<img id=\"{}\" class=\"{}\" src=\"{}\">", self.id, classes, self.src)
}
}
impl img {
pub(crate) fn new(id: String, classes: Vec<String>, src: String) -> Self {
Self { id, classes, src }
}
}
#[allow(non_camel_case_types)]
pub(crate) struct a {
id: String,
classes: Vec<String>,
href: String,
text: String,
}
impl Render for a {
fn render(&self) -> String {
let classes = self.classes.join(" ");
format!("<a id=\"{}\" class=\"{}\" href=\"{}\">{}</a>", self.id, classes, self.href, self.text)
}
}
impl a {
pub(crate) fn new(id: String, classes: Vec<String>, href: String, text: String) -> Self {
Self { id, classes, href, text }
}
}

63
src/html/mod.rs Normal file
View File

@@ -0,0 +1,63 @@
pub(crate) mod elements;
pub(crate) trait Render {
fn render(&self) -> String;
}
pub(crate) struct Page {
title: String,
head: Vec<Box<dyn Render>>,
body: Vec<Box<dyn Render>>,
}
impl Render for Vec<Box<dyn Render>> {
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!(
"\
<!DOCTYPE html>
<html lang=\"en\">
<head>
<meta charset=\"UTF-8\">
<title>{}</title>
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />
{}
</head>
<body>
{}
</body>
</html>",
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));
}
}