rune/runtime/
dynamic.rs
1use core::borrow::Borrow;
2use core::hash::Hash;
3use core::ops::Deref;
4
5use crate::alloc::{Box, Vec};
6
7use super::{FromValue, Repr, Rtti, RttiKind, RuntimeError, Tuple, TypeInfo, Value};
8
9use rust_alloc::sync::Arc;
10
11pub struct DynamicEmpty {
13 rtti: Arc<Rtti>,
14}
15
16impl FromValue for DynamicEmpty {
17 #[inline]
18 fn from_value(value: Value) -> Result<Self, RuntimeError> {
19 match value.take_repr() {
20 Repr::Dynamic(value) if matches!(value.rtti().kind, RttiKind::Empty) => Ok(Self {
21 rtti: value.rtti().clone(),
22 }),
23 value => Err(RuntimeError::expected_empty(value.type_info())),
24 }
25 }
26}
27
28impl DynamicEmpty {
29 pub fn type_info(&self) -> TypeInfo {
31 self.rtti.clone().type_info()
32 }
33}
34
35pub struct DynamicTuple {
40 rtti: Arc<Rtti>,
41 values: Vec<Value>,
42}
43
44impl FromValue for DynamicTuple {
45 #[inline]
46 fn from_value(value: Value) -> Result<Self, RuntimeError> {
47 match value.take_repr() {
48 Repr::Dynamic(value) if matches!(value.rtti().kind, RttiKind::Tuple) => {
49 let mut values = Vec::try_with_capacity(value.len())?;
50
51 for value in value.borrow_ref()?.iter() {
52 values.try_push(value.clone())?;
53 }
54
55 Ok(Self {
56 rtti: value.rtti().clone(),
57 values,
58 })
59 }
60 value => Err(RuntimeError::expected_tuple(value.type_info())),
61 }
62 }
63}
64
65impl DynamicTuple {
66 pub fn type_info(&self) -> TypeInfo {
68 self.rtti.clone().type_info()
69 }
70}
71
72impl Deref for DynamicTuple {
73 type Target = Tuple;
74
75 #[inline]
76 fn deref(&self) -> &Self::Target {
77 Tuple::new(&self.values)
78 }
79}
80
81pub struct DynamicStruct {
83 rtti: Arc<Rtti>,
84 values: Vec<Value>,
85}
86
87impl FromValue for DynamicStruct {
88 #[inline]
89 fn from_value(value: Value) -> Result<Self, RuntimeError> {
90 match value.take_repr() {
91 Repr::Dynamic(value) if matches!(value.rtti().kind, RttiKind::Struct) => {
92 let mut values = Vec::try_with_capacity(value.len())?;
93
94 for value in value.borrow_ref()?.iter() {
95 values.try_push(value.clone())?;
96 }
97
98 Ok(Self {
99 rtti: value.rtti().clone(),
100 values,
101 })
102 }
103 value => Err(RuntimeError::expected_struct(value.type_info())),
104 }
105 }
106}
107
108impl DynamicStruct {
109 pub fn get<Q>(&self, key: &Q) -> Option<&Value>
111 where
112 Box<str>: Borrow<Q>,
113 Q: Hash + Eq + ?Sized,
114 {
115 let index = *self.rtti.fields.get(key)?;
116 self.values.get(index)
117 }
118
119 pub fn type_info(&self) -> TypeInfo {
121 self.rtti.clone().type_info()
122 }
123}