1use std::fmt;
2use std::ops::Deref;
3
4#[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}