pub use crate::fns::rgb;
use crate::value::Value;
#[inline]
fn unit<V>(unit_name: &str, v: V) -> String
where
V: Into<Value>,
{
let value: Value = v.into();
match value {
Value::Vec(values) => values
.into_iter()
.map(|v| format!("{}{}", Into::<Value>::into(v), unit_name))
.collect::<Vec<_>>()
.join(" "),
_ => {
format!("{}{}", value, unit_name)
}
}
}
macro_rules! declare_units{
( $(
$(#[$attr:meta])*
$name:ident;
)*
) => {
$(
$(#[$attr])*
///
/// [MDN reference](https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Values_and_units)
pub fn $name<V>(v: V) -> String
where V: Into<Value>
{
unit(stringify!($name), v)
}
)*
};
(
$(
$(#[$attr:meta])*
$name:ident => $unit:tt;
)*
) => {
$(
$(#[$attr])*
pub fn $name<V>(v: V) -> String
where V: Into<Value>
{
unit($unit, v)
}
)*
}
}
declare_units! {
px;
q;
mm;
cm;
pt;
pc;
em;
ex;
ch;
rem;
vw;
vh;
}
declare_units! {
r#in => "in";
percent => "%";
}
declare_units! {
deg;
rad;
grad;
turn;
}
declare_units! {
s;
ms;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_units() {
assert_eq!(px(1), "1px");
assert_eq!(mm(1), "1mm");
assert_eq!(cm(2), "2cm");
assert_eq!(pt(5), "5pt");
assert_eq!(pc(5), "5pc");
assert_eq!(r#in(2.5), "2.5in");
assert_eq!(ch(1), "1ch");
}
}