html_site_generator/html/
link.rs1use std::io::Write;
2
3use anyhow::Result;
4use derive_builder::Builder;
5
6use crate::html::hyperlink::ReferrerPolicy;
7use crate::html::IntoHtmlNode;
8
9#[derive(Debug, Clone)]
11pub enum CrossOrigin {
12 Anonymous,
13 UseCredentials,
14}
15
16impl CrossOrigin {
17 pub(crate) fn to_html_string(&self) -> &'static str {
18 match self {
19 CrossOrigin::Anonymous => "anonymous",
20 CrossOrigin::UseCredentials => "use-credentials",
21 }
22 }
23}
24
25#[derive(Debug, Clone, Default)]
27pub enum Relationship {
28 Alternate,
29 Author,
30 DnsPrefetch,
31 Help,
32 Icon,
33 License,
34 Next,
35 Pingback,
36 Preconnect,
37 Prefetch,
38 Preload,
39 Prerender,
40 Prev,
41 Search,
42 #[default]
43 Stylesheet,
44}
45
46impl Relationship {
47 fn to_html_string(&self) -> &'static str {
48 match self {
49 Relationship::Alternate => "alternate",
50 Relationship::Author => "author",
51 Relationship::DnsPrefetch => "dns-prefetch",
52 Relationship::Help => "help",
53 Relationship::Icon => "icon",
54 Relationship::License => "license",
55 Relationship::Next => "next",
56 Relationship::Pingback => "pingback",
57 Relationship::Preconnect => "preconnect",
58 Relationship::Prefetch => "prefetch",
59 Relationship::Preload => "preload",
60 Relationship::Prerender => "prerender",
61 Relationship::Prev => "prev",
62 Relationship::Search => "search",
63 Relationship::Stylesheet => "stylesheet",
64 }
65 }
66}
67
68#[derive(Debug, Default, Builder)]
70pub struct Link {
71 #[builder(setter(strip_option), default)]
73 crossorigin: Option<CrossOrigin>,
74
75 #[builder(setter(strip_option, into), default)]
77 href: Option<String>,
78
79 #[builder(setter(strip_option, into), default)]
81 href_lang: Option<String>,
82
83 #[builder(setter(strip_option, into), default)]
85 media: Option<String>,
86
87 #[builder(setter(strip_option), default)]
89 referrer_policy: Option<ReferrerPolicy>,
90
91 rel: Relationship,
93
94 #[builder(setter(strip_option, into), default)]
96 sizes: Option<String>,
97
98 #[builder(setter(strip_option, into), default)]
100 title: Option<String>,
101
102 #[builder(setter(strip_option, into), default)]
105 media_type: Option<String>,
106}
107
108impl IntoHtmlNode for Link {
109 fn transform_into_html_node(&self, buffer: &mut dyn Write) -> Result<()> {
110 write!(buffer, "<link")?;
111
112 if let Some(value) = &self.crossorigin {
113 write!(buffer, " crossorigin=\"{}\"", value.to_html_string())?;
114 }
115 if let Some(value) = &self.href {
116 write!(buffer, " href=\"{}\"", value)?;
117 }
118 if let Some(value) = &self.href_lang {
119 write!(buffer, " hreflang=\"{}\"", value)?;
120 }
121 if let Some(value) = &self.media {
122 write!(buffer, " media=\"{}\"", value)?;
123 }
124 if let Some(value) = &self.referrer_policy {
125 write!(buffer, " referrerpolicy=\"{}\"", value.to_html_string())?;
126 }
127 write!(buffer, " rel=\"{}\"", self.rel.to_html_string())?;
128 if let Some(value) = &self.sizes {
129 write!(buffer, " sizes=\"{}\"", value)?;
130 }
131 if let Some(value) = &self.title {
132 write!(buffer, " title=\"{}\"", value)?;
133 }
134 if let Some(value) = &self.title {
135 write!(buffer, " title=\"{}\"", value)?;
136 }
137 if let Some(value) = &self.media_type {
138 write!(buffer, " type=\"{}\"", value)?;
139 }
140
141 writeln!(buffer, ">")?;
142
143 Ok(())
144 }
145}