1use bytemuck::{AnyBitPattern, NoUninit, cast_slice, cast_slice_mut};
2use smol_str::SmolStr;
3use std::any::Any;
4use std::collections::BTreeMap;
5use std::mem;
6use tinyvec::TinyVec;
7const TINY_SIZE: usize = 28;
8pub mod json;
9#[derive(Debug, Default, Clone, PartialEq)]
10pub struct MyVec<T> {
11 pub(crate) data: TinyVec<[u8; TINY_SIZE]>,
12 phantom: std::marker::PhantomData<T>,
13}
14
15impl<T> MyVec<T> {
16 pub fn len(&self) -> usize {
17 self.data.len() / mem::size_of::<T>()
18 }
19
20 pub fn is_empty(&self) -> bool {
21 self.data.is_empty()
22 }
23
24 pub fn as_slice(&self) -> &[u8] {
25 self.data.as_slice()
26 }
27}
28
29impl<T: NoUninit + AnyBitPattern> MyVec<T> {
30 pub fn push(&mut self, value: T) {
31 let binding = [value];
32 let bytes = cast_slice(&binding);
33 self.data.extend_from_slice(bytes);
34 }
35
36 pub fn pop(&mut self) -> Option<T>
37 where
38 T: AnyBitPattern,
39 {
40 if self.data.len() < mem::size_of::<T>() {
41 return None;
42 }
43 let start = self.data.len() - mem::size_of::<T>();
44 let slice = &self.data[start..];
45 let value = cast_slice::<u8, T>(slice)[0];
46 self.data.truncate(start);
47 Some(value)
48 }
49
50 pub fn get(&self, idx: usize) -> Option<T> {
51 if idx >= self.len() {
52 return None;
53 }
54 let start = idx * mem::size_of::<T>();
55 let slice = &self.data[start..start + mem::size_of::<T>()];
56 Some(cast_slice::<u8, T>(slice)[0])
57 }
58
59 pub fn set(&mut self, idx: usize, value: T) {
60 if idx < self.len() {
61 let start = idx * mem::size_of::<T>();
62 let slice = &mut self.data[start..start + mem::size_of::<T>()];
63 cast_slice_mut::<u8, T>(slice)[0] = value;
64 }
65 }
66
67 pub fn iter(&self) -> Iter<'_, T> {
68 Iter { data: self.data.as_slice(), index: 0, phantom: std::marker::PhantomData }
69 }
70 pub fn extend_from_slice(&mut self, slice: &[T]) {
71 self.data.extend_from_slice(cast_slice(slice));
72 }
73}
74
75impl<T: NoUninit> From<&[T]> for MyVec<T> {
76 fn from(vec: &[T]) -> Self {
77 let mut data: TinyVec<[u8; TINY_SIZE]> = TinyVec::new();
78 data.extend_from_slice(cast_slice(vec));
79 Self { data, phantom: std::marker::PhantomData }
80 }
81}
82
83impl<T: NoUninit, const N: usize> From<[T; N]> for MyVec<T> {
84 fn from(arr: [T; N]) -> Self {
85 Self::from(&arr[..])
86 }
87}
88
89impl<T: AnyBitPattern> From<MyVec<T>> for Vec<T> {
90 fn from(my_vec: MyVec<T>) -> Self {
91 cast_slice(my_vec.data.as_slice()).to_vec()
92 }
93}
94
95pub struct Iter<'a, T> {
96 data: &'a [u8],
97 index: usize,
98 phantom: std::marker::PhantomData<T>,
99}
100
101impl<'a, T: AnyBitPattern> Iterator for Iter<'a, T> {
102 type Item = &'a T;
103 fn next(&mut self) -> Option<Self::Item> {
104 let size = std::mem::size_of::<T>();
105 let start = self.index * size;
106
107 if start + size > self.data.len() {
108 return None;
109 }
110
111 let slice = &self.data[start..start + size];
112 let value = &cast_slice::<u8, T>(slice)[0];
113 self.index += 1;
114 Some(value)
115 }
116
117 fn size_hint(&self) -> (usize, Option<usize>) {
118 let remaining = self.data.len() / std::mem::size_of::<T>() - self.index;
119 (remaining, Some(remaining))
120 }
121}
122
123impl<'a, T: AnyBitPattern> ExactSizeIterator for Iter<'a, T> {
124 fn len(&self) -> usize {
125 self.data.len() / std::mem::size_of::<T>() - self.index
126 }
127}
128
129#[derive(Debug, thiserror::Error)]
130pub enum DynamicErr {
131 #[error("type mismatch")]
132 TypeMismatch,
133 #[error("range error: {0}")]
134 Range(i64),
135 #[error("没有成员: {0}")]
136 NoField(SmolStr),
137 #[error("out of range")]
138 OutOfRange,
139}
140
141use std::sync::{Arc, RwLock};
142
143pub trait CustomProperty: Any + Send + Sync {
144 fn get_key(&self, key: &str) -> Option<Dynamic>;
145
146 fn set_key(&self, key: &str, value: Dynamic) -> bool;
147
148 fn contains_key(&self, key: &str) -> bool {
149 self.get_key(key).is_some()
150 }
151}
152
153#[derive(Clone)]
154pub struct CustomValue {
155 type_name: &'static str,
156 value: Arc<dyn Any + Send + Sync>,
157 get_key: Option<fn(&(dyn Any + Send + Sync), &str) -> Option<Dynamic>>,
158 set_key: Option<fn(&(dyn Any + Send + Sync), &str, Dynamic) -> bool>,
159 contains_key: Option<fn(&(dyn Any + Send + Sync), &str) -> bool>,
160}
161
162impl CustomValue {
163 pub fn new<T>(value: T) -> Self
164 where
165 T: Any + Send + Sync + 'static,
166 {
167 Self { type_name: std::any::type_name::<T>(), value: Arc::new(value), get_key: None, set_key: None, contains_key: None }
168 }
169
170 pub fn from_arc<T>(value: Arc<T>) -> Self
171 where
172 T: Any + Send + Sync + 'static,
173 {
174 Self { type_name: std::any::type_name::<T>(), value, get_key: None, set_key: None, contains_key: None }
175 }
176
177 pub fn new_with_properties<T>(value: T) -> Self
178 where
179 T: CustomProperty + 'static,
180 {
181 Self::from_property_arc(Arc::new(value))
182 }
183
184 pub fn from_property_arc<T>(value: Arc<T>) -> Self
185 where
186 T: CustomProperty + 'static,
187 {
188 fn get_key<T: CustomProperty + 'static>(value: &(dyn Any + Send + Sync), key: &str) -> Option<Dynamic> {
189 value.downcast_ref::<T>()?.get_key(key)
190 }
191
192 fn set_key<T: CustomProperty + 'static>(value: &(dyn Any + Send + Sync), key: &str, next: Dynamic) -> bool {
193 value.downcast_ref::<T>().is_some_and(|value| value.set_key(key, next))
194 }
195
196 fn contains_key<T: CustomProperty + 'static>(value: &(dyn Any + Send + Sync), key: &str) -> bool {
197 value.downcast_ref::<T>().is_some_and(|value| value.contains_key(key))
198 }
199
200 Self { type_name: std::any::type_name::<T>(), value, get_key: Some(get_key::<T>), set_key: Some(set_key::<T>), contains_key: Some(contains_key::<T>) }
201 }
202
203 pub fn as_any(&self) -> &(dyn Any + Send + Sync) {
204 self.value.as_ref()
205 }
206
207 pub fn custom_type_name(&self) -> &'static str {
208 self.type_name
209 }
210
211 fn ptr_eq(&self, other: &Self) -> bool {
212 Arc::ptr_eq(&self.value, &other.value)
213 }
214
215 fn get_key(&self, key: &str) -> Option<Dynamic> {
216 self.get_key.and_then(|get_key| get_key(self.as_any(), key))
217 }
218
219 fn set_key(&self, key: &str, value: Dynamic) -> bool {
220 self.set_key.is_some_and(|set_key| set_key(self.as_any(), key, value))
221 }
222
223 fn contains_key(&self, key: &str) -> bool {
224 self.contains_key.is_some_and(|contains_key| contains_key(self.as_any(), key))
225 }
226}
227
228impl std::fmt::Debug for CustomValue {
229 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
230 f.debug_struct("CustomValue").field("type_name", &self.type_name).finish()
231 }
232}
233
234#[derive(Debug, Default, Clone)]
235pub enum Dynamic {
236 #[default]
237 Null,
238 Bool(bool),
239 U8(u8),
240 I8(i8),
241 U16(u16),
242 I16(i16),
243 U32(u32),
244 I32(i32), U64(u64),
246 I64(i64),
247 F32(f32), F64(f64),
249 String(SmolStr),
250 StringBuf(String),
251 Bytes(Vec<u8>),
252 VecI8(MyVec<i8>),
253 VecU16(MyVec<u16>),
254 VecI16(MyVec<i16>),
255 VecU32(MyVec<u32>),
256 VecI32(MyVec<i32>),
257 VecF32(MyVec<f32>),
258 VecU64(Vec<u64>),
259 VecI64(Vec<i64>),
260 VecF64(Vec<f64>),
261 List(Arc<RwLock<Vec<Dynamic>>>),
262 Map(Arc<RwLock<BTreeMap<SmolStr, Dynamic>>>),
263 Struct {
264 addr: usize,
265 ty: Type,
266 },
267 Custom(CustomValue),
268 Iter {
269 idx: usize,
270 keys: Vec<SmolStr>,
271 value: Box<Dynamic>,
272 },
273}
274
275unsafe impl Send for Dynamic {}
276unsafe impl Sync for Dynamic {}
277
278impl PartialEq for Dynamic {
279 fn eq(&self, other: &Self) -> bool {
280 match (self, other) {
281 (Self::Null, Self::Null) => true,
282 (Self::Bool(a), Self::Bool(b)) => a == b,
283 (a, b) if a.is_str() && b.is_str() => a.as_str() == b.as_str(),
284 (Self::Bytes(a), Self::Bytes(b)) => a == b,
285 (Self::U8(a), Self::U8(b)) => a == b,
287 (Self::I8(a), Self::I8(b)) => a == b,
288 (Self::U16(a), Self::U16(b)) => a == b,
289 (Self::I16(a), Self::I16(b)) => a == b,
290 (Self::U32(a), Self::U32(b)) => a == b,
291 (Self::I32(a), Self::I32(b)) => a == b,
292 (Self::U64(a), Self::U64(b)) => a == b,
293 (Self::I64(a), Self::I64(b)) => a == b,
294 (a, b) if a.is_int() && b.is_int() => a.as_int() == b.as_int(),
296 (Self::F32(a), Self::F32(b)) => a.to_bits() == b.to_bits(),
298 (Self::F64(a), Self::F64(b)) => a.to_bits() == b.to_bits(),
299 (a, b) if (a.is_f32() || a.is_f64()) && (b.is_f32() || b.is_f64()) => a.as_float() == b.as_float(),
300 (Self::VecI8(a), Self::VecI8(b)) => a.data == b.data,
302 (Self::VecU16(a), Self::VecU16(b)) => a.data == b.data,
303 (Self::VecI16(a), Self::VecI16(b)) => a.data == b.data,
304 (Self::VecU32(a), Self::VecU32(b)) => a.data == b.data,
305 (Self::VecI32(a), Self::VecI32(b)) => a.data == b.data,
306 (Self::VecF32(a), Self::VecF32(b)) => a.data == b.data,
307 (Self::VecU64(a), Self::VecU64(b)) => a == b,
308 (Self::VecI64(a), Self::VecI64(b)) => a == b,
309 (Self::VecF64(a), Self::VecF64(b)) => a == b,
310 (Self::List(a), Self::List(b)) => {
312 let a_guard = a.read().unwrap();
313 let b_guard = b.read().unwrap();
314 if a_guard.len() != b_guard.len() {
315 return false;
316 }
317 a_guard.iter().zip(b_guard.iter()).all(|(x, y)| x == y)
318 }
319 (Self::Map(a), Self::Map(b)) => {
321 let a_guard = a.read().unwrap();
322 let b_guard = b.read().unwrap();
323 if a_guard.len() != b_guard.len() {
324 return false;
325 }
326 for (k, v) in a_guard.iter() {
327 if let Some(other_v) = b_guard.get(k) {
328 if v != other_v {
329 return false;
330 }
331 } else {
332 return false;
333 }
334 }
335 true
336 }
337 (Self::Struct { addr: a_addr, ty: a_ty }, Self::Struct { addr: b_addr, ty: b_ty }) => a_addr == b_addr && a_ty == b_ty,
339 (Self::Custom(a), Self::Custom(b)) => a.ptr_eq(b),
340 _ => false,
341 }
342 }
343}
344
345impl Eq for Dynamic {}
346
347use std::cmp::Ordering;
348
349impl PartialOrd for Dynamic {
350 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
351 Some(self.cmp(other))
352 }
353}
354
355impl Ord for Dynamic {
356 fn cmp(&self, other: &Self) -> Ordering {
357 if self.is_f32() || self.is_f64() || other.is_f32() || other.is_f64() {
358 self.as_float().unwrap_or(0.0).total_cmp(&other.as_float().unwrap_or(0.0))
359 } else if self.is_int() || other.is_int() {
360 self.as_int().unwrap_or(0).cmp(&other.as_int().unwrap_or(0))
361 } else if self.is_uint() || other.is_uint() {
362 self.as_uint().unwrap_or(0).cmp(&other.as_uint().unwrap_or(0))
363 } else if self.is_false() && other.is_true() {
364 Ordering::Less } else if self.is_true() && other.is_false() {
366 Ordering::Greater } else if self.is_null() && other.is_null() {
368 Ordering::Equal
369 } else if self.is_str() && other.is_str() {
370 self.as_str().cmp(other.as_str())
371 } else {
372 Ordering::Equal
373 }
374 }
375}
376
377macro_rules! impl_dynamic_scalar {
378 ($variant:ident, $ty:ty) => {
379 impl From<$ty> for Dynamic {
380 fn from(value: $ty) -> Self {
381 Dynamic::$variant(value)
382 }
383 }
384 };
385}
386
387impl_dynamic_scalar!(Bool, bool);
388
389impl_dynamic_scalar!(I8, i8);
390impl_dynamic_scalar!(U16, u16);
391impl_dynamic_scalar!(I16, i16);
392impl_dynamic_scalar!(U32, u32);
393impl_dynamic_scalar!(I32, i32);
394impl_dynamic_scalar!(F32, f32);
395impl_dynamic_scalar!(I64, i64);
396impl_dynamic_scalar!(U64, u64);
397impl_dynamic_scalar!(F64, f64);
398impl_dynamic_scalar!(String, SmolStr);
399impl From<&str> for Dynamic {
400 fn from(s: &str) -> Self {
401 Dynamic::String(s.into())
402 }
403}
404
405macro_rules! impl_try_from_dynamic_int {
406 ($($target:ty),+ $(,)?) => {
407 $(
408 impl TryFrom<Dynamic> for $target {
409 type Error = DynamicErr;
410 fn try_from(value: Dynamic) -> Result<Self, Self::Error> {
411 match value {
412 Dynamic::F32(v) => Ok(v as $target),
413 Dynamic::F64(v) => Ok(v as $target),
414 Dynamic::String(v) => v.trim().parse::<$target>().or_else(|_| v.trim().parse::<f64>().map(|value| value as $target)).map_err(|_| DynamicErr::TypeMismatch),
415 Dynamic::StringBuf(v) => v.trim().parse::<$target>().or_else(|_| v.trim().parse::<f64>().map(|value| value as $target)).map_err(|_| DynamicErr::TypeMismatch),
416 Dynamic::U8(v) => v.try_into().map_err(|_| DynamicErr::OutOfRange),
417 Dynamic::U16(v) => v.try_into().map_err(|_| DynamicErr::OutOfRange),
418 Dynamic::U32(v) => v.try_into().map_err(|_| DynamicErr::OutOfRange),
419 Dynamic::U64(v) => v.try_into().map_err(|_| DynamicErr::OutOfRange),
420 Dynamic::I8(v) => v.try_into().map_err(|_| DynamicErr::OutOfRange),
421 Dynamic::I16(v) => v.try_into().map_err(|_| DynamicErr::OutOfRange),
422 Dynamic::I32(v) => v.try_into().map_err(|_| DynamicErr::OutOfRange),
423 Dynamic::I64(v) => v.try_into().map_err(|_| DynamicErr::OutOfRange),
424 _ => Err(DynamicErr::TypeMismatch),
425 }
426 }
427 }
428 )+
429 };
430}
431impl_try_from_dynamic_int!(u8, u16, u32, u64, i8, i16, i32, i64);
432
433impl TryFrom<Dynamic> for f64 {
434 type Error = DynamicErr;
435 fn try_from(value: Dynamic) -> Result<Self, Self::Error> {
436 match value {
437 Dynamic::F32(v) => Ok(v as f64),
438 Dynamic::F64(v) => Ok(v),
439 Dynamic::U8(v) => Ok(v as f64),
440 Dynamic::U16(v) => Ok(v as f64),
441 Dynamic::U32(v) => Ok(v as f64),
442 Dynamic::U64(v) => Ok(v as f64),
443 Dynamic::I8(v) => Ok(v as f64),
444 Dynamic::I16(v) => Ok(v as f64),
445 Dynamic::I32(v) => Ok(v as f64),
446 Dynamic::I64(v) => Ok(v as f64),
447 Dynamic::String(v) => v.trim().parse::<f64>().map_err(|_| DynamicErr::TypeMismatch),
448 Dynamic::StringBuf(v) => v.trim().parse::<f64>().map_err(|_| DynamicErr::TypeMismatch),
449 _ => Err(DynamicErr::TypeMismatch),
450 }
451 }
452}
453
454impl TryFrom<Dynamic> for f32 {
455 type Error = DynamicErr;
456 fn try_from(value: Dynamic) -> Result<Self, Self::Error> {
457 match value {
458 Dynamic::F32(v) => Ok(v),
459 Dynamic::F64(v) => Ok(v as f32),
460 Dynamic::U8(v) => Ok(v as f32),
461 Dynamic::U16(v) => Ok(v as f32),
462 Dynamic::U32(v) => Ok(v as f32),
463 Dynamic::U64(v) => Ok(v as f32),
464 Dynamic::I8(v) => Ok(v as f32),
465 Dynamic::I16(v) => Ok(v as f32),
466 Dynamic::I32(v) => Ok(v as f32),
467 Dynamic::I64(v) => Ok(v as f32),
468 Dynamic::String(v) => v.trim().parse::<f32>().map_err(|_| DynamicErr::TypeMismatch),
469 Dynamic::StringBuf(v) => v.trim().parse::<f32>().map_err(|_| DynamicErr::TypeMismatch),
470 _ => Err(DynamicErr::TypeMismatch),
471 }
472 }
473}
474
475impl TryFrom<Dynamic> for bool {
476 type Error = DynamicErr;
477 fn try_from(value: Dynamic) -> Result<Self, Self::Error> {
478 match value {
479 Dynamic::Bool(v) => Ok(v),
480 Dynamic::U8(v) => Ok(v != 0),
481 Dynamic::U16(v) => Ok(v != 0),
482 Dynamic::U32(v) => Ok(v != 0),
483 Dynamic::U64(v) => Ok(v != 0),
484 Dynamic::I8(v) => Ok(v != 0),
485 Dynamic::I16(v) => Ok(v != 0),
486 Dynamic::I32(v) => Ok(v != 0),
487 Dynamic::I64(v) => Ok(v != 0),
488 _ => Err(DynamicErr::TypeMismatch),
489 }
490 }
491}
492
493impl TryFrom<Dynamic> for SmolStr {
494 type Error = DynamicErr;
495 fn try_from(value: Dynamic) -> Result<Self, Self::Error> {
496 match value {
497 Dynamic::String(s) => Ok(s),
498 Dynamic::StringBuf(s) => Ok(s.into()),
499 _ => Err(DynamicErr::TypeMismatch),
500 }
501 }
502}
503
504macro_rules! impl_dynamic_vec_from_slice {
505 ($variant:ident, $ty:ty) => {
506 impl From<&[$ty]> for Dynamic {
507 fn from(vec: &[$ty]) -> Self {
508 Dynamic::$variant(MyVec::from(vec))
509 }
510 }
511
512 impl<const N: usize> From<[$ty; N]> for Dynamic {
513 fn from(vec: [$ty; N]) -> Self {
514 Dynamic::$variant(MyVec::from(vec))
515 }
516 }
517 };
518}
519
520impl_dynamic_vec_from_slice!(VecI8, i8);
521impl_dynamic_vec_from_slice!(VecU16, u16);
522impl_dynamic_vec_from_slice!(VecI16, i16);
523impl_dynamic_vec_from_slice!(VecU32, u32);
524impl_dynamic_vec_from_slice!(VecI32, i32);
525impl_dynamic_vec_from_slice!(VecF32, f32);
526
527impl From<&[u8]> for Dynamic {
528 fn from(vec: &[u8]) -> Self {
529 Dynamic::Bytes(vec.to_vec())
530 }
531}
532
533impl From<Vec<u8>> for Dynamic {
534 fn from(vec: Vec<u8>) -> Self {
535 Dynamic::Bytes(vec)
536 }
537}
538
539impl From<&[u64]> for Dynamic {
540 fn from(vec: &[u64]) -> Self {
541 Dynamic::VecU64(vec.to_vec())
542 }
543}
544
545impl<const N: usize> From<[u64; N]> for Dynamic {
546 fn from(vec: [u64; N]) -> Self {
547 Dynamic::VecU64(vec.to_vec())
548 }
549}
550
551impl From<&[i64]> for Dynamic {
552 fn from(vec: &[i64]) -> Self {
553 Dynamic::VecI64(vec.to_vec())
554 }
555}
556impl<const N: usize> From<[i64; N]> for Dynamic {
557 fn from(vec: [i64; N]) -> Self {
558 Dynamic::VecI64(vec.to_vec())
559 }
560}
561
562impl From<&[f64]> for Dynamic {
563 fn from(vec: &[f64]) -> Self {
564 Dynamic::VecF64(vec.to_vec())
565 }
566}
567impl<const N: usize> From<[f64; N]> for Dynamic {
568 fn from(vec: [f64; N]) -> Self {
569 Dynamic::VecF64(vec.to_vec())
570 }
571}
572
573impl<T: Into<Dynamic>> From<Vec<T>> for Dynamic {
574 fn from(vec: Vec<T>) -> Self {
575 let vec = vec.into_iter().map(|v| v.into()).collect();
576 Dynamic::List(Arc::new(RwLock::new(vec)))
577 }
578}
579
580impl From<String> for Dynamic {
581 fn from(s: String) -> Self {
582 Dynamic::String(s.into())
583 }
584}
585
586impl ToString for Dynamic {
587 fn to_string(&self) -> String {
588 match self {
589 Self::Null => "()".into(),
590 Self::Bool(b) => {
591 if *b {
592 "true".into()
593 } else {
594 "false".into()
595 }
596 }
597 Self::U8(u) => u.to_string(),
598 Self::U16(u) => u.to_string(),
599 Self::U32(u) => u.to_string(),
600 Self::U64(u) => u.to_string(),
601 Self::I8(u) => u.to_string(),
602 Self::I16(u) => u.to_string(),
603 Self::I32(u) => u.to_string(),
604 Self::I64(u) => u.to_string(),
605 Self::F32(u) => u.to_string(),
606 Self::F64(u) => u.to_string(),
607 Self::String(s) => s.to_string(),
608 Self::StringBuf(s) => s.clone(),
609 _ => {
610 let mut buf = String::new();
611 self.to_json(&mut buf);
612 if buf.is_empty() { format!("{:?}", self) } else { buf }
613 }
614 }
615 }
616}
617
618use anyhow::Result;
619impl Dynamic {
620 pub fn custom<T>(value: T) -> Self
621 where
622 T: Any + Send + Sync + 'static,
623 {
624 Self::Custom(CustomValue::new(value))
625 }
626
627 pub fn custom_arc<T>(value: Arc<T>) -> Self
628 where
629 T: Any + Send + Sync + 'static,
630 {
631 Self::Custom(CustomValue::from_arc(value))
632 }
633
634 pub fn custom_with_properties<T>(value: T) -> Self
635 where
636 T: CustomProperty + 'static,
637 {
638 Self::Custom(CustomValue::new_with_properties(value))
639 }
640
641 pub fn custom_property_arc<T>(value: Arc<T>) -> Self
642 where
643 T: CustomProperty + 'static,
644 {
645 Self::Custom(CustomValue::from_property_arc(value))
646 }
647
648 pub fn is_custom(&self) -> bool {
649 matches!(self, Self::Custom(_))
650 }
651
652 pub fn custom_type_name(&self) -> Option<&'static str> {
653 if let Self::Custom(value) = self { Some(value.custom_type_name()) } else { None }
654 }
655
656 pub fn as_custom<T>(&self) -> Option<&T>
657 where
658 T: Any + Send + Sync,
659 {
660 if let Self::Custom(value) = self { value.as_any().downcast_ref::<T>() } else { None }
661 }
662
663 pub fn deep_clone(&self) -> Self {
664 match self {
665 Self::Map(m) => {
666 let m = m.read().unwrap().iter().map(|(k, v)| (k.clone(), v.deep_clone())).collect();
667 Self::map(m)
668 }
669 Self::List(l) => {
670 let l = l.read().unwrap().iter().map(|item| item.deep_clone()).collect();
671 Self::list(l)
672 }
673 Self::Struct { addr, ty } => Self::Struct { addr: *addr, ty: ty.clone() },
674 _ => self.clone(),
675 }
676 }
677
678 pub fn add(&mut self, val: i64) -> Option<i64> {
679 match self {
681 Self::U8(u) => {
682 let v = (*u as i64) + val;
683 *u = v as u8;
684 Some(v)
685 }
686 Self::U16(u) => {
687 let v = (*u as i64) + val;
688 *u = v as u16;
689 Some(v)
690 }
691 Self::U32(u) => {
692 let v = (*u as i64) + val;
693 *u = v as u32;
694 Some(v)
695 }
696 Self::U64(u) => {
697 let v = (*u as i64) + val;
698 *u = v as u64;
699 Some(v)
700 }
701 Self::I8(i) => {
702 let v = (*i as i64) + val;
703 *i = v as i8;
704 Some(v)
705 }
706 Self::I16(i) => {
707 let v = (*i as i64) + val;
708 *i = v as i16;
709 Some(v)
710 }
711 Self::I32(i) => {
712 let v = (*i as i64) + val;
713 *i = v as i32;
714 Some(v)
715 }
716 Self::I64(i) => {
717 let v = (*i as i64) + val;
718 *i = v;
719 Some(v)
720 }
721 _ => None,
722 }
723 }
724
725 pub fn is_vec(&self) -> bool {
726 use Dynamic::*;
727 match self {
728 VecI8(_) | VecU16(_) | Self::VecI16(_) | VecU32(_) | VecI32(_) | VecF32(_) | VecU64(_) | VecI64(_) | VecF64(_) => true,
729 _ => false,
730 }
731 }
732
733 pub fn as_bytes(&self) -> Option<&[u8]> {
734 match self {
735 Self::Bytes(b) => Some(b.as_slice()),
736 _ => None,
737 }
738 }
739
740 pub fn as_str(&self) -> &str {
741 match self {
742 Dynamic::String(s) => s.as_str(),
743 Dynamic::StringBuf(s) => s.as_str(),
744 _ => "",
745 }
746 }
747
748 pub fn is_native(&self) -> bool {
749 if self.is_f64() || self.is_f32() || self.is_int() || self.is_true() || self.is_false() { true } else { false }
750 }
751
752 pub fn from_utf8(buf: &[u8]) -> Result<Self> {
753 Ok(Dynamic::from(SmolStr::new(std::str::from_utf8(buf)?)))
754 }
755
756 pub fn append(&self, other: Self) {
757 match (self, other) {
758 (Self::List(left), rhs) => {
759 if let Self::List(right) = rhs {
760 left.write().unwrap().append(&mut right.write().unwrap());
761 } else {
762 left.write().unwrap().push(rhs);
763 }
764 }
765 (Self::Map(left), Self::Map(right)) => {
766 left.write().unwrap().append(&mut right.write().unwrap());
767 }
768 (_, _) => {}
769 }
770 }
771
772 pub fn into_vec<T: TryFrom<Self> + 'static>(self) -> Option<Vec<T>> {
773 if std::any::TypeId::of::<T>() == std::any::TypeId::of::<Dynamic>() {
774 match self {
775 Dynamic::List(list) => {
776 match Arc::try_unwrap(list) {
777 Ok(vec) => vec.into_inner().map(|v| unsafe { mem::transmute::<Vec<Dynamic>, Vec<T>>(v) }).ok(), Err(_) => None, }
780 }
781 _ => {
782 let mut vec = Vec::with_capacity(self.len());
783 for idx in 0..self.len() {
784 if let Some(item) = self.get_idx(idx) {
785 vec.push(item);
786 }
787 }
788 Some(unsafe { mem::transmute(vec) })
789 }
790 }
791 } else {
792 match self {
793 Dynamic::List(list) => Arc::try_unwrap(list).ok().and_then(|l| l.into_inner().map(|l| l.into_iter().filter_map(|l| T::try_from(l).ok()).collect()).ok()),
794 Dynamic::Bytes(vec) => {
795 if std::any::TypeId::of::<T>() == std::any::TypeId::of::<u8>() {
796 let bytes_vec: Vec<u8> = Vec::from(vec);
797 Some(unsafe { mem::transmute(bytes_vec) })
798 } else {
799 None
800 }
801 }
802 Dynamic::VecI8(vec) => {
803 if std::any::TypeId::of::<T>() == std::any::TypeId::of::<i8>() {
804 let vec_i8: Vec<i8> = Vec::from(vec);
805 Some(unsafe { mem::transmute(vec_i8) })
806 } else {
807 None
808 }
809 }
810 Dynamic::VecU16(vec) => {
811 if std::any::TypeId::of::<T>() == std::any::TypeId::of::<u16>() {
812 let vec_u16: Vec<u16> = Vec::from(vec);
813 Some(unsafe { mem::transmute(vec_u16) })
814 } else {
815 None
816 }
817 }
818 Dynamic::VecI16(vec) => {
819 if std::any::TypeId::of::<T>() == std::any::TypeId::of::<i16>() {
820 let vec_i16: Vec<i16> = Vec::from(vec);
821 Some(unsafe { mem::transmute(vec_i16) })
822 } else {
823 None
824 }
825 }
826 Dynamic::VecU32(vec) => {
827 if std::any::TypeId::of::<T>() == std::any::TypeId::of::<u32>() {
828 let vec_u32: Vec<u32> = Vec::from(vec);
829 Some(unsafe { mem::transmute(vec_u32) })
830 } else {
831 None
832 }
833 }
834 Dynamic::VecI32(vec) => {
835 if std::any::TypeId::of::<T>() == std::any::TypeId::of::<i32>() {
836 let vec_i32: Vec<i32> = Vec::from(vec);
837 Some(unsafe { mem::transmute(vec_i32) })
838 } else {
839 None
840 }
841 }
842 Dynamic::VecF32(vec) => {
843 if std::any::TypeId::of::<T>() == std::any::TypeId::of::<f32>() {
844 let vec_f32: Vec<f32> = Vec::from(vec);
845 Some(unsafe { mem::transmute(vec_f32) })
846 } else {
847 None
848 }
849 }
850 Dynamic::VecU64(vec) => {
851 if std::any::TypeId::of::<T>() == std::any::TypeId::of::<u64>() {
852 Some(unsafe { mem::transmute(vec) })
853 } else {
854 None
855 }
856 }
857 Dynamic::VecI64(vec) => {
858 if std::any::TypeId::of::<T>() == std::any::TypeId::of::<i64>() {
859 Some(unsafe { mem::transmute(vec) })
860 } else {
861 None
862 }
863 }
864 Dynamic::VecF64(vec) => {
865 if std::any::TypeId::of::<T>() == std::any::TypeId::of::<f64>() {
866 Some(unsafe { mem::transmute(vec) })
867 } else {
868 None
869 }
870 }
871 _ => None,
872 }
873 }
874 }
875
876 pub fn push<T: Into<Dynamic> + 'static>(&mut self, value: T) -> bool {
877 match self {
878 Self::List(list) => {
879 list.write().unwrap().push(value.into());
880 true
881 }
882 Self::Bytes(vec) => {
883 if std::any::TypeId::of::<T>() == std::any::TypeId::of::<u8>() {
884 vec.push(unsafe { mem::transmute_copy(&value) });
885 true
886 } else {
887 false
888 }
889 }
890 Self::VecI8(vec) => {
891 if std::any::TypeId::of::<T>() == std::any::TypeId::of::<i8>() {
892 vec.push(unsafe { mem::transmute_copy(&value) });
893 true
894 } else {
895 false
896 }
897 }
898 Self::VecU16(vec) => {
899 if std::any::TypeId::of::<T>() == std::any::TypeId::of::<u16>() {
900 vec.push(unsafe { mem::transmute_copy(&value) });
901 true
902 } else {
903 false
904 }
905 }
906 Self::VecI16(vec) => {
907 if std::any::TypeId::of::<T>() == std::any::TypeId::of::<i16>() {
908 vec.push(unsafe { mem::transmute_copy(&value) });
909 true
910 } else {
911 false
912 }
913 }
914 Self::VecU32(vec) => {
915 if std::any::TypeId::of::<T>() == std::any::TypeId::of::<u32>() {
916 vec.push(unsafe { mem::transmute_copy(&value) });
917 true
918 } else {
919 false
920 }
921 }
922 Self::VecI32(vec) => {
923 if std::any::TypeId::of::<T>() == std::any::TypeId::of::<i32>() {
924 vec.push(unsafe { mem::transmute_copy(&value) });
925 true
926 } else {
927 false
928 }
929 }
930 Self::VecF32(vec) => {
931 if std::any::TypeId::of::<T>() == std::any::TypeId::of::<f32>() {
932 vec.push(unsafe { mem::transmute_copy(&value) });
933 true
934 } else {
935 false
936 }
937 }
938 Self::VecU64(vec) => {
939 if std::any::TypeId::of::<T>() == std::any::TypeId::of::<u64>() {
940 vec.push(unsafe { mem::transmute_copy(&value) });
941 true
942 } else {
943 false
944 }
945 }
946 Self::VecI64(vec) => {
947 if std::any::TypeId::of::<T>() == std::any::TypeId::of::<i64>() {
948 vec.push(unsafe { mem::transmute_copy(&value) });
949 true
950 } else {
951 false
952 }
953 }
954 Self::VecF64(vec) => {
955 if std::any::TypeId::of::<T>() == std::any::TypeId::of::<f64>() {
956 vec.push(unsafe { mem::transmute_copy(&value) });
957 true
958 } else {
959 false
960 }
961 }
962 _ => false,
963 }
964 }
965
966 pub fn push_dynamic(&mut self, value: Dynamic) -> bool {
967 match self {
968 Self::List(list) => {
969 list.write().unwrap().push(value);
970 true
971 }
972 Self::Bytes(vec) => value.try_into().map(|value| vec.push(value)).is_ok(),
973 Self::VecI8(vec) => value.try_into().map(|value| vec.push(value)).is_ok(),
974 Self::VecU16(vec) => value.try_into().map(|value| vec.push(value)).is_ok(),
975 Self::VecI16(vec) => value.try_into().map(|value| vec.push(value)).is_ok(),
976 Self::VecU32(vec) => value.try_into().map(|value| vec.push(value)).is_ok(),
977 Self::VecI32(vec) => value.try_into().map(|value| vec.push(value)).is_ok(),
978 Self::VecF32(vec) => value.try_into().map(|value| vec.push(value)).is_ok(),
979 Self::VecU64(vec) => value.try_into().map(|value| vec.push(value)).is_ok(),
980 Self::VecI64(vec) => value.try_into().map(|value| vec.push(value)).is_ok(),
981 Self::VecF64(vec) => value.try_into().map(|value| vec.push(value)).is_ok(),
982 _ => false,
983 }
984 }
985
986 pub fn pop(&mut self) -> Option<Dynamic> {
987 match self {
988 Self::List(list) => list.write().unwrap().pop(),
989 Self::Bytes(vec) => vec.pop().map(Dynamic::U8),
990 Self::VecI8(vec) => vec.pop().map(Dynamic::I8),
991 Self::VecU16(vec) => vec.pop().map(Dynamic::U16),
992 Self::VecI16(vec) => vec.pop().map(Dynamic::I16),
993 Self::VecU32(vec) => vec.pop().map(Dynamic::U32),
994 Self::VecI32(vec) => vec.pop().map(Dynamic::I32),
995 Self::VecF32(vec) => vec.pop().map(Dynamic::F32),
996 Self::VecU64(vec) => vec.pop().map(Dynamic::U64),
997 Self::VecI64(vec) => vec.pop().map(Dynamic::I64),
998 Self::VecF64(vec) => vec.pop().map(Dynamic::F64),
999 _ => None,
1000 }
1001 }
1002
1003 pub fn is_null(&self) -> bool {
1004 match self {
1005 Self::Null => true,
1006 _ => false,
1007 }
1008 }
1009
1010 pub fn as_bool(&self) -> Option<bool> {
1011 if let Self::Bool(b) = self { Some(*b) } else { None }
1012 }
1013
1014 pub fn is_true(&self) -> bool {
1015 match self {
1016 Self::Bool(b) => *b,
1017 _ => false,
1018 }
1019 }
1020
1021 pub fn is_false(&self) -> bool {
1022 match self {
1023 Self::Bool(b) => !*b,
1024 _ => false,
1025 }
1026 }
1027
1028 pub fn is_int(&self) -> bool {
1029 match self {
1030 Self::I8(_) | Self::I16(_) | Self::I32(_) | Self::I64(_) => true,
1031 Self::U8(_) | Self::U16(_) | Self::U32(_) | Self::U64(_) => true,
1032 _ => false,
1033 }
1034 }
1035
1036 pub fn as_int(&self) -> Option<i64> {
1037 match self {
1038 Self::U8(u) => Some(*u as i64),
1039 Self::U16(u) => Some(*u as i64),
1040 Self::U32(u) => Some(*u as i64),
1041 Self::U64(u) => i64::try_from(*u).ok(),
1042 Self::I8(i) => Some(*i as i64),
1043 Self::I16(i) => Some(*i as i64),
1044 Self::I32(i) => Some(*i as i64),
1045 Self::I64(i) => Some(*i as i64),
1046 _ => None,
1047 }
1048 }
1049
1050 pub fn is_uint(&self) -> bool {
1051 match self {
1052 Self::U8(_) | Self::U16(_) | Self::U32(_) | Self::U64(_) => true,
1053 _ => false,
1054 }
1055 }
1056
1057 pub fn as_uint(&self) -> Option<u64> {
1058 match self {
1059 Self::U8(i) => Some(*i as u64),
1060 Self::U16(i) => Some(*i as u64),
1061 Self::U32(i) => Some(*i as u64),
1062 Self::U64(i) => Some(*i as u64),
1063 _ => None,
1064 }
1065 }
1066
1067 pub fn is_f32(&self) -> bool {
1068 if let Self::F32(_) = self { true } else { false }
1069 }
1070
1071 pub fn is_str(&self) -> bool {
1072 if let Self::String(_) | Self::StringBuf(_) = self { true } else { false }
1073 }
1074
1075 pub fn is_f64(&self) -> bool {
1076 if let Self::F64(_) = self { true } else { false }
1077 }
1078
1079 pub fn as_float(&self) -> Option<f64> {
1080 match self {
1081 Self::U8(u) => Some(*u as f64),
1082 Self::U16(u) => Some(*u as f64),
1083 Self::U32(u) => Some(*u as f64),
1084 Self::U64(u) => Some(*u as f64),
1085 Self::I8(i) => Some(*i as f64),
1086 Self::I16(i) => Some(*i as f64),
1087 Self::I32(i) => Some(*i as f64),
1088 Self::I64(i) => Some(*i as f64),
1089 Self::F32(f) => Some(*f as f64),
1090 Self::F64(f) => Some(*f),
1091 _ => None,
1092 }
1093 }
1094
1095 pub fn is_signed(&self) -> bool {
1096 match self {
1097 Self::I8(_) | Self::I16(_) | Self::I32(_) | Self::I64(_) | Self::F32(_) | Self::F64(_) => true,
1098 _ => false,
1099 }
1100 }
1101
1102 pub fn size_of(&self) -> usize {
1103 match self {
1104 Self::I8(_) | Self::U8(_) => 1,
1105 Self::I16(_) | Self::U16(_) => 2,
1106 Self::I32(_) | Self::U32(_) | Self::F32(_) => 4,
1107 Self::I64(_) | Self::U64(_) | Self::F64(_) => 8,
1108 Self::String(s) => s.len(),
1109 Self::StringBuf(s) => s.len(),
1110 Self::Bytes(bytes) => bytes.len(),
1111 Self::VecI8(vec) => vec.len(),
1112 Self::VecU16(vec) => vec.len(),
1113 Self::VecI16(vec) => vec.len(),
1114 Self::VecU32(vec) => vec.len(),
1115 Self::VecI32(vec) => vec.len(),
1116 Self::VecF32(vec) => vec.len(),
1117 Self::VecI64(vec) => vec.len(),
1118 Self::VecU64(vec) => vec.len(),
1119 Self::VecF64(vec) => vec.len(),
1120 Self::List(list) => list.read().unwrap().len(),
1121 Self::Map(obj) => obj.read().unwrap().len(),
1122 Self::Struct { ty, .. } => ty.len(),
1123 Self::Custom(_) => 0,
1124 _ => 1,
1125 }
1126 }
1127
1128 pub fn list(v: Vec<Dynamic>) -> Self {
1129 Dynamic::List(Arc::new(RwLock::new(v)))
1130 }
1131
1132 pub fn is_list(&self) -> bool {
1133 match self {
1134 Self::List(_) | Self::VecF32(_) | Self::VecF64(_) | Self::VecI16(_) | Self::VecI32(_) | Self::VecI64(_) | Self::VecU16(_) | Self::VecU32(_) | Self::VecU64(_) => true,
1135 _ => false,
1136 }
1137 }
1138
1139 pub fn split(self, tag: &str) -> Self {
1140 match self {
1141 Self::String(s) => Self::list(s.split(tag).map(|p| Dynamic::from(p)).collect()),
1142 Self::StringBuf(s) => Self::list(s.split(tag).map(|p| Dynamic::from(p)).collect()),
1143 _ => self,
1144 }
1145 }
1146
1147 pub fn map(m: BTreeMap<SmolStr, Dynamic>) -> Self {
1148 Dynamic::Map(Arc::new(RwLock::new(m)))
1149 }
1150
1151 pub fn into_map(self) -> Option<BTreeMap<SmolStr, Dynamic>> {
1152 if let Self::Map(map) = self { Arc::try_unwrap(map).ok().and_then(|m| m.into_inner().ok()) } else { None }
1153 }
1154
1155 pub fn is_map(&self) -> bool {
1156 if let Self::Map(_) | Self::Struct { .. } = self { true } else { false }
1157 }
1158
1159 pub fn insert<K: Into<SmolStr>, T: Into<Self>>(&self, key: K, value: T) {
1160 match self {
1161 Self::Map(obj) => {
1162 obj.write().unwrap().insert(key.into(), value.into());
1163 }
1164 _ => {}
1165 }
1166 }
1167
1168 pub fn len(&self) -> usize {
1169 match self {
1170 Self::String(value) => value.len(),
1171 Self::StringBuf(value) => value.len(),
1172 Self::List(list) => list.read().unwrap().len(),
1173 Self::Bytes(bytes) => bytes.len(),
1174 Self::VecI8(vec) => vec.len(),
1175 Self::VecU16(vec) => vec.len(),
1176 Self::VecI16(vec) => vec.len(),
1177 Self::VecU32(vec) => vec.len(),
1178 Self::VecI32(vec) => vec.len(),
1179 Self::VecF32(vec) => vec.len(),
1180 Self::VecI64(vec) => vec.len(),
1181 Self::VecU64(vec) => vec.len(),
1182 Self::VecF64(vec) => vec.len(),
1183 Self::Map(obj) => obj.read().unwrap().len(),
1184 Self::Custom(_) => 0,
1185 _ => 0,
1186 }
1187 }
1188
1189 pub fn keys(&self) -> Vec<SmolStr> {
1190 if let Self::Map(map) = self {
1191 map.read().unwrap().keys().cloned().collect()
1192 } else if let Self::Struct { ty: Type::Struct { params: _, fields }, .. } = self {
1193 fields.iter().map(|(name, _)| name.clone()).collect()
1194 } else {
1195 Vec::new()
1196 }
1197 }
1198
1199 pub fn contains(&self, key: &str) -> bool {
1200 if let Self::Map(map) = self {
1201 map.read().unwrap().get(key).is_some_and(|value| !value.is_null())
1202 } else if let Self::Struct { ty, .. } = self {
1203 ty.get_field(key).is_ok()
1204 } else if let Self::List(list) = self {
1205 list.read().unwrap().iter().find(|l| l.as_str() == key).is_some()
1206 } else if let Self::String(s) = self {
1207 s.contains(key)
1208 } else if let Self::StringBuf(s) = self {
1209 s.contains(key)
1210 } else if let Self::Custom(value) = self {
1211 value.contains_key(key)
1212 } else {
1213 false
1214 }
1215 }
1216
1217 pub fn starts_with(&self, prefix: &str) -> bool {
1218 if let Self::String(s) = self {
1219 s.starts_with(prefix)
1220 } else if let Self::StringBuf(s) = self {
1221 s.starts_with(prefix)
1222 } else {
1223 false
1224 }
1225 }
1226
1227 pub fn get_dynamic(&self, key: &str) -> Option<Dynamic> {
1228 if let Self::Map(map) = self {
1229 map.read().unwrap().get(key).cloned()
1230 } else if let Self::Struct { addr, ty } = self {
1231 let (idx, field_ty) = ty.get_field(key).ok()?;
1232 Self::read_struct_field(*addr, idx, field_ty, ty)
1233 } else if let Self::Custom(value) = self {
1234 value.get_key(key)
1235 } else {
1236 None
1237 }
1238 }
1239
1240 pub fn set_dynamic(&self, key: SmolStr, value: impl Into<Dynamic>) {
1241 if let Self::Map(map) = self {
1242 map.write().unwrap().insert(key, value.into());
1243 } else if let Self::Struct { addr, ty } = self
1244 && let Ok((idx, field_ty)) = ty.get_field(key.as_str())
1245 {
1246 Self::write_struct_field(*addr, idx, field_ty, ty, value.into());
1247 } else if let Self::Custom(custom) = self {
1248 custom.set_key(key.as_str(), value.into());
1249 }
1250 }
1251
1252 fn field_addr(addr: usize, idx: usize, struct_ty: &Type) -> Option<usize> {
1253 struct_ty.field_offset(idx).map(|offset| addr + offset as usize)
1254 }
1255
1256 fn read_dynamic_ptr(addr: usize) -> Option<Dynamic> {
1257 let ptr = unsafe { std::ptr::read_unaligned(addr as *const usize) };
1258 if ptr == 0 { None } else { Some(unsafe { (&*(ptr as *const Dynamic)).clone() }) }
1259 }
1260
1261 fn write_dynamic_ptr(addr: usize, value: Dynamic) {
1262 let ptr = Box::into_raw(Box::new(value)) as usize;
1263 unsafe {
1264 std::ptr::write_unaligned(addr as *mut usize, ptr);
1265 }
1266 }
1267
1268 fn read_struct_field(addr: usize, idx: usize, field_ty: &Type, struct_ty: &Type) -> Option<Dynamic> {
1269 let field_addr = Self::field_addr(addr, idx, struct_ty)?;
1270 match field_ty {
1271 Type::Bool => Some(Dynamic::Bool(unsafe { std::ptr::read_unaligned(field_addr as *const u8) } != 0)),
1272 Type::I8 => Some(Dynamic::I8(unsafe { std::ptr::read_unaligned(field_addr as *const i8) })),
1273 Type::U8 => Some(Dynamic::U8(unsafe { std::ptr::read_unaligned(field_addr as *const u8) })),
1274 Type::I16 => Some(Dynamic::I16(unsafe { std::ptr::read_unaligned(field_addr as *const i16) })),
1275 Type::U16 => Some(Dynamic::U16(unsafe { std::ptr::read_unaligned(field_addr as *const u16) })),
1276 Type::I32 => Some(Dynamic::I32(unsafe { std::ptr::read_unaligned(field_addr as *const i32) })),
1277 Type::U32 => Some(Dynamic::U32(unsafe { std::ptr::read_unaligned(field_addr as *const u32) })),
1278 Type::I64 => Some(Dynamic::I64(unsafe { std::ptr::read_unaligned(field_addr as *const i64) })),
1279 Type::U64 => Some(Dynamic::U64(unsafe { std::ptr::read_unaligned(field_addr as *const u64) })),
1280 Type::F32 => Some(Dynamic::F32(unsafe { std::ptr::read_unaligned(field_addr as *const f32) })),
1281 Type::F64 => Some(Dynamic::F64(unsafe { std::ptr::read_unaligned(field_addr as *const f64) })),
1282 Type::Struct { .. } => {
1283 let ptr = unsafe { std::ptr::read_unaligned(field_addr as *const usize) };
1284 Some(Dynamic::Struct { addr: ptr, ty: field_ty.clone() })
1285 }
1286 _ => Self::read_dynamic_ptr(field_addr),
1287 }
1288 }
1289
1290 fn write_struct_field(addr: usize, idx: usize, field_ty: &Type, struct_ty: &Type, value: Dynamic) {
1291 let Some(field_addr) = Self::field_addr(addr, idx, struct_ty) else {
1292 return;
1293 };
1294 match field_ty {
1295 Type::Bool => unsafe {
1296 std::ptr::write_unaligned(field_addr as *mut u8, if value.is_true() { 1 } else { 0 });
1297 },
1298 Type::I8 => unsafe {
1299 std::ptr::write_unaligned(field_addr as *mut i8, value.try_into().unwrap_or_default());
1300 },
1301 Type::U8 => unsafe {
1302 std::ptr::write_unaligned(field_addr as *mut u8, value.try_into().unwrap_or_default());
1303 },
1304 Type::I16 => unsafe {
1305 std::ptr::write_unaligned(field_addr as *mut i16, value.try_into().unwrap_or_default());
1306 },
1307 Type::U16 => unsafe {
1308 std::ptr::write_unaligned(field_addr as *mut u16, value.try_into().unwrap_or_default());
1309 },
1310 Type::I32 => unsafe {
1311 std::ptr::write_unaligned(field_addr as *mut i32, value.try_into().unwrap_or_default());
1312 },
1313 Type::U32 => unsafe {
1314 std::ptr::write_unaligned(field_addr as *mut u32, value.try_into().unwrap_or_default());
1315 },
1316 Type::I64 => unsafe {
1317 std::ptr::write_unaligned(field_addr as *mut i64, value.try_into().unwrap_or_default());
1318 },
1319 Type::U64 => unsafe {
1320 std::ptr::write_unaligned(field_addr as *mut u64, value.try_into().unwrap_or_default());
1321 },
1322 Type::F32 => unsafe {
1323 std::ptr::write_unaligned(field_addr as *mut f32, f32::try_from(value).unwrap_or_default());
1324 },
1325 Type::F64 => unsafe {
1326 std::ptr::write_unaligned(field_addr as *mut f64, f64::try_from(value).unwrap_or_default());
1327 },
1328 Type::Struct { .. } => {
1329 if let Dynamic::Struct { addr, ty: _ } = value {
1330 unsafe {
1331 std::ptr::write_unaligned(field_addr as *mut usize, addr);
1332 }
1333 }
1334 }
1335 _ => Self::write_dynamic_ptr(field_addr, value),
1336 }
1337 }
1338
1339 pub fn remove_dynamic(&self, key: &str) -> Option<Dynamic> {
1340 if let Self::Map(map) = self { map.write().unwrap().remove(key) } else { None }
1341 }
1342
1343 pub fn get_idx(&self, idx: usize) -> Option<Self> {
1344 match self {
1345 Self::List(list) => list.read().unwrap().get(idx).cloned(),
1346 Self::VecI8(vec) => vec.get(idx).map(Self::I8),
1347 Self::VecU16(vec) => vec.get(idx).map(Self::U16),
1348 Self::VecI16(vec) => vec.get(idx).map(Self::I16),
1349 Self::VecU32(vec) => vec.get(idx).map(Self::U32),
1350 Self::VecI32(vec) => vec.get(idx).map(Self::I32),
1351 Self::VecF32(vec) => vec.get(idx).map(Self::F32),
1352 Self::VecI64(vec) => vec.get(idx).cloned().map(Self::I64),
1353 Self::VecU64(vec) => vec.get(idx).cloned().map(Self::U64),
1354 Self::VecF64(vec) => vec.get(idx).cloned().map(Self::F64),
1355 Self::Struct { addr, ty } => {
1356 if let Type::Struct { params: _, fields } = ty {
1357 fields.get(idx).and_then(|(_, field_ty)| Self::read_struct_field(*addr, idx, field_ty, ty))
1358 } else {
1359 None
1360 }
1361 }
1362 _ => None,
1363 }
1364 }
1365
1366 pub fn into_iter(self) -> Self {
1367 if self.is_map() {
1368 let keys = self.keys();
1369 Self::Iter { idx: 0, keys, value: Box::new(self) }
1370 } else {
1371 Self::Iter { idx: 0, keys: Vec::new(), value: Box::new(self) }
1372 }
1373 }
1374
1375 pub fn next(&mut self) -> Option<Self> {
1376 if let Self::Iter { idx, keys, value } = self {
1377 if !keys.is_empty() {
1378 if *idx < keys.len() {
1379 let k = keys[*idx].clone();
1380 let v = value.get_dynamic(k.as_str()).unwrap();
1381 *idx += 1;
1382 return Some(v);
1383 }
1384 } else {
1385 if let Some(v) = value.get_idx(*idx) {
1386 *idx += 1;
1387 return Some(v);
1388 }
1389 }
1390 }
1391 None
1392 }
1393
1394 pub fn next_pair(&mut self) -> Option<Self> {
1395 if let Self::Iter { idx, keys, value } = self {
1396 if !keys.is_empty() {
1397 if *idx < keys.len() {
1398 let k = keys[*idx].clone();
1399 let v = value.get_dynamic(k.as_str()).unwrap();
1400 *idx += 1;
1401 return Some(list!(k, v));
1402 }
1403 } else {
1404 if let Some(v) = value.get_idx(*idx) {
1405 *idx += 1;
1406 return Some(v);
1407 }
1408 }
1409 }
1410 None
1411 }
1412
1413 pub fn set_idx(&mut self, idx: usize, val: Dynamic) {
1414 match self {
1415 Self::List(list) => {
1416 list.write().unwrap().get_mut(idx).map(|l| *l = val);
1417 }
1418 Self::VecI8(vec) => vec.set(idx, val.try_into().unwrap()),
1419 Self::VecU16(vec) => vec.set(idx, val.try_into().unwrap()),
1420 Self::VecI16(vec) => vec.set(idx, val.try_into().unwrap()),
1421 Self::VecU32(vec) => vec.set(idx, val.try_into().unwrap()),
1422 Self::VecI32(vec) => vec.set(idx, val.try_into().unwrap()),
1423 Self::VecF32(vec) => vec.set(idx, val.try_into().unwrap()),
1424 Self::VecI64(vec) => vec[idx] = val.try_into().unwrap(),
1425 Self::VecU64(vec) => vec[idx] = val.try_into().unwrap(),
1426 Self::VecF64(vec) => vec[idx] = val.try_into().unwrap(),
1427 Self::Struct { addr, ty } => {
1428 if let Type::Struct { params: _, fields } = ty.clone()
1429 && let Some((_, field_ty)) = fields.get(idx)
1430 {
1431 Self::write_struct_field(*addr, idx, field_ty, &ty, val);
1432 }
1433 }
1434 _ => {}
1435 }
1436 }
1437
1438 pub fn to_markdown(&self) -> String {
1439 let mut s = String::new();
1440 if let Self::Map(m) = self {
1441 for (key, v) in m.read().unwrap().iter() {
1442 s.push_str(&format!("#### ```{}```\n", key));
1443 s.push_str(&v.to_markdown());
1444 s.push('\n');
1445 }
1446 } else if let Self::Bytes(bytes) = self {
1447 s = format!("[{}...]", hex::encode(&bytes[..8]));
1448 } else {
1449 let len = self.len();
1450 if len > 0 {
1451 for idx in 0..len {
1452 s.push_str(&format!("- {}\n", self.get_idx(idx).unwrap().to_markdown()));
1453 }
1454 } else {
1455 s = self.to_string();
1456 }
1457 }
1458 s
1459 }
1460}
1461
1462#[cfg(test)]
1463mod tests {
1464 use super::*;
1465 use std::sync::RwLock;
1466
1467 #[derive(Debug, PartialEq)]
1468 struct CustomCounter {
1469 value: i64,
1470 }
1471
1472 #[test]
1473 fn custom_values_can_be_downcast_and_shared_by_clone() {
1474 let value = Dynamic::custom(RwLock::new(CustomCounter { value: 7 }));
1475 assert!(value.is_custom());
1476 assert!(value.custom_type_name().is_some());
1477
1478 let cloned = value.clone();
1479 assert_eq!(cloned.as_custom::<RwLock<CustomCounter>>().unwrap().read().unwrap().value, 7);
1480
1481 cloned.as_custom::<RwLock<CustomCounter>>().unwrap().write().unwrap().value = 9;
1482 assert_eq!(value.as_custom::<RwLock<CustomCounter>>().unwrap().read().unwrap().value, 9);
1483 assert_eq!(value, cloned);
1484 }
1485
1486 #[derive(Debug, Default)]
1487 struct CustomPropertyBag {
1488 values: RwLock<BTreeMap<SmolStr, Dynamic>>,
1489 }
1490
1491 impl CustomProperty for CustomPropertyBag {
1492 fn get_key(&self, key: &str) -> Option<Dynamic> {
1493 self.values.read().unwrap().get(key).cloned()
1494 }
1495
1496 fn set_key(&self, key: &str, value: Dynamic) -> bool {
1497 self.values.write().unwrap().insert(key.into(), value);
1498 true
1499 }
1500 }
1501
1502 #[test]
1503 fn custom_values_can_forward_dynamic_properties() {
1504 let value = Dynamic::custom_with_properties(CustomPropertyBag::default());
1505
1506 value.set_dynamic("file_mode".into(), 2i64);
1507
1508 assert!(value.contains("file_mode"));
1509 assert_eq!(value.get_dynamic("file_mode").and_then(|value| value.as_int()), Some(2));
1510 }
1511
1512 #[test]
1513 fn deep_clone_recursively_copies_maps_and_lists() {
1514 let nested = Dynamic::map(Default::default());
1515 nested.insert("score", 1);
1516
1517 let value = Dynamic::map(Default::default());
1518 value.insert("nested", nested.clone());
1519 value.insert("items", Dynamic::list(vec![nested.clone()]));
1520
1521 let cloned = value.deep_clone();
1522 cloned.get_dynamic("nested").unwrap().insert("score", 2);
1523 cloned.get_dynamic("items").unwrap().get_idx(0).unwrap().insert("score", 3);
1524
1525 assert_eq!(value.get_dynamic("nested").unwrap().get_dynamic("score").and_then(|v| v.as_int()), Some(1));
1526 assert_eq!(value.get_dynamic("items").unwrap().get_idx(0).unwrap().get_dynamic("score").and_then(|v| v.as_int()), Some(1));
1527 }
1528
1529 #[test]
1530 fn string_add_keeps_concat_semantics() {
1531 let left = Dynamic::from("hello");
1532 let right = Dynamic::from(" world");
1533 let joined = left + right;
1534 assert!(matches!(joined, Dynamic::StringBuf(_)));
1535 assert_eq!(joined.as_str(), "hello world");
1536
1537 assert_eq!((Dynamic::from("level ") + Dynamic::I64(7)).as_str(), "level 7");
1538 assert_eq!((Dynamic::I64(7) + Dynamic::from(" days")).as_str(), "7 days");
1539 }
1540
1541 #[test]
1542 fn string_add_reuses_string_buf_after_first_concat() {
1543 let mut value = Dynamic::from("a") + Dynamic::from("b");
1544 assert!(matches!(value, Dynamic::StringBuf(_)));
1545
1546 value = value + Dynamic::from("c");
1547 assert!(matches!(value, Dynamic::StringBuf(_)));
1548 assert_eq!(value.as_str(), "abc");
1549 }
1550
1551 #[test]
1552 fn u64_as_int_does_not_wrap() {
1553 assert_eq!(Dynamic::U64(i64::MAX as u64).as_int(), Some(i64::MAX));
1554 assert_eq!(Dynamic::U64(i64::MAX as u64 + 1).as_int(), None);
1555 }
1556}
1557
1558#[macro_export]
1559macro_rules! assert_ok {
1560 ( $x: expr, $ok: expr) => {
1561 if $x {
1562 return Ok($ok);
1563 }
1564 };
1565}
1566
1567#[macro_export]
1568macro_rules! assert_err {
1569 ( $x: expr, $err: expr) => {
1570 if $x {
1571 return Err($err);
1572 }
1573 };
1574}
1575
1576pub struct ZOnce {
1577 first: Option<&'static str>,
1578 other: &'static str,
1579}
1580
1581impl ZOnce {
1582 pub fn new(first: &'static str, other: &'static str) -> Self {
1583 Self { first: Some(first), other }
1584 }
1585 pub fn take(&mut self) -> &'static str {
1586 self.first.take().unwrap_or(self.other)
1587 }
1588}
1589
1590mod fixvec;
1591pub use fixvec::FixVec;
1592mod msgpack;
1593pub use msgpack::{MsgPack, MsgUnpack};
1594
1595pub use json::{FromJson, ToJson};
1596
1597mod ops;
1598mod types;
1599pub use types::{ConstIntOp, Type, call_fn, set_dynamic_return_handler};
1600
1601#[macro_export]
1602macro_rules! list {
1603 ($($v:expr),+ $(,)?) => {{
1604 let mut list = Vec::new();
1605 $( let _ = list.push(Dynamic::from($v)); )*
1606 Dynamic::List(std::sync::Arc::new(std::sync::RwLock::new(list)))
1607 }};
1608}
1609
1610#[macro_export]
1611macro_rules! map {
1612 ($($k:expr => $v:expr), *) => {{
1613 let mut obj = std::collections::BTreeMap::new();
1614 $( let _ = obj.insert(smol_str::SmolStr::from($k), Dynamic::from($v)); )*
1615 Dynamic::Map(std::sync::Arc::new(std::sync::RwLock::new(obj)))
1616 }};
1617}