svg/node/
value.rs

1use std::fmt;
2use std::ops::Deref;
3
4/// A value of an attribute.
5#[derive(Clone, Debug, PartialEq)]
6pub struct Value(String);
7
8impl Deref for Value {
9    type Target = str;
10
11    #[inline]
12    fn deref(&self) -> &Self::Target {
13        &self.0
14    }
15}
16
17impl fmt::Display for Value {
18    #[inline]
19    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
20        self.0.fmt(formatter)
21    }
22}
23
24impl<T> PartialEq<T> for Value
25where
26    T: AsRef<str>,
27{
28    #[inline]
29    fn eq(&self, other: &T) -> bool {
30        self.0 == other.as_ref()
31    }
32}
33
34impl From<Value> for String {
35    #[inline]
36    fn from(Value(inner): Value) -> Self {
37        inner
38    }
39}
40
41macro_rules! implement {
42    ($($primitive:ty,)*) => (
43        $(impl From<$primitive> for Value {
44            #[inline]
45            fn from(inner: $primitive) -> Self {
46                Value(inner.to_string())
47            }
48        })*
49    );
50}
51
52implement! {
53    i8, i16, i32, i64, isize,
54    u8, u16, u32, u64, usize,
55    f32, f64,
56    String,
57    bool,
58}
59
60impl<'l> From<&'l str> for Value {
61    #[inline]
62    fn from(inner: &'l str) -> Value {
63        Value(inner.to_string())
64    }
65}
66
67impl<T> From<Vec<T>> for Value
68where
69    T: Into<Value>,
70{
71    fn from(mut inner: Vec<T>) -> Self {
72        Value(
73            inner
74                .drain(..)
75                .map(|value| value.into().0)
76                .collect::<Vec<_>>()
77                .join(" "),
78        )
79    }
80}
81
82macro_rules! implement {
83    (@express $e:expr) => ($e);
84    ($pattern:expr, $(($t:ident, $n:tt)),*) => (
85        impl<$($t),*> From<($($t),*)> for Value
86        where
87            $($t: Into<Value>),*
88        {
89            fn from(inner: ($($t),*)) -> Self {
90                Value(format!($pattern, $(implement!(@express inner.$n).into()),*))
91            }
92        }
93    );
94}
95
96implement! { "{} {}", (T0, 0), (T1, 1) }
97implement! { "{} {} {} {}", (T0, 0), (T1, 1), (T2, 2), (T3, 3) }
98
99#[cfg(test)]
100mod tests {
101    use super::Value;
102
103    #[test]
104    fn value_from_vector() {
105        assert_eq!(String::from(Value::from(vec![42, 69])), "42 69");
106    }
107}