use crate::parser::parser::Node;
use std::collections::HashMap;
#[derive(Debug, Clone, Default)]
pub struct SlotResolver {
named: HashMap<String, Vec<Node>>,
main: Vec<Node>,
}
impl SlotResolver {
pub fn from_component_body(nodes: &[Node]) -> Self {
let mut named = HashMap::new();
let mut main = Vec::new();
let mut i = 0;
while i < nodes.len() {
match &nodes[i] {
Node::Directive { name, body, .. } if name == "fill" => {
if let Some(fill_body) = body {
named.insert("default".to_string(), fill_body.clone());
}
i += 1;
}
_ => {
main.push(nodes[i].clone());
i += 1;
}
}
}
SlotResolver { named, main }
}
pub fn new() -> Self {
SlotResolver {
named: HashMap::new(),
main: Vec::new(),
}
}
pub fn add_fill(&mut self, name: &str, nodes: Vec<Node>) {
if name == "main" {
self.main = nodes;
} else {
self.named.insert(name.to_string(), nodes);
}
}
pub fn get_fill(&self, name: &str) -> Option<&Vec<Node>> {
if name == "main" {
if self.main.is_empty() {
None
} else {
Some(&self.main)
}
} else {
self.named.get(name)
}
}
pub fn resolve(&self, name: Option<&str>) -> &[Node] {
match name {
Some(slot_name) => self
.named
.get(slot_name)
.map(|v| v.as_slice())
.unwrap_or(&[]),
None => &self.main,
}
}
pub fn has_slot(&self, name: &str) -> bool {
self.named.contains_key(name)
}
pub fn has_main(&self) -> bool {
!self.main.is_empty()
}
pub fn named_slots(&self) -> impl Iterator<Item = &String> {
self.named.keys()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_resolve_main_slot() {
let resolver = SlotResolver {
named: HashMap::new(),
main: vec![Node::Text("main content".to_string())],
};
let result = resolver.resolve(None);
assert!(!result.is_empty());
}
#[test]
fn test_resolve_named_slot() {
let mut named = HashMap::new();
named.insert(
"header".to_string(),
vec![Node::Text("header content".to_string())],
);
let resolver = SlotResolver {
named,
main: vec![],
};
let result = resolver.resolve(Some("header"));
assert!(!result.is_empty());
}
#[test]
fn test_resolve_missing_slot() {
let resolver = SlotResolver {
named: HashMap::new(),
main: vec![],
};
let result = resolver.resolve(Some("missing"));
assert!(result.is_empty());
}
}