Skip to main content

lunar_lib/formatter/
format_table.rs

1use std::{collections::HashMap, convert::Infallible};
2
3use crate::formatter::{Render, Taggable, Template, TemplateError};
4
5/// The format table for `key=value` pairs used when rendering `Arguments`, like in `format()`
6#[derive(Debug, Clone, PartialEq, Eq, Default)]
7pub struct FormatTable {
8    table: HashMap<String, String>,
9}
10
11impl FormatTable {
12    /// Creates a new, empty format table
13    #[must_use] 
14    pub fn new() -> Self {
15        Self {
16            table: HashMap::new(),
17        }
18    }
19
20    /// Renders a template to a string, replacing tags with values from the table
21    #[must_use] 
22    pub fn render(&self, template: &Template) -> String {
23        template.render(self)
24    }
25
26    pub fn render_string(&self, str: impl AsRef<str>) -> Result<String, TemplateError> {
27        let args = Template::try_from(str.as_ref())?;
28        Ok(self.render(&args))
29    }
30
31    /// Adds a single `key=value` pair to the table
32    pub fn add_entry(&mut self, key: impl Into<String>, value: impl Into<String>) {
33        self.table
34            .insert(key.into().to_ascii_lowercase(), value.into());
35    }
36
37    /// Extends the table with an iterator of `key=value` pairs
38    pub fn add_table<I, K, V>(&mut self, table: I)
39    where
40        I: IntoIterator<Item = (K, V)>,
41        K: Into<String>,
42        V: Into<String>,
43    {
44        self.table
45            .extend(table.into_iter().map(|(k, v)| (k.into(), v.into())));
46    }
47
48    /// Extends the table with any [`Taggable`]
49    pub fn extend_from_taggable<T: Taggable>(&mut self, from: &T) -> Result<(), T::Err> {
50        from.fill_table(self)
51    }
52
53    /// Gets the the held table of `self`
54    #[must_use] 
55    pub fn table(&self) -> &HashMap<String, String> {
56        &self.table
57    }
58}
59
60impl Taggable for FormatTable {
61    type Err = Infallible;
62
63    fn fill_table(&self, table: &mut FormatTable) -> Result<(), Infallible> {
64        table.table.extend(self.table.clone());
65        Ok(())
66    }
67}
68
69impl<I, K, V> From<I> for FormatTable
70where
71    I: IntoIterator<Item = (K, V)>,
72    K: Into<String>,
73    V: Into<String>,
74{
75    fn from(value: I) -> Self {
76        FormatTable::from_iter(value)
77    }
78}
79
80impl<K, V> FromIterator<(K, V)> for FormatTable
81where
82    K: Into<String>,
83    V: Into<String>,
84{
85    fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
86        FormatTable {
87            table: iter
88                .into_iter()
89                .map(|(k, v)| (k.into(), v.into()))
90                .collect(),
91        }
92    }
93}