shiny_configuration/
value.rs1pub(crate) use deserializer::ValueDeserializer;
2use std::collections::{hash_map::Entry, HashMap};
3use crate::value::number::Number;
4
5pub mod deserializer;
6pub mod serializer;
7pub mod number;
8mod serialize;
9mod deserialize;
10
11
12
13#[derive(Debug, Clone)]
14pub enum Value {
15 String(String),
16 Bool(bool),
17 Number(Number),
18 None,
19 Map(HashMap<String, Value>),
20 Array(Vec<Value>),
21}
22
23impl Value {
24 pub fn merge(&mut self, merge_value: Value) {
25 match (self, merge_value) {
26 (Value::Map(ref mut self_map), Value::Map(merge_map)) => {
27 for (k, v) in merge_map {
28 match self_map.entry(k) {
29 Entry::Occupied(mut occupied) => {
30 occupied.get_mut().merge(v);
31 }
32 Entry::Vacant(vacant) => {
33 vacant.insert(v);
34 }
35 }
36 }
37 }
38 (self_value, merge_value) => *self_value = merge_value,
39 }
40 }
41
42 pub fn get(&self, key: &str) -> Option<&Value> {
43 if key.is_empty() {
44 return Some(self);
45 }
46
47 key.split('.').try_fold(self, |target, key| match target {
48 Value::Map(map) => map.get(key),
49 _ => None,
50 })
51 }
52
53 pub fn get_mut_or_create(&mut self, key: &str) -> &mut Value {
54 if key.is_empty() {
55 return self;
56 }
57
58 key.split('.').fold(self, |target, key| match target {
59 Value::Map(map) => map.entry(key.to_string()).or_insert(Value::None),
60 value => {
61 *value = Value::Map(HashMap::new());
62
63 match value {
64 Value::Map(map) => map.entry(key.to_string()).or_insert(Value::None),
65 _ => unreachable!(),
66 }
67 }
68 })
69 }
70}
71
72impl PartialEq for Value {
73 fn eq(&self, other: &Self) -> bool {
74 match (self, other) {
75 (Value::String(v1), Value::String(v2)) => v1 == v2,
76 (Value::Bool(v1), Value::Bool(v2)) => v1 == v2,
77 (Value::Number(v1), Value::Number(v2)) => v1 == v2,
78 (Value::None, Value::None) => true,
79 (Value::Map(v1), Value::Map(v2)) => v1 == v2,
80 (Value::Array(v1), Value::Array(v2)) => v1 == v2,
81 _ => false,
82 }
83 }
84}
85
86impl From<bool> for Value {
87 fn from(value: bool) -> Self {
88 Value::Bool(value)
89 }
90}
91
92impl From<()> for Value {
93 fn from(_: ()) -> Self {
94 Value::None
95 }
96}
97
98impl From<&str> for Value {
99 fn from(value: &str) -> Value {
100 Value::String(value.to_string())
101 }
102}
103
104impl From<String> for Value {
105 fn from(value: String) -> Value {
106 Value::String(value)
107 }
108}
109
110impl From<char> for Value {
111 fn from(value: char) -> Value {
112 Value::String(value.to_string())
113 }
114}
115
116impl From<u8> for Value {
117 fn from(value: u8) -> Self {
118 Value::Number(value.into())
119 }
120}
121
122impl From<u16> for Value {
123 fn from(value: u16) -> Self {
124 Value::Number(value.into())
125 }
126}
127
128impl From<u32> for Value {
129 fn from(value: u32) -> Self {
130 Value::Number(value.into())
131 }
132}
133
134impl From<u64> for Value {
135 fn from(value: u64) -> Self {
136 Value::Number(value.into())
137 }
138}
139
140impl From<i8> for Value {
141 fn from(value: i8) -> Self {
142 Value::Number(value.into())
143 }
144}
145
146impl From<i16> for Value {
147 fn from(value: i16) -> Self {
148 Value::Number(value.into())
149 }
150}
151
152impl From<i32> for Value {
153 fn from(value: i32) -> Self {
154 Value::Number(value.into())
155 }
156}
157
158impl From<i64> for Value {
159 fn from(value: i64) -> Self {
160 Value::Number(value.into())
161 }
162}
163
164impl From<f32> for Value {
165 fn from(value: f32) -> Self {
166 Value::Number(value.into())
167 }
168}
169
170impl From<f64> for Value {
171 fn from(value: f64) -> Self {
172 Value::Number(value.into())
173 }
174}
175
176impl<R: ToString, T: Into<Value>> From<HashMap<R, T>> for Value {
177 fn from(value: HashMap<R, T>) -> Self {
178 Value::Map(
179 value
180 .into_iter()
181 .map(|(k, v)| (k.to_string(), v.into()))
182 .collect(),
183 )
184 }
185}
186
187impl<T: Into<Value>> From<Vec<T>> for Value {
188 fn from(value: Vec<T>) -> Self {
189 Value::Array(value.into_iter().map(|v| v.into()).collect())
190 }
191}
192
193impl<T: Into<Value>> From<Option<T>> for Value {
194 fn from(v: Option<T>) -> Self {
195 match v {
196 None => Value::None,
197 Some(v) => v.into(),
198 }
199 }
200}