1pub trait IntoAttributeValue {
12 fn into_attribute_value(self) -> Option<String>;
14}
15
16macro_rules! impl_into_attribute_value {
17 ($t:ty) => {
18 impl IntoAttributeValue for $t {
19 fn into_attribute_value(self) -> Option<String> {
20 Some(format!("{}", self))
21 }
22 }
23 };
24}
25
26macro_rules! impl_into_attribute_values {
27 ($($t:ty),*) => {
28 $(impl_into_attribute_value!($t);)*
29 }
30}
31
32impl_into_attribute_values!(
33 usize,
34 u64,
35 u32,
36 u16,
37 u8,
38 isize,
39 i64,
40 i32,
41 i16,
42 i8,
43 ::core::net::IpAddr
44);
45
46impl IntoAttributeValue for String {
47 fn into_attribute_value(self) -> Option<String> {
48 Some(self)
49 }
50}
51
52impl IntoAttributeValue for &String {
53 fn into_attribute_value(self) -> Option<String> {
54 Some(self.to_owned())
55 }
56}
57
58impl IntoAttributeValue for &str {
59 fn into_attribute_value(self) -> Option<String> {
60 Some(self.to_owned())
61 }
62}
63
64impl<T: IntoAttributeValue> IntoAttributeValue for Option<T> {
65 fn into_attribute_value(self) -> Option<String> {
66 self.and_then(IntoAttributeValue::into_attribute_value)
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::IntoAttributeValue;
73 use core::net::IpAddr;
74 use core::str::FromStr;
75
76 #[test]
77 fn test_into_attribute_value_on_ints() {
78 assert_eq!(16u8.into_attribute_value().unwrap(), "16");
79 assert_eq!(17u16.into_attribute_value().unwrap(), "17");
80 assert_eq!(18u32.into_attribute_value().unwrap(), "18");
81 assert_eq!(19u64.into_attribute_value().unwrap(), "19");
82 assert_eq!(16i8.into_attribute_value().unwrap(), "16");
83 assert_eq!((-17i16).into_attribute_value().unwrap(), "-17");
84 assert_eq!(18i32.into_attribute_value().unwrap(), "18");
85 assert_eq!((-19i64).into_attribute_value().unwrap(), "-19");
86 assert_eq!(
87 IpAddr::from_str("0000:0::1")
88 .unwrap()
89 .into_attribute_value()
90 .unwrap(),
91 "::1"
92 );
93 }
94}