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