class_names/
lib.rs

1#![no_std]
2use core::cell::RefCell;
3extern crate alloc;
4use alloc::string::String;
5use alloc::vec::Vec;
6
7pub trait AddClassList<'a> {
8    fn insert_into_list(&'a self, list: &'a ClassList<'a>);
9}
10
11impl<'a> AddClassList<'a> for &str {
12    fn insert_into_list(&'a self, list: &'a ClassList<'a>) {
13        list.classes.borrow_mut().push(self);
14    }
15}
16
17impl<'a> AddClassList<'a> for Option<&str> {
18    fn insert_into_list(&'a self, list: &'a ClassList<'a>) {
19        match self {
20            Some(t) => list.classes.borrow_mut().push(t),
21            None => (),
22        };
23    }
24}
25
26pub struct ClassList<'a> {
27    classes: RefCell<Vec<&'a str>>,
28}
29
30impl<'a> ClassList<'a> {
31    pub fn new() -> ClassList<'a> {
32        ClassList {
33            classes: RefCell::new(Vec::new()),
34        }
35    }
36    pub fn add<T>(&'a self, item: &'a T)
37    where
38        T: AddClassList<'a>,
39    {
40        (&item).insert_into_list(self);
41    }
42    pub fn to_string(&self) -> String {
43        self.classes.borrow_mut().join(" ")
44    }
45}
46
47#[macro_export]
48macro_rules! class_names {
49    // `()` indicates that the macro takes no argument.
50    ($($element:expr),*) => {
51        {
52            let class_list = ClassList::new();
53            $(
54                let e = $element;
55                class_list.add(&e);
56            )*
57            class_list.to_string()
58        }
59    };
60}