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