1use crate::*;
2pub use bytes::Bytes;
3pub use smol_str::SmolStr;
4
5use std::{collections::HashMap, hash::Hash};
6
7#[derive(Clone)]
12pub struct Value<'val, 'ty>(pub(crate) ValueInner<'val, 'ty>)
13where
14 'ty: 'val;
15
16#[derive(Clone)]
17pub(crate) enum ValueInner<'val, 'ty>
18where
19 'ty: 'val,
20{
21 U64(u64),
22 U32(u32),
23 U16(u16),
24 U8(u8),
25 I64(i64),
26 I32(i32),
27 I16(i16),
28 I8(i8),
29 F32(f32),
30 F64(f64),
31 Bool(bool),
32 String(&'val String),
33 Str(&'val str),
34 Vec(&'val (dyn VecInstance<'ty> + 'ty)),
35 HashMap(&'val (dyn HashMapInstance<'ty> + 'ty)),
36 Struct(&'val (dyn StructInstance<'ty> + 'ty)),
37 Enum(&'val (dyn EnumInstance<'ty> + 'ty)),
38 Bytes(&'val Bytes),
39 Option(&'val (dyn OptionInstance<'ty> + 'ty)),
40}
41
42impl<'val, 'ty> Value<'val, 'ty> {
43 pub fn from_vec(s: &'val (dyn VecInstance<'ty> + 'ty)) -> Value<'val, 'ty> {
45 Value(ValueInner::Vec(s))
46 }
47
48 pub fn from_hashmap(s: &'val (dyn HashMapInstance<'ty> + 'ty)) -> Value<'val, 'ty> {
50 Value(ValueInner::HashMap(s))
51 }
52
53 pub fn from_struct(s: &'val (dyn StructInstance<'ty> + 'ty)) -> Value<'val, 'ty> {
55 Value(ValueInner::Struct(s))
56 }
57
58 pub fn from_enum(s: &'val (dyn EnumInstance<'ty> + 'ty)) -> Value<'val, 'ty> {
60 Value(ValueInner::Enum(s))
61 }
62
63 pub fn from_option(s: &'val (dyn OptionInstance<'ty> + 'ty)) -> Value<'val, 'ty> {
65 Value(ValueInner::Option(s))
66 }
67
68 pub fn borrow<'b, T: FromValue<'val, 'ty>>(&'b self) -> Option<T>
71 where
72 'val: 'b,
73 'ty: 'b,
74 {
75 T::from_value(self)
76 }
77
78 pub fn into<T: FromValue<'val, 'ty> + 'ty>(self) -> Option<T> {
83 T::from_value(&self)
84 }
85
86 pub fn as_reflected_vec(&self) -> Option<&'val (dyn VecInstance<'ty> + 'ty)> {
88 match self.0 {
89 ValueInner::Vec(v) => Some(v),
90 _ => None,
91 }
92 }
93
94 pub fn as_reflected_struct(&self) -> Option<&'val (dyn StructInstance<'ty> + 'ty)> {
96 match self.0 {
97 ValueInner::Struct(v) => Some(v),
98 _ => None,
99 }
100 }
101
102 pub fn as_reflected_enum(&'val self) -> Option<&(dyn EnumInstance<'ty> + 'ty)> {
104 match self.0 {
105 ValueInner::Enum(v) => Some(v),
106 _ => None,
107 }
108 }
109
110 pub fn as_reflected_option(&'val self) -> Option<&(dyn OptionInstance<'ty> + 'ty)> {
112 match self.0 {
113 ValueInner::Option(v) => Some(v),
114 _ => None,
115 }
116 }
117
118 pub fn as_reflected_hashmap(&self) -> Option<&'val (dyn HashMapInstance<'ty> + 'ty)> {
120 match self.0 {
121 ValueInner::HashMap(v) => Some(v),
122 _ => None,
123 }
124 }
125
126 pub fn to_owned(&self) -> OwnedValue<'ty> {
128 match self.0 {
129 ValueInner::U64(u) => OwnedValue::U64(u),
130 ValueInner::U32(u) => OwnedValue::U32(u),
131 ValueInner::U16(u) => OwnedValue::U16(u),
132 ValueInner::U8(u) => OwnedValue::U8(u),
133 ValueInner::I64(u) => OwnedValue::I64(u),
134 ValueInner::I32(u) => OwnedValue::I32(u),
135 ValueInner::I16(u) => OwnedValue::I16(u),
136 ValueInner::I8(u) => OwnedValue::I8(u),
137 ValueInner::F32(u) => OwnedValue::F32(u),
138 ValueInner::F64(u) => OwnedValue::F64(u),
139 ValueInner::Bool(u) => OwnedValue::Bool(u),
140 ValueInner::String(s) => OwnedValue::String(s.clone()),
141 ValueInner::Str(s) => OwnedValue::String(s.to_string()),
142 ValueInner::Vec(v) => OwnedValue::Vec(v.boxed_clone()),
143 ValueInner::HashMap(v) => OwnedValue::HashMap(v.boxed_clone()),
144 ValueInner::Struct(s) => OwnedValue::Struct(s.boxed_clone()),
145 ValueInner::Enum(e) => OwnedValue::Enum(e.boxed_clone()),
146 ValueInner::Bytes(b) => OwnedValue::Bytes(b.clone()),
147 ValueInner::Option(o) => OwnedValue::Option(o.boxed_clone()),
148 }
149 }
150
151 pub fn try_hash<H: std::hash::Hasher>(&self, mut hasher: H) -> Option<u64> {
153 match self.0 {
154 ValueInner::U64(x) => x.hash(&mut hasher),
155 ValueInner::U32(x) => x.hash(&mut hasher),
156 ValueInner::U16(x) => x.hash(&mut hasher),
157 ValueInner::U8(x) => x.hash(&mut hasher),
158 ValueInner::I64(x) => x.hash(&mut hasher),
159 ValueInner::I32(x) => x.hash(&mut hasher),
160 ValueInner::I16(x) => x.hash(&mut hasher),
161 ValueInner::I8(x) => x.hash(&mut hasher),
162 ValueInner::Bool(x) => x.hash(&mut hasher),
163 ValueInner::String(x) => x.hash(&mut hasher),
164 ValueInner::Str(x) => x.hash(&mut hasher),
165 ValueInner::Bytes(x) => x.hash(&mut hasher),
166 _ => return None,
167 };
168 Some(hasher.finish())
169 }
170
171 pub fn slow_eq<'c, 'd>(&self, r: &Value<'c, 'd>) -> bool {
178 match (&self.0, &r.0) {
179 (ValueInner::U64(l), ValueInner::U64(r)) => l == r,
180 (ValueInner::U32(l), ValueInner::U32(r)) => l == r,
181 (ValueInner::U16(l), ValueInner::U16(r)) => l == r,
182 (ValueInner::U8(l), ValueInner::U8(r)) => l == r,
183 (ValueInner::I64(l), ValueInner::I64(r)) => l == r,
184 (ValueInner::I32(l), ValueInner::I32(r)) => l == r,
185 (ValueInner::I16(l), ValueInner::I16(r)) => l == r,
186 (ValueInner::I8(l), ValueInner::I8(r)) => l == r,
187 (ValueInner::F32(l), ValueInner::F32(r)) => l == r,
188 (ValueInner::F64(l), ValueInner::F64(r)) => l == r,
189 (ValueInner::Bool(l), ValueInner::Bool(r)) => l == r,
190 (ValueInner::String(l), ValueInner::String(r)) => l == r,
191 (ValueInner::Str(l), ValueInner::Str(r)) => l == r,
192 (ValueInner::String(l), ValueInner::Str(r))
193 | (ValueInner::Str(r), ValueInner::String(l)) => l == r,
194 (ValueInner::Bytes(l), ValueInner::Bytes(r)) => l == r,
195 (ValueInner::Struct(l), ValueInner::Struct(r)) => {
196 match_map_fields(l.values(), r.values())
197 }
198 (ValueInner::HashMap(l), ValueInner::HashMap(r)) => {
199 match_raw_map_fields(l.values(), r.values())
200 }
201 (ValueInner::Vec(l), ValueInner::Vec(r)) => match_vec_fields(l.values(), r.values()),
202 (ValueInner::Enum(l), ValueInner::Enum(r)) => match (l.field(), r.field()) {
203 (EnumField::Unit(l), EnumField::Unit(r)) => l == r,
204 (
205 EnumField::Tuple {
206 name: l_name,
207 fields: l_fields,
208 },
209 EnumField::Tuple {
210 name: r_name,
211 fields: r_fields,
212 },
213 ) => {
214 if l_name == r_name {
215 match_vec_fields(l_fields, r_fields)
216 } else {
217 false
218 }
219 }
220 (
221 EnumField::Struct {
222 name: l_name,
223 fields: l_fields,
224 },
225 EnumField::Struct {
226 name: r_name,
227 fields: r_fields,
228 },
229 ) => {
230 if l_name == r_name {
231 match_map_fields(l_fields, r_fields)
232 } else {
233 false
234 }
235 }
236 _ => false,
237 },
238 _ => false,
239 }
240 }
241}
242
243impl<'val, 'ty> From<&'val Bytes> for Value<'val, 'ty> {
244 fn from(bytes: &'val Bytes) -> Self {
245 Self(ValueInner::Bytes(bytes))
246 }
247}
248
249fn match_vec_fields(l_fields: Vec<CowValue<'_, '_>>, r_fields: Vec<CowValue<'_, '_>>) -> bool {
250 if l_fields.len() != r_fields.len() {
251 return false;
252 }
253 for (i, l_val) in l_fields.iter().enumerate() {
254 if let Some(r_val) = r_fields.get(i) {
255 if !l_val.slow_eq(r_val) {
256 return false;
257 }
258 } else {
259 return false;
260 }
261 }
262 true
263}
264
265fn match_raw_map_fields(
266 l_fields: HashMap<String, CowValue<'_, '_>>,
267 r_fields: HashMap<String, CowValue<'_, '_>>,
268) -> bool {
269 if l_fields.len() != r_fields.len() {
270 return false;
271 }
272
273 l_fields.iter().all(|(field, l_val)| {
274 r_fields.get(field).map_or(false, |r_val| l_val.slow_eq(r_val))
275 })
276}
277
278fn match_map_fields(
279 l_fields: HashMap<SmolStr, CowValue<'_, '_>>,
280 r_fields: HashMap<SmolStr, CowValue<'_, '_>>,
281) -> bool {
282 if l_fields.len() != r_fields.len() {
283 return false;
284 }
285 for (field, l_val) in &l_fields {
286 if let Some(r_val) = r_fields.get(field) {
287 if !l_val.slow_eq(r_val) {
288 return false;
289 }
290 } else {
291 return false;
292 }
293 }
294 true
295}
296
297impl std::fmt::Debug for Value<'_, '_> {
298 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
299 match self.0 {
300 ValueInner::U64(x) => std::fmt::Debug::fmt(&x, f),
301 ValueInner::U32(x) => std::fmt::Debug::fmt(&x, f),
302 ValueInner::U16(x) => std::fmt::Debug::fmt(&x, f),
303 ValueInner::U8(x) => std::fmt::Debug::fmt(&x, f),
304 ValueInner::I64(x) => std::fmt::Debug::fmt(&x, f),
305 ValueInner::I32(x) => std::fmt::Debug::fmt(&x, f),
306 ValueInner::I16(x) => std::fmt::Debug::fmt(&x, f),
307 ValueInner::I8(x) => std::fmt::Debug::fmt(&x, f),
308 ValueInner::F32(x) => std::fmt::Debug::fmt(&x, f),
309 ValueInner::F64(x) => std::fmt::Debug::fmt(&x, f),
310 ValueInner::Bool(x) => std::fmt::Debug::fmt(&x, f),
311 ValueInner::String(x) => std::fmt::Debug::fmt(&x, f),
312 ValueInner::Str(x) => std::fmt::Debug::fmt(&x, f),
313 ValueInner::Vec(x) => std::fmt::Debug::fmt(&x, f),
314 ValueInner::HashMap(x) => std::fmt::Debug::fmt(&x, f),
315 ValueInner::Struct(x) => std::fmt::Debug::fmt(&x, f),
316 ValueInner::Enum(x) => std::fmt::Debug::fmt(&x, f),
317 ValueInner::Bytes(x) => std::fmt::Debug::fmt(&x, f),
318 ValueInner::Option(x) => std::fmt::Debug::fmt(&x, f),
319 }
320 }
321}
322
323impl PartialEq for Value<'_, '_> {
324 fn eq(&self, other: &Self) -> bool {
325 match (&self.0, &other.0) {
326 (ValueInner::U64(l), ValueInner::U64(r)) => l == r,
327 (ValueInner::U32(l), ValueInner::U32(r)) => l == r,
328 (ValueInner::U16(l), ValueInner::U16(r)) => l == r,
329 (ValueInner::U8(l), ValueInner::U8(r)) => l == r,
330 (ValueInner::I64(l), ValueInner::I64(r)) => l == r,
331 (ValueInner::I32(l), ValueInner::I32(r)) => l == r,
332 (ValueInner::I16(l), ValueInner::I16(r)) => l == r,
333 (ValueInner::I8(l), ValueInner::I8(r)) => l == r,
334 (ValueInner::F32(l), ValueInner::F32(r)) => l == r,
335 (ValueInner::F64(l), ValueInner::F64(r)) => l == r,
336 (ValueInner::Bool(l), ValueInner::Bool(r)) => l == r,
337 (ValueInner::String(l), ValueInner::String(r)) => l == r,
338 (ValueInner::Str(st), ValueInner::String(s))
339 | (ValueInner::String(s), ValueInner::Str(st)) => st == s,
340 (ValueInner::Str(l), ValueInner::Str(r)) => l == r,
341 (ValueInner::Vec(l), ValueInner::Vec(r)) => l == r,
342 (ValueInner::Bytes(l), ValueInner::Bytes(r)) => l == r,
343 (ValueInner::Struct(l), ValueInner::Struct(r)) => l == r,
344 (ValueInner::Option(l), ValueInner::Option(r)) => l == r,
345 (ValueInner::Enum(l), ValueInner::Enum(r)) => l == r,
346 (ValueInner::HashMap(l), ValueInner::HashMap(r)) => l == r,
347 (_, _) => false,
348 }
349 }
350}