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}