cabin/html/elements/
title.rs

1use std::borrow::Cow;
2
3use http::{HeaderName, HeaderValue};
4
5use crate::html::attributes::Attributes;
6use crate::html::{Global, Html};
7use crate::render::Renderer;
8use crate::view::RenderFuture;
9use crate::View;
10
11/// The `title` element represents the document's title or name. Authors should use titles that
12/// identify their documents even when they are used out of context, for example in a user's history
13/// or bookmarks, or in search results. The document's title is often different from its first
14/// heading, since the first heading does not have to stand alone when taken out of context.
15pub fn title(title: impl Into<Cow<'static, str>>) -> Html<marker::Title, (), Cow<'static, str>> {
16    Html::new("title", (), title.into())
17}
18
19pub mod marker {
20    pub struct Title;
21}
22
23impl<A: Attributes, V: 'static> Global for Html<marker::Title, A, V> {}
24
25pub struct TitleUpdate(pub Cow<'static, str>);
26
27pub fn title_update(title: impl Into<Cow<'static, str>>) -> TitleUpdate {
28    TitleUpdate(title.into())
29}
30
31impl View for TitleUpdate {
32    fn render(self, mut r: Renderer, _include_hash: bool) -> RenderFuture {
33        if r.is_update() {
34            match HeaderValue::from_str(&self.0) {
35                Ok(v) => {
36                    let h = r.headers_mut();
37                    h.insert(HeaderName::from_static("x-cabin-title"), v);
38                }
39                Err(err) => {
40                    tracing::error!(%err, "invalid header value for X-CABIN-TITLE");
41                }
42            }
43        }
44
45        RenderFuture::Ready(Some(Ok(r)))
46    }
47
48    fn prime(&mut self) {
49        self.0.prime()
50    }
51}