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
//! 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>,
                  {
                      format!("{}{}", v.into(), stringify!($name))
                  }
        )*
    };
    (
        $(
            $(#[$attr:meta])*
            $name:ident => $unit:tt;
         )*
    ) => {
        $(
            $(#[$attr])*
            pub fn $name<V>(v: V) -> String
            where V: Into<Value>,
                  {
                      format!("{}{}", v.into(), $unit)
                  }
        )*
    }
}

declare_units! {

    /// pixels (1px = 1/96th of 1in)
    ///
    /// a helper function which append `px` into a value
    /// Example:
    /// ```ignore
    /// 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!(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");
    }
}