virtual_node/velement/
attribute_value.rs1use std::fmt::{Display, Formatter};
2use wasm_bindgen::JsValue;
3
4#[derive(Debug, PartialEq, Clone)]
9pub enum AttributeValue {
10 String(String),
12 Bool(bool),
14}
15
16impl AttributeValue {
17 pub fn as_string(&self) -> Option<&String> {
19 match self {
20 AttributeValue::String(s) => Some(s),
21 _ => None,
22 }
23 }
24
25 pub fn as_bool(&self) -> Option<bool> {
27 match self {
28 AttributeValue::Bool(b) => Some(*b),
29 _ => None,
30 }
31 }
32}
33
34macro_rules! to_string_impls {
37 ($ty:ty) => {
38 impl From<$ty> for AttributeValue {
39 fn from(val: $ty) -> Self {
40 AttributeValue::String(val.to_string())
41 }
42 }
43
44 impl From<&$ty> for AttributeValue {
45 fn from(val: &$ty) -> Self {
46 AttributeValue::String(val.to_string())
47 }
48 }
49 };
50
51 ($ty:ty, $($tys:ty),*) => {
52 to_string_impls!( $ty );
53 to_string_impls! ( $($tys),* );
54 }
55}
56to_string_impls!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, f32, f64);
57
58impl Into<JsValue> for AttributeValue {
59 fn into(self) -> JsValue {
60 match self {
61 AttributeValue::String(s) => s.into(),
62 AttributeValue::Bool(b) => b.into(),
63 }
64 }
65}
66
67impl From<String> for AttributeValue {
68 fn from(s: String) -> Self {
69 AttributeValue::String(s)
70 }
71}
72
73impl From<&String> for AttributeValue {
74 fn from(s: &String) -> Self {
75 AttributeValue::String(s.to_string())
76 }
77}
78
79impl From<&str> for AttributeValue {
80 fn from(s: &str) -> Self {
81 AttributeValue::String(s.to_string())
82 }
83}
84
85impl<S: AsRef<str>, const N: usize> From<[S; N]> for AttributeValue {
86 fn from(vals: [S; N]) -> Self {
87 let mut combined = "".to_string();
88
89 for (idx, val) in vals.iter().enumerate() {
90 if idx != 0 {
91 combined += " ";
92 }
93
94 combined += val.as_ref();
95 }
96
97 AttributeValue::String(combined)
98 }
99}
100
101impl<S: AsRef<str>> From<Vec<S>> for AttributeValue {
102 fn from(vals: Vec<S>) -> Self {
103 let mut combined = "".to_string();
104
105 for (idx, val) in vals.iter().enumerate() {
106 if idx != 0 {
107 combined += " ";
108 }
109
110 combined += val.as_ref();
111 }
112
113 AttributeValue::String(combined)
114 }
115}
116
117impl From<bool> for AttributeValue {
118 fn from(b: bool) -> Self {
119 AttributeValue::Bool(b)
120 }
121}
122
123impl From<&bool> for AttributeValue {
124 fn from(b: &bool) -> Self {
125 AttributeValue::Bool(*b)
126 }
127}
128
129impl Display for AttributeValue {
130 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
131 match self {
132 AttributeValue::String(s) => s.fmt(f),
133 AttributeValue::Bool(b) => b.fmt(f),
134 }
135 }
136}
137
138#[cfg(test)]
139mod tests {
140 use super::*;
141
142 #[test]
143 fn array_of_as_ref_str() {
144 assert_eq!(
145 AttributeValue::from(["hello", "world"]),
146 AttributeValue::String("hello world".to_string())
147 );
148 }
149
150 #[test]
151 fn vec_of_as_ref_str() {
152 assert_eq!(
153 AttributeValue::from(vec!["foo", "bar"]),
154 AttributeValue::String("foo bar".to_string())
155 );
156 }
157}