1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
//! provides function and macro for html units such as px, %, em, etc.
use crate::prelude::Value;
macro_rules! declare_units{
( $(
$(#[$attr:meta])*
$name:ident;
)*
) => {
$(
$(#[$attr])*
pub fn $name<V>(v: V) -> String
where V: Into<Value>,
{
let value = v.into();
match value{
Value::Vec(values) => {
values.into_iter()
.map(|v|format!("{}{}",Into::<Value>::into(v), stringify!($name)))
.collect::<Vec<_>>().join(" ")
}
_ => {
format!("{}{}", Into::<Value>::into(value), stringify!($name))
}
}
}
)*
};
(
$(
$(#[$attr:meta])*
$name:ident => $unit:tt;
)*
) => {
$(
$(#[$attr])*
pub fn $name<V>(v: V) -> String
where V: Into<Value>,
{
let value = v.into();
match value{
Value::Vec(values) => {
values.into_iter()
.map(|v|format!("{}{}",Into::<Value>::into(v), $unit))
.collect::<Vec<_>>().join(" ")
}
_ => {
format!("{}{}", Into::<Value>::into(value), $unit)
}
}
}
)*
}
}
declare_units! {
/// pixels (1px = 1/96th of 1in)
///
/// a helper function which append `px` into a value
/// Example:
/// ```rust
/// use sauron::prelude::*;
/// use sauron::html::attributes::style;
///
/// let inline: Attribute<()> = style("width", px(100));
///
/// ```
px;
/// 1q is equivalent to 1/40th of 1cm.
q;
/// milimeters
mm;
/// centimeters
cm;
/// points (1pt = 1/72 of 1in)
pt;
/// picas (1pc = 12 pt)
pc;
/// Relative to the font-size of the element (2em means 2 times the size of the current font)
em;
/// Relative to the x-height of the current font (rarely used)
ex;
/// Relative to the width of the "0" (zero)
ch;
/// Relative to font-size of the root element
rem;
/// Relative to 1% of the width of the viewport*
vw;
/// Relative to 1% of the height of the viewport*
vh;
}
declare_units! {
/// inches (1in = 96px = 2.54cm)
r#in => "in";
/// percentage
percent => "%";
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_units() {
assert_eq!(px(1), "1px");
assert_eq!(px(-2), "-2px");
assert_eq!(px([0, -2, 4]), "0px -2px 4px");
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");
}
}