#![doc = include_str!("../README.md")]
#![doc = include_str!("../examples/css/mod.rs")]
pub mod to_option_vec_string;
pub use to_option_vec_string::ToOptionVecString;
#[macro_export]
macro_rules! C {
( $($class:expr $(,)?)+ ) => {
{
let mut all_classes = vec![];
$(
$crate::_push_all_strings(&mut all_classes, $class.to_option_vec_string());
)*
all_classes.join(" ")
}
};
}
#[macro_export]
macro_rules! DC {
( $($class:expr $(,)?)+ ) => {
{
let mut all_classes = vec![];
$(
$crate::_push_all_strings(&mut all_classes, $class.to_option_vec_string());
)*
format_args!("{}", all_classes.join(" "))
}
};
}
#[macro_export]
macro_rules! M {
( $($modifier:expr $(,)?)* ) => {
{
let mut all_modifiers = vec![];
$(
$crate::_push_all_strings(&mut all_modifiers, $modifier.to_option_vec_string());
)*
all_modifiers.join(":")
}
};
}
pub fn _push_all_strings(all_strings: &mut Vec<String>, classes: Option<Vec<String>>) {
if let Some(classes) = classes {
all_strings.append(
&mut classes
.into_iter()
.filter(|c| !c.is_empty())
.collect::<Vec<_>>(),
);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test() {
assert_eq!(C![""], "");
assert_eq!(C!["x"], "x");
let x = "x";
let y = "y";
assert_eq!(C![x, y], "x y");
assert_eq!(C![x, y, "z"], "x y z");
assert_eq!(C![M!["md", "x"]], "md:x");
assert_eq!(C![M!["md", "hover", "x"]], "md:hover:x");
assert_eq!(C![M!["md", "x"], M!["hover", "y"]], "md:x hover:y");
assert_eq!(C![x, M!["md", y], M!["hover", "z"]], "x md:y hover:z");
let z = "z".to_string();
assert_eq!(C![x, y, z, "foo"], "x y z foo");
let z = "z".to_string();
assert_eq!(C![M![x, y, z, "foo"]], "x:y:z:foo");
}
#[test]
fn to_option_vec_string_ref_str() {
let text: &str = "foo";
assert_eq!(C![text], "foo");
assert_eq!(M![text], "foo");
}
#[test]
fn to_option_vec_string_ref_str_empty() {
let text: &str = "";
assert!(C![text].is_empty());
assert!(M![text].is_empty());
}
#[test]
fn to_option_vec_string_string() {
let text = String::from("bar");
assert_eq!(C![text], "bar");
let text = String::from("bar");
assert_eq!(M![text], "bar");
}
#[test]
fn to_option_vec_string_ref_string() {
let text = &String::from("ref_bar");
assert_eq!(C![text], "ref_bar");
let text = &String::from("ref_bar");
assert_eq!(M![text], "ref_bar");
}
#[test]
fn to_option_vec_string_vec() {
let vec: Vec<&str> = vec!["foo_1", "foo_2"];
assert_eq!(C![vec], "foo_1 foo_2");
let vec: Vec<&str> = vec!["foo_1", "foo_2"];
assert_eq!(M![vec], "foo_1:foo_2");
}
#[test]
fn to_option_vec_string_ref_vec() {
let vec: &Vec<&str> = &vec!["foo_1", "foo_2"];
assert_eq!(C![vec], "foo_1 foo_2");
let vec: &Vec<&str> = &vec!["foo_1", "foo_2"];
assert_eq!(M![vec], "foo_1:foo_2");
}
#[test]
fn to_option_vec_string_slice() {
let slice: &[&str] = &["foo_1", "foo_2"];
assert_eq!(C![slice], "foo_1 foo_2");
assert_eq!(M![slice], "foo_1:foo_2");
}
#[test]
fn to_option_vec_string_option_some() {
let option: Option<&str> = Some("foo_opt");
assert_eq!(C![option], "foo_opt");
assert_eq!(M![option], "foo_opt");
}
#[test]
fn to_option_vec_string_ref_option_some() {
let option: &Option<&str> = &Some("foo_opt");
assert_eq!(C![option], "foo_opt");
assert_eq!(M![option], "foo_opt");
}
#[test]
fn to_option_vec_string_option_none() {
let option: Option<&str> = None;
assert!(C![option].is_empty());
assert!(M![option].is_empty());
}
#[test]
fn to_option_vec_string_option_vec() {
let option_vec: Option<Vec<&str>> = Some(vec!["foo_1", "foo_2"]);
assert_eq!(C![option_vec], "foo_1 foo_2");
let option_vec: Option<Vec<&str>> = Some(vec!["foo_1", "foo_2"]);
assert_eq!(M![option_vec], "foo_1:foo_2");
}
#[test]
fn with_fmt() {
struct Classes {
classes: String,
}
impl std::fmt::Display for Classes {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{} {}", self.classes, C!["foo", "bar" M!["md", "baz"]],)
}
}
let classes = Classes {
classes: "x y z".to_string(),
};
assert_eq!(format!("{classes}"), "x y z foo bar md:baz");
}
}