Skip to main content

doido_view/
content_for.rs

1//! Named content blocks (Rails `content_for(:name) { ... }` + `yield :name`).
2//!
3//! A view captures HTML under a key with [`ContentFor::set`]; the layout reads it
4//! back with [`ContentFor::get`]. Repeated `set`s for a key append, matching
5//! Rails' accumulating `content_for`.
6
7use std::collections::BTreeMap;
8
9/// A store of named content blocks for one render.
10#[derive(Debug, Default, Clone)]
11pub struct ContentFor {
12    blocks: BTreeMap<String, String>,
13}
14
15impl ContentFor {
16    pub fn new() -> Self {
17        Self::default()
18    }
19
20    /// Append `html` to the block under `key`.
21    pub fn set(&mut self, key: &str, html: &str) {
22        self.blocks
23            .entry(key.to_string())
24            .or_default()
25            .push_str(html);
26    }
27
28    /// The captured content for `key` (empty string if none — like `yield`).
29    pub fn get(&self, key: &str) -> &str {
30        self.blocks.get(key).map(String::as_str).unwrap_or("")
31    }
32
33    /// Whether any content was captured for `key` (Rails `content_for?`).
34    pub fn has(&self, key: &str) -> bool {
35        self.blocks.contains_key(key)
36    }
37}