1#[macro_use]
8mod macros;
9mod numeric_value;
10mod visitor;
11
12use crate::{
13 error::InternalError,
14 model::field::{FieldKind, FieldModel, FieldStorageDecode},
15 prelude::*,
16 types::{EntityTag, Id},
17 value::{StorageKey, StorageKeyEncodeError, Value, ValueEnum},
18 visitor::VisitorContext,
19};
20use std::collections::{BTreeMap, BTreeSet};
21
22pub use numeric_value::*;
23pub use visitor::*;
24
25pub use canic_cdk::structures::storable::Storable;
30pub use serde::{Deserialize, Serialize, de::DeserializeOwned};
31pub use std::{
32 cmp::{Eq, Ordering, PartialEq},
33 convert::From,
34 default::Default,
35 fmt::Debug,
36 hash::Hash,
37 ops::{Add, AddAssign, Deref, DerefMut, Div, DivAssign, Mul, MulAssign, Rem, Sub, SubAssign},
38};
39
40pub trait Path {
54 const PATH: &'static str;
55}
56
57pub trait Kind: Path + 'static {}
63impl<T> Kind for T where T: Path + 'static {}
64
65pub trait CanisterKind: Kind {
71 const COMMIT_MEMORY_ID: u8;
73}
74
75pub trait StoreKind: Kind {
81 type Canister: CanisterKind;
82}
83
84pub trait EntityKey {
106 type Key: Copy
107 + Debug
108 + Eq
109 + Ord
110 + KeyValueCodec
111 + StorageKeyCodec
112 + StorageKeyDecode
113 + EntityKeyBytes
114 + 'static;
115}
116
117pub trait EntityKeyBytes {
122 const BYTE_LEN: usize;
124
125 fn write_bytes(&self, out: &mut [u8]);
127}
128
129macro_rules! impl_entity_key_bytes_numeric {
130 ($($ty:ty),* $(,)?) => {
131 $(
132 impl EntityKeyBytes for $ty {
133 const BYTE_LEN: usize = ::core::mem::size_of::<Self>();
134
135 fn write_bytes(&self, out: &mut [u8]) {
136 assert_eq!(out.len(), Self::BYTE_LEN);
137 out.copy_from_slice(&self.to_be_bytes());
138 }
139 }
140 )*
141 };
142}
143
144impl_entity_key_bytes_numeric!(i8, i16, i32, i64, u8, u16, u32, u64);
145
146impl EntityKeyBytes for () {
147 const BYTE_LEN: usize = 0;
148
149 fn write_bytes(&self, out: &mut [u8]) {
150 assert_eq!(out.len(), Self::BYTE_LEN);
151 }
152}
153
154pub trait KeyValueCodec {
164 fn to_key_value(&self) -> Value;
165
166 #[must_use]
167 fn from_key_value(value: &Value) -> Option<Self>
168 where
169 Self: Sized;
170}
171
172pub trait StorageKeyCodec {
180 fn to_storage_key(&self) -> Result<StorageKey, StorageKeyEncodeError>;
181}
182
183pub trait StorageKeyDecode: Sized {
192 fn from_storage_key(key: StorageKey) -> Result<Self, InternalError>;
193}
194
195fn storage_key_variant_decode_failed(
196 type_name: &'static str,
197 key: StorageKey,
198 expected: &'static str,
199) -> InternalError {
200 InternalError::store_corruption(format!(
201 "storage key decode failed for `{type_name}`: expected {expected}, found {key:?}",
202 ))
203}
204
205fn storage_key_range_decode_failed(type_name: &'static str, key: StorageKey) -> InternalError {
206 InternalError::store_corruption(format!(
207 "storage key decode failed for `{type_name}`: value out of range for {key:?}",
208 ))
209}
210
211macro_rules! impl_storage_key_codec_signed {
212 ($($ty:ty),* $(,)?) => {
213 $(
214 impl StorageKeyCodec for $ty {
215 fn to_storage_key(&self) -> Result<StorageKey, StorageKeyEncodeError> {
216 Ok(StorageKey::Int(i64::from(*self)))
217 }
218 }
219 )*
220 };
221}
222
223macro_rules! impl_storage_key_codec_unsigned {
224 ($($ty:ty),* $(,)?) => {
225 $(
226 impl StorageKeyCodec for $ty {
227 fn to_storage_key(&self) -> Result<StorageKey, StorageKeyEncodeError> {
228 Ok(StorageKey::Uint(u64::from(*self)))
229 }
230 }
231 )*
232 };
233}
234
235impl<T> KeyValueCodec for T
236where
237 T: RuntimeValueDecode + RuntimeValueEncode,
238{
239 fn to_key_value(&self) -> Value {
240 self.to_value()
241 }
242
243 fn from_key_value(value: &Value) -> Option<Self> {
244 Self::from_value(value)
245 }
246}
247
248impl_storage_key_codec_signed!(i8, i16, i32, i64);
249impl_storage_key_codec_unsigned!(u8, u16, u32, u64);
250
251macro_rules! impl_storage_key_decode_signed {
252 ($($ty:ty),* $(,)?) => {
253 $(
254 impl StorageKeyDecode for $ty {
255 fn from_storage_key(key: StorageKey) -> Result<Self, InternalError> {
256 let StorageKey::Int(value) = key else {
257 return Err(storage_key_variant_decode_failed(
258 ::std::any::type_name::<Self>(),
259 key,
260 "StorageKey::Int",
261 ));
262 };
263
264 Self::try_from(value).map_err(|_| {
265 storage_key_range_decode_failed(::std::any::type_name::<Self>(), key)
266 })
267 }
268 }
269 )*
270 };
271}
272
273macro_rules! impl_storage_key_decode_unsigned {
274 ($($ty:ty),* $(,)?) => {
275 $(
276 impl StorageKeyDecode for $ty {
277 fn from_storage_key(key: StorageKey) -> Result<Self, InternalError> {
278 let StorageKey::Uint(value) = key else {
279 return Err(storage_key_variant_decode_failed(
280 ::std::any::type_name::<Self>(),
281 key,
282 "StorageKey::Uint",
283 ));
284 };
285
286 Self::try_from(value).map_err(|_| {
287 storage_key_range_decode_failed(::std::any::type_name::<Self>(), key)
288 })
289 }
290 }
291 )*
292 };
293}
294
295impl_storage_key_decode_signed!(i8, i16, i32, i64);
296impl_storage_key_decode_unsigned!(u8, u16, u32, u64);
297
298impl StorageKeyCodec for crate::types::Principal {
299 fn to_storage_key(&self) -> Result<StorageKey, StorageKeyEncodeError> {
300 Ok(StorageKey::Principal(*self))
301 }
302}
303
304impl StorageKeyDecode for crate::types::Principal {
305 fn from_storage_key(key: StorageKey) -> Result<Self, InternalError> {
306 match key {
307 StorageKey::Principal(value) => Ok(value),
308 other => Err(storage_key_variant_decode_failed(
309 ::std::any::type_name::<Self>(),
310 other,
311 "StorageKey::Principal",
312 )),
313 }
314 }
315}
316
317impl StorageKeyCodec for crate::types::Subaccount {
318 fn to_storage_key(&self) -> Result<StorageKey, StorageKeyEncodeError> {
319 Ok(StorageKey::Subaccount(*self))
320 }
321}
322
323impl StorageKeyDecode for crate::types::Subaccount {
324 fn from_storage_key(key: StorageKey) -> Result<Self, InternalError> {
325 match key {
326 StorageKey::Subaccount(value) => Ok(value),
327 other => Err(storage_key_variant_decode_failed(
328 ::std::any::type_name::<Self>(),
329 other,
330 "StorageKey::Subaccount",
331 )),
332 }
333 }
334}
335
336impl StorageKeyCodec for crate::types::Account {
337 fn to_storage_key(&self) -> Result<StorageKey, StorageKeyEncodeError> {
338 Ok(StorageKey::Account(*self))
339 }
340}
341
342impl StorageKeyDecode for crate::types::Account {
343 fn from_storage_key(key: StorageKey) -> Result<Self, InternalError> {
344 match key {
345 StorageKey::Account(value) => Ok(value),
346 other => Err(storage_key_variant_decode_failed(
347 ::std::any::type_name::<Self>(),
348 other,
349 "StorageKey::Account",
350 )),
351 }
352 }
353}
354
355impl StorageKeyCodec for crate::types::Timestamp {
356 fn to_storage_key(&self) -> Result<StorageKey, StorageKeyEncodeError> {
357 Ok(StorageKey::Timestamp(*self))
358 }
359}
360
361impl StorageKeyDecode for crate::types::Timestamp {
362 fn from_storage_key(key: StorageKey) -> Result<Self, InternalError> {
363 match key {
364 StorageKey::Timestamp(value) => Ok(value),
365 other => Err(storage_key_variant_decode_failed(
366 ::std::any::type_name::<Self>(),
367 other,
368 "StorageKey::Timestamp",
369 )),
370 }
371 }
372}
373
374impl StorageKeyCodec for crate::types::Ulid {
375 fn to_storage_key(&self) -> Result<StorageKey, StorageKeyEncodeError> {
376 Ok(StorageKey::Ulid(*self))
377 }
378}
379
380impl StorageKeyDecode for crate::types::Ulid {
381 fn from_storage_key(key: StorageKey) -> Result<Self, InternalError> {
382 match key {
383 StorageKey::Ulid(value) => Ok(value),
384 other => Err(storage_key_variant_decode_failed(
385 ::std::any::type_name::<Self>(),
386 other,
387 "StorageKey::Ulid",
388 )),
389 }
390 }
391}
392
393impl StorageKeyCodec for () {
394 fn to_storage_key(&self) -> Result<StorageKey, StorageKeyEncodeError> {
395 Ok(StorageKey::Unit)
396 }
397}
398
399impl StorageKeyDecode for () {
400 fn from_storage_key(key: StorageKey) -> Result<Self, InternalError> {
401 match key {
402 StorageKey::Unit => Ok(()),
403 other => Err(storage_key_variant_decode_failed(
404 ::std::any::type_name::<Self>(),
405 other,
406 "StorageKey::Unit",
407 )),
408 }
409 }
410}
411
412pub trait RuntimeValueEncode {
424 fn to_value(&self) -> Value;
425}
426
427pub trait RuntimeValueDecode {
438 #[must_use]
439 fn from_value(value: &Value) -> Option<Self>
440 where
441 Self: Sized;
442}
443
444pub fn runtime_value_to_value<T>(value: &T) -> Value
453where
454 T: ?Sized + RuntimeValueEncode,
455{
456 value.to_value()
457}
458
459#[must_use]
468pub fn runtime_value_from_value<T>(value: &Value) -> Option<T>
469where
470 T: RuntimeValueDecode,
471{
472 T::from_value(value)
473}
474
475pub trait PersistedByKindCodec: Sized {
485 fn encode_persisted_slot_payload_by_kind(
487 &self,
488 kind: FieldKind,
489 field_name: &'static str,
490 ) -> Result<Vec<u8>, InternalError>;
491
492 fn decode_persisted_option_slot_payload_by_kind(
496 bytes: &[u8],
497 kind: FieldKind,
498 field_name: &'static str,
499 ) -> Result<Option<Self>, InternalError>;
500}
501
502pub trait PersistedStructuredFieldCodec {
514 fn encode_persisted_structured_payload(&self) -> Result<Vec<u8>, InternalError>;
516
517 fn decode_persisted_structured_payload(bytes: &[u8]) -> Result<Self, InternalError>
519 where
520 Self: Sized;
521}
522
523pub trait EntitySchema: EntityKey {
534 const NAME: &'static str;
535 const MODEL: &'static EntityModel;
536}
537
538pub trait EntityPlacement {
552 type Store: StoreKind;
553 type Canister: CanisterKind;
554}
555
556pub trait EntityKind: EntitySchema + EntityPlacement + Kind + TypeKind {
566 const ENTITY_TAG: EntityTag;
567}
568
569pub trait EntityValue: EntityKey + FieldProjection + Sized {
587 fn id(&self) -> Id<Self>;
588}
589
590pub struct EntityCreateMaterialization<E> {
599 entity: E,
600 authored_slots: Vec<usize>,
601}
602
603impl<E> EntityCreateMaterialization<E> {
604 #[must_use]
606 pub const fn new(entity: E, authored_slots: Vec<usize>) -> Self {
607 Self {
608 entity,
609 authored_slots,
610 }
611 }
612
613 #[must_use]
615 pub fn into_entity(self) -> E {
616 self.entity
617 }
618
619 #[must_use]
621 pub const fn authored_slots(&self) -> &[usize] {
622 self.authored_slots.as_slice()
623 }
624}
625
626pub trait EntityCreateInput: Sized {
635 type Entity: EntityValue + Default;
636
637 fn materialize_create(self) -> EntityCreateMaterialization<Self::Entity>;
639}
640
641pub trait EntityCreateType: EntityValue {
651 type Create: EntityCreateInput<Entity = Self>;
652}
653
654pub trait SingletonEntity: EntityValue {}
656
657pub trait TypeKind:
675 Kind + Clone + Default + DeserializeOwned + Sanitize + Validate + Visitable + PartialEq
676{
677}
678
679impl<T> TypeKind for T where
680 T: Kind + Clone + Default + DeserializeOwned + PartialEq + Sanitize + Validate + Visitable
681{
682}
683
684pub trait FieldTypeMeta {
693 const KIND: FieldKind;
695
696 const STORAGE_DECODE: FieldStorageDecode;
698
699 const NESTED_FIELDS: &'static [FieldModel] = &[];
701}
702
703pub trait PersistedFieldMetaCodec: FieldTypeMeta + Sized {
714 fn encode_persisted_slot_payload_by_meta(
717 &self,
718 field_name: &'static str,
719 ) -> Result<Vec<u8>, InternalError>;
720
721 fn decode_persisted_slot_payload_by_meta(
724 bytes: &[u8],
725 field_name: &'static str,
726 ) -> Result<Self, InternalError>;
727
728 fn encode_persisted_option_slot_payload_by_meta(
731 value: &Option<Self>,
732 field_name: &'static str,
733 ) -> Result<Vec<u8>, InternalError>;
734
735 fn decode_persisted_option_slot_payload_by_meta(
738 bytes: &[u8],
739 field_name: &'static str,
740 ) -> Result<Option<Self>, InternalError>;
741}
742
743pub trait PersistedFieldSlotCodec: Sized {
753 fn encode_persisted_slot(&self, field_name: &'static str) -> Result<Vec<u8>, InternalError>;
756
757 fn decode_persisted_slot(bytes: &[u8], field_name: &'static str)
760 -> Result<Self, InternalError>;
761
762 fn encode_persisted_option_slot(
765 value: &Option<Self>,
766 field_name: &'static str,
767 ) -> Result<Vec<u8>, InternalError>;
768
769 fn decode_persisted_option_slot(
772 bytes: &[u8],
773 field_name: &'static str,
774 ) -> Result<Option<Self>, InternalError>;
775}
776
777impl<T> FieldTypeMeta for Option<T>
778where
779 T: FieldTypeMeta,
780{
781 const KIND: FieldKind = T::KIND;
782 const STORAGE_DECODE: FieldStorageDecode = T::STORAGE_DECODE;
783 const NESTED_FIELDS: &'static [FieldModel] = T::NESTED_FIELDS;
784}
785
786impl<T> FieldTypeMeta for Box<T>
787where
788 T: FieldTypeMeta,
789{
790 const KIND: FieldKind = T::KIND;
791 const STORAGE_DECODE: FieldStorageDecode = T::STORAGE_DECODE;
792 const NESTED_FIELDS: &'static [FieldModel] = T::NESTED_FIELDS;
793}
794
795impl<T> FieldTypeMeta for Vec<T>
799where
800 T: FieldTypeMeta,
801{
802 const KIND: FieldKind = FieldKind::List(&T::KIND);
803 const STORAGE_DECODE: FieldStorageDecode = FieldStorageDecode::Value;
804}
805
806impl<T> FieldTypeMeta for BTreeSet<T>
807where
808 T: FieldTypeMeta,
809{
810 const KIND: FieldKind = FieldKind::Set(&T::KIND);
811 const STORAGE_DECODE: FieldStorageDecode = FieldStorageDecode::Value;
812}
813
814impl<K, V> FieldTypeMeta for BTreeMap<K, V>
815where
816 K: FieldTypeMeta,
817 V: FieldTypeMeta,
818{
819 const KIND: FieldKind = FieldKind::Map {
820 key: &K::KIND,
821 value: &V::KIND,
822 };
823 const STORAGE_DECODE: FieldStorageDecode = FieldStorageDecode::Value;
824}
825
826pub trait Collection {
839 type Item;
840
841 type Iter<'a>: Iterator<Item = &'a Self::Item> + 'a
843 where
844 Self: 'a;
845
846 fn iter(&self) -> Self::Iter<'_>;
848
849 fn len(&self) -> usize;
851
852 fn is_empty(&self) -> bool {
854 self.len() == 0
855 }
856}
857
858pub trait MapCollection {
867 type Key;
868 type Value;
869
870 type Iter<'a>: Iterator<Item = (&'a Self::Key, &'a Self::Value)> + 'a
872 where
873 Self: 'a;
874
875 fn iter(&self) -> Self::Iter<'_>;
877
878 fn len(&self) -> usize;
880
881 fn is_empty(&self) -> bool {
883 self.len() == 0
884 }
885}
886
887impl<T> Collection for Vec<T> {
888 type Item = T;
889 type Iter<'a>
890 = std::slice::Iter<'a, T>
891 where
892 Self: 'a;
893
894 fn iter(&self) -> Self::Iter<'_> {
895 self.as_slice().iter()
896 }
897
898 fn len(&self) -> usize {
899 self.as_slice().len()
900 }
901}
902
903impl<T> Collection for BTreeSet<T> {
904 type Item = T;
905 type Iter<'a>
906 = std::collections::btree_set::Iter<'a, T>
907 where
908 Self: 'a;
909
910 fn iter(&self) -> Self::Iter<'_> {
911 self.iter()
912 }
913
914 fn len(&self) -> usize {
915 self.len()
916 }
917}
918
919impl<K, V> MapCollection for BTreeMap<K, V> {
920 type Key = K;
921 type Value = V;
922 type Iter<'a>
923 = std::collections::btree_map::Iter<'a, K, V>
924 where
925 Self: 'a;
926
927 fn iter(&self) -> Self::Iter<'_> {
928 self.iter()
929 }
930
931 fn len(&self) -> usize {
932 self.len()
933 }
934}
935
936pub trait EnumValue {
937 fn to_value_enum(&self) -> ValueEnum;
938}
939
940pub trait FieldProjection {
941 fn get_value_by_index(&self, index: usize) -> Option<Value>;
943}
944
945#[derive(Clone, Copy, Debug, Eq, PartialEq)]
953pub enum RuntimeValueKind {
954 Atomic,
956
957 Structured {
960 queryable: bool,
962 },
963}
964
965impl RuntimeValueKind {
966 #[must_use]
967 pub const fn is_queryable(self) -> bool {
968 match self {
969 Self::Atomic => true,
970 Self::Structured { queryable } => queryable,
971 }
972 }
973}
974
975pub trait RuntimeValueMeta {
984 fn kind() -> RuntimeValueKind
985 where
986 Self: Sized;
987}
988
989pub fn runtime_value_collection_to_value<C>(collection: &C) -> Value
998where
999 C: Collection,
1000 C::Item: RuntimeValueEncode,
1001{
1002 Value::List(
1003 collection
1004 .iter()
1005 .map(RuntimeValueEncode::to_value)
1006 .collect(),
1007 )
1008}
1009
1010#[must_use]
1019pub fn runtime_value_vec_from_value<T>(value: &Value) -> Option<Vec<T>>
1020where
1021 T: RuntimeValueDecode,
1022{
1023 let Value::List(values) = value else {
1024 return None;
1025 };
1026
1027 let mut out = Vec::with_capacity(values.len());
1028 for value in values {
1029 out.push(T::from_value(value)?);
1030 }
1031
1032 Some(out)
1033}
1034
1035#[must_use]
1044pub fn runtime_value_btree_set_from_value<T>(value: &Value) -> Option<BTreeSet<T>>
1045where
1046 T: Ord + RuntimeValueDecode,
1047{
1048 let Value::List(values) = value else {
1049 return None;
1050 };
1051
1052 let mut out = BTreeSet::new();
1053 for value in values {
1054 let item = T::from_value(value)?;
1055 if !out.insert(item) {
1056 return None;
1057 }
1058 }
1059
1060 Some(out)
1061}
1062
1063pub fn runtime_value_map_collection_to_value<M>(map: &M, path: &'static str) -> Value
1073where
1074 M: MapCollection,
1075 M::Key: RuntimeValueEncode,
1076 M::Value: RuntimeValueEncode,
1077{
1078 let mut entries: Vec<(Value, Value)> = map
1079 .iter()
1080 .map(|(key, value)| {
1081 (
1082 RuntimeValueEncode::to_value(key),
1083 RuntimeValueEncode::to_value(value),
1084 )
1085 })
1086 .collect();
1087
1088 if let Err(err) = Value::validate_map_entries(entries.as_slice()) {
1089 debug_assert!(false, "invalid map field value for {path}: {err}");
1090 return Value::Map(entries);
1091 }
1092
1093 Value::sort_map_entries_in_place(entries.as_mut_slice());
1094
1095 for i in 1..entries.len() {
1096 let (left_key, _) = &entries[i - 1];
1097 let (right_key, _) = &entries[i];
1098 if Value::canonical_cmp_key(left_key, right_key) == Ordering::Equal {
1099 debug_assert!(
1100 false,
1101 "duplicate map key in {path} after value-surface canonicalization",
1102 );
1103 break;
1104 }
1105 }
1106
1107 Value::Map(entries)
1108}
1109
1110#[must_use]
1119pub fn runtime_value_btree_map_from_value<K, V>(value: &Value) -> Option<BTreeMap<K, V>>
1120where
1121 K: Ord + RuntimeValueDecode,
1122 V: RuntimeValueDecode,
1123{
1124 let Value::Map(entries) = value else {
1125 return None;
1126 };
1127
1128 let normalized = Value::normalize_map_entries(entries.clone()).ok()?;
1129 if normalized.as_slice() != entries.as_slice() {
1130 return None;
1131 }
1132
1133 let mut map = BTreeMap::new();
1134 for (entry_key, entry_value) in normalized {
1135 let key = K::from_value(&entry_key)?;
1136 let value = V::from_value(&entry_value)?;
1137 map.insert(key, value);
1138 }
1139
1140 Some(map)
1141}
1142
1143#[must_use]
1152pub fn runtime_value_from_vec_into<T, I>(entries: Vec<I>) -> Vec<T>
1153where
1154 I: Into<T>,
1155{
1156 entries.into_iter().map(Into::into).collect()
1157}
1158
1159#[must_use]
1168pub fn runtime_value_from_vec_into_btree_set<T, I>(entries: Vec<I>) -> BTreeSet<T>
1169where
1170 I: Into<T>,
1171 T: Ord,
1172{
1173 entries.into_iter().map(Into::into).collect()
1174}
1175
1176#[must_use]
1185pub fn runtime_value_from_vec_into_btree_map<K, V, IK, IV>(entries: Vec<(IK, IV)>) -> BTreeMap<K, V>
1186where
1187 IK: Into<K>,
1188 IV: Into<V>,
1189 K: Ord,
1190{
1191 entries
1192 .into_iter()
1193 .map(|(key, value)| (key.into(), value.into()))
1194 .collect()
1195}
1196
1197#[must_use]
1206pub fn runtime_value_into<T, U>(value: U) -> T
1207where
1208 U: Into<T>,
1209{
1210 value.into()
1211}
1212
1213impl RuntimeValueMeta for &str {
1214 fn kind() -> RuntimeValueKind {
1215 RuntimeValueKind::Atomic
1216 }
1217}
1218
1219impl RuntimeValueEncode for &str {
1220 fn to_value(&self) -> Value {
1221 Value::Text((*self).to_string())
1222 }
1223}
1224
1225impl RuntimeValueDecode for &str {
1226 fn from_value(_value: &Value) -> Option<Self> {
1227 None
1228 }
1229}
1230
1231impl RuntimeValueMeta for String {
1232 fn kind() -> RuntimeValueKind {
1233 RuntimeValueKind::Atomic
1234 }
1235}
1236
1237impl RuntimeValueEncode for String {
1238 fn to_value(&self) -> Value {
1239 Value::Text(self.clone())
1240 }
1241}
1242
1243impl RuntimeValueDecode for String {
1244 fn from_value(value: &Value) -> Option<Self> {
1245 match value {
1246 Value::Text(v) => Some(v.clone()),
1247 _ => None,
1248 }
1249 }
1250}
1251
1252impl<T: RuntimeValueMeta> RuntimeValueMeta for Option<T> {
1253 fn kind() -> RuntimeValueKind {
1254 T::kind()
1255 }
1256}
1257
1258impl<T: RuntimeValueEncode> RuntimeValueEncode for Option<T> {
1259 fn to_value(&self) -> Value {
1260 match self {
1261 Some(v) => v.to_value(),
1262 None => Value::Null,
1263 }
1264 }
1265}
1266
1267impl<T: RuntimeValueDecode> RuntimeValueDecode for Option<T> {
1268 fn from_value(value: &Value) -> Option<Self> {
1269 if matches!(value, Value::Null) {
1270 return Some(None);
1271 }
1272
1273 T::from_value(value).map(Some)
1274 }
1275}
1276
1277impl<T: RuntimeValueMeta> RuntimeValueMeta for Box<T> {
1278 fn kind() -> RuntimeValueKind {
1279 T::kind()
1280 }
1281}
1282
1283impl<T: RuntimeValueEncode> RuntimeValueEncode for Box<T> {
1284 fn to_value(&self) -> Value {
1285 (**self).to_value()
1286 }
1287}
1288
1289impl<T: RuntimeValueDecode> RuntimeValueDecode for Box<T> {
1290 fn from_value(value: &Value) -> Option<Self> {
1291 T::from_value(value).map(Self::new)
1292 }
1293}
1294
1295impl<T> RuntimeValueMeta for Vec<T> {
1296 fn kind() -> RuntimeValueKind {
1297 RuntimeValueKind::Structured { queryable: true }
1298 }
1299}
1300
1301impl<T: RuntimeValueEncode> RuntimeValueEncode for Vec<T> {
1302 fn to_value(&self) -> Value {
1303 runtime_value_collection_to_value(self)
1304 }
1305}
1306
1307impl<T: RuntimeValueDecode> RuntimeValueDecode for Vec<T> {
1308 fn from_value(value: &Value) -> Option<Self> {
1309 runtime_value_vec_from_value(value)
1310 }
1311}
1312
1313impl<T> RuntimeValueMeta for BTreeSet<T>
1314where
1315 T: Ord,
1316{
1317 fn kind() -> RuntimeValueKind {
1318 RuntimeValueKind::Structured { queryable: true }
1319 }
1320}
1321
1322impl<T> RuntimeValueEncode for BTreeSet<T>
1323where
1324 T: Ord + RuntimeValueEncode,
1325{
1326 fn to_value(&self) -> Value {
1327 runtime_value_collection_to_value(self)
1328 }
1329}
1330
1331impl<T> RuntimeValueDecode for BTreeSet<T>
1332where
1333 T: Ord + RuntimeValueDecode,
1334{
1335 fn from_value(value: &Value) -> Option<Self> {
1336 runtime_value_btree_set_from_value(value)
1337 }
1338}
1339
1340impl<K, V> RuntimeValueMeta for BTreeMap<K, V>
1341where
1342 K: Ord,
1343{
1344 fn kind() -> RuntimeValueKind {
1345 RuntimeValueKind::Structured { queryable: true }
1346 }
1347}
1348
1349impl<K, V> RuntimeValueEncode for BTreeMap<K, V>
1350where
1351 K: Ord + RuntimeValueEncode,
1352 V: RuntimeValueEncode,
1353{
1354 fn to_value(&self) -> Value {
1355 runtime_value_map_collection_to_value(self, std::any::type_name::<Self>())
1356 }
1357}
1358
1359impl<K, V> RuntimeValueDecode for BTreeMap<K, V>
1360where
1361 K: Ord + RuntimeValueDecode,
1362 V: RuntimeValueDecode,
1363{
1364 fn from_value(value: &Value) -> Option<Self> {
1365 runtime_value_btree_map_from_value(value)
1366 }
1367}
1368
1369#[macro_export]
1371macro_rules! impl_runtime_value {
1372 ( $( $type:ty => $variant:ident ),* $(,)? ) => {
1373 $(
1374 impl RuntimeValueMeta for $type {
1375 fn kind() -> RuntimeValueKind {
1376 RuntimeValueKind::Atomic
1377 }
1378 }
1379
1380 impl RuntimeValueEncode for $type {
1381 fn to_value(&self) -> Value {
1382 Value::$variant((*self).into())
1383 }
1384 }
1385
1386 impl RuntimeValueDecode for $type {
1387 fn from_value(value: &Value) -> Option<Self> {
1388 match value {
1389 Value::$variant(v) => (*v).try_into().ok(),
1390 _ => None,
1391 }
1392 }
1393 }
1394 )*
1395 };
1396}
1397
1398impl_runtime_value!(
1399 i8 => Int,
1400 i16 => Int,
1401 i32 => Int,
1402 i64 => Int,
1403 u8 => Uint,
1404 u16 => Uint,
1405 u32 => Uint,
1406 u64 => Uint,
1407 bool => Bool,
1408);
1409
1410pub trait Inner<T> {
1421 fn inner(&self) -> &T;
1422 fn into_inner(self) -> T;
1423}
1424
1425pub trait Repr {
1432 type Inner;
1433
1434 fn repr(&self) -> Self::Inner;
1435 fn from_repr(inner: Self::Inner) -> Self;
1436}
1437
1438pub trait Sanitizer<T> {
1449 fn sanitize(&self, value: &mut T) -> Result<(), String>;
1450
1451 fn sanitize_with_context(
1452 &self,
1453 value: &mut T,
1454 ctx: &mut dyn VisitorContext,
1455 ) -> Result<(), String> {
1456 let _ = ctx;
1457
1458 self.sanitize(value)
1459 }
1460}
1461
1462pub trait Validator<T: ?Sized> {
1469 fn validate(&self, value: &T, ctx: &mut dyn VisitorContext);
1470}