forma_server/raw.rs
1//! The named raw HTML boundary. A RawHtml is reviewed application markup,
2//! not sanitized data. Each constructor belongs on the application's SR8
3//! allowlist with an owner. PageConfig::body_prefix accepts this type directly.
4use std::{fmt, ops::Deref};
5
6/// Markup explicitly vouched for by the application. The private field and sole
7/// named constructor keep raw entry points searchable; strings cannot become a
8/// RawHtml through From, Into, Default or deserialization.
9///
10/// ```
11/// use forma_server::RawHtml;
12/// let logo = RawHtml::trusted("<nav>Example</nav>");
13/// assert_eq!(logo.as_str(), "<nav>Example</nav>");
14/// ```
15///
16/// Verified by: crates/forma-server/tests/internal_renderer/raw_html.rs > "a_search_finds_one_raw_constructor"
17pub struct RawHtml {
18 html: Box<str>,
19}
20
21impl RawHtml {
22 /// Vouch for `html`: forma-server writes it into the page as it is.
23 ///
24 /// Whatever reaches the markup is trusted. Escape any value from a
25 /// request, a database or a tenant before it goes in, or render it
26 /// through a component instead, where the walker escapes it for you.
27 /// Each call belongs on the application's raw-entry allowlist
28 /// (`forma-raw-lint`) with an owner.
29 pub fn trusted(html: impl Into<String>) -> RawHtml {
30 let html = html.into().into_boxed_str();
31 RawHtml { html }
32 }
33
34 /// The markup.
35 pub fn as_str(&self) -> &str {
36 &self.html
37 }
38}
39
40impl Deref for RawHtml {
41 type Target = str;
42
43 fn deref(&self) -> &str {
44 &self.html
45 }
46}
47
48impl Clone for RawHtml {
49 fn clone(&self) -> Self {
50 RawHtml::trusted(&*self.html)
51 }
52}
53
54impl PartialEq for RawHtml {
55 fn eq(&self, other: &Self) -> bool {
56 self.html == other.html
57 }
58}
59
60impl Eq for RawHtml {}
61
62impl fmt::Debug for RawHtml {
63 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64 f.debug_tuple("RawHtml").field(&&*self.html).finish()
65 }
66}