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 const COMMIT_STABLE_KEY: &'static str;
76}
77
78pub trait StoreKind: Kind {
84 type Canister: CanisterKind;
85}
86
87pub trait EntityKey {
109 type Key: Copy
110 + Debug
111 + Eq
112 + Ord
113 + KeyValueCodec
114 + PrimaryKeyCodec
115 + PrimaryKeyDecode
116 + EntityKeyBytes
117 + 'static;
118}
119
120pub trait EntityKeyBytes {
125 const BYTE_LEN: usize;
127
128 fn write_bytes(&self, out: &mut [u8]);
130}
131
132macro_rules! impl_entity_key_bytes_numeric {
133 ($($ty:ty),* $(,)?) => {
134 $(
135 impl EntityKeyBytes for $ty {
136 const BYTE_LEN: usize = ::core::mem::size_of::<Self>();
137
138 fn write_bytes(&self, out: &mut [u8]) {
139 assert_eq!(out.len(), Self::BYTE_LEN);
140 out.copy_from_slice(&self.to_be_bytes());
141 }
142 }
143 )*
144 };
145}
146
147impl_entity_key_bytes_numeric!(i8, i16, i32, i64, u8, u16, u32, u64);
148
149impl EntityKeyBytes for () {
150 const BYTE_LEN: usize = 0;
151
152 fn write_bytes(&self, out: &mut [u8]) {
153 assert_eq!(out.len(), Self::BYTE_LEN);
154 }
155}
156
157pub trait KeyValueCodec {
167 fn to_key_value(&self) -> Value;
168
169 #[must_use]
170 fn from_key_value(value: &Value) -> Option<Self>
171 where
172 Self: Sized;
173}
174
175pub trait PrimaryKeyCodec {
184 fn to_primary_key_value(&self) -> Result<StorageKey, StorageKeyEncodeError>;
185}
186
187pub trait PrimaryKeyDecode: Sized {
197 fn from_primary_key_value(key: StorageKey) -> Result<Self, InternalError>;
198}
199
200fn primary_key_variant_decode_failed(
201 type_name: &'static str,
202 key: StorageKey,
203 expected: &'static str,
204) -> InternalError {
205 InternalError::store_corruption(format!(
206 "primary key decode failed for `{type_name}`: expected {expected}, found {key:?}",
207 ))
208}
209
210fn primary_key_range_decode_failed(type_name: &'static str, key: StorageKey) -> InternalError {
211 InternalError::store_corruption(format!(
212 "primary key decode failed for `{type_name}`: value out of range for {key:?}",
213 ))
214}
215
216macro_rules! impl_primary_key_codec_signed {
217 ($($ty:ty),* $(,)?) => {
218 $(
219 impl PrimaryKeyCodec for $ty {
220 fn to_primary_key_value(&self) -> Result<StorageKey, StorageKeyEncodeError> {
221 Ok(StorageKey::Int(i64::from(*self)))
222 }
223 }
224 )*
225 };
226}
227
228macro_rules! impl_primary_key_codec_unsigned {
229 ($($ty:ty),* $(,)?) => {
230 $(
231 impl PrimaryKeyCodec for $ty {
232 fn to_primary_key_value(&self) -> Result<StorageKey, StorageKeyEncodeError> {
233 Ok(StorageKey::Nat(u64::from(*self)))
234 }
235 }
236 )*
237 };
238}
239
240impl<T> KeyValueCodec for T
241where
242 T: RuntimeValueDecode + RuntimeValueEncode,
243{
244 fn to_key_value(&self) -> Value {
245 self.to_value()
246 }
247
248 fn from_key_value(value: &Value) -> Option<Self> {
249 Self::from_value(value)
250 }
251}
252
253impl_primary_key_codec_signed!(i8, i16, i32, i64);
254impl_primary_key_codec_unsigned!(u8, u16, u32, u64);
255
256macro_rules! impl_primary_key_decode_signed {
257 ($($ty:ty),* $(,)?) => {
258 $(
259 impl PrimaryKeyDecode for $ty {
260 fn from_primary_key_value(key: StorageKey) -> Result<Self, InternalError> {
261 let StorageKey::Int(value) = key else {
262 return Err(primary_key_variant_decode_failed(
263 ::std::any::type_name::<Self>(),
264 key,
265 "StorageKey::Int",
266 ));
267 };
268
269 Self::try_from(value).map_err(|_| {
270 primary_key_range_decode_failed(::std::any::type_name::<Self>(), key)
271 })
272 }
273 }
274 )*
275 };
276}
277
278macro_rules! impl_primary_key_decode_unsigned {
279 ($($ty:ty),* $(,)?) => {
280 $(
281 impl PrimaryKeyDecode for $ty {
282 fn from_primary_key_value(key: StorageKey) -> Result<Self, InternalError> {
283 let StorageKey::Nat(value) = key else {
284 return Err(primary_key_variant_decode_failed(
285 ::std::any::type_name::<Self>(),
286 key,
287 "StorageKey::Nat",
288 ));
289 };
290
291 Self::try_from(value).map_err(|_| {
292 primary_key_range_decode_failed(::std::any::type_name::<Self>(), key)
293 })
294 }
295 }
296 )*
297 };
298}
299
300impl_primary_key_decode_signed!(i8, i16, i32, i64);
301impl_primary_key_decode_unsigned!(u8, u16, u32, u64);
302
303impl PrimaryKeyCodec for crate::types::Principal {
304 fn to_primary_key_value(&self) -> Result<StorageKey, StorageKeyEncodeError> {
305 Ok(StorageKey::Principal(*self))
306 }
307}
308
309impl PrimaryKeyDecode for crate::types::Principal {
310 fn from_primary_key_value(key: StorageKey) -> Result<Self, InternalError> {
311 match key {
312 StorageKey::Principal(value) => Ok(value),
313 other => Err(primary_key_variant_decode_failed(
314 ::std::any::type_name::<Self>(),
315 other,
316 "StorageKey::Principal",
317 )),
318 }
319 }
320}
321
322impl PrimaryKeyCodec for crate::types::Subaccount {
323 fn to_primary_key_value(&self) -> Result<StorageKey, StorageKeyEncodeError> {
324 Ok(StorageKey::Subaccount(*self))
325 }
326}
327
328impl PrimaryKeyDecode for crate::types::Subaccount {
329 fn from_primary_key_value(key: StorageKey) -> Result<Self, InternalError> {
330 match key {
331 StorageKey::Subaccount(value) => Ok(value),
332 other => Err(primary_key_variant_decode_failed(
333 ::std::any::type_name::<Self>(),
334 other,
335 "StorageKey::Subaccount",
336 )),
337 }
338 }
339}
340
341impl PrimaryKeyCodec for crate::types::Account {
342 fn to_primary_key_value(&self) -> Result<StorageKey, StorageKeyEncodeError> {
343 Ok(StorageKey::Account(*self))
344 }
345}
346
347impl PrimaryKeyDecode for crate::types::Account {
348 fn from_primary_key_value(key: StorageKey) -> Result<Self, InternalError> {
349 match key {
350 StorageKey::Account(value) => Ok(value),
351 other => Err(primary_key_variant_decode_failed(
352 ::std::any::type_name::<Self>(),
353 other,
354 "StorageKey::Account",
355 )),
356 }
357 }
358}
359
360impl PrimaryKeyCodec for crate::types::Timestamp {
361 fn to_primary_key_value(&self) -> Result<StorageKey, StorageKeyEncodeError> {
362 Ok(StorageKey::Timestamp(*self))
363 }
364}
365
366impl PrimaryKeyDecode for crate::types::Timestamp {
367 fn from_primary_key_value(key: StorageKey) -> Result<Self, InternalError> {
368 match key {
369 StorageKey::Timestamp(value) => Ok(value),
370 other => Err(primary_key_variant_decode_failed(
371 ::std::any::type_name::<Self>(),
372 other,
373 "StorageKey::Timestamp",
374 )),
375 }
376 }
377}
378
379impl PrimaryKeyCodec for crate::types::Ulid {
380 fn to_primary_key_value(&self) -> Result<StorageKey, StorageKeyEncodeError> {
381 Ok(StorageKey::Ulid(*self))
382 }
383}
384
385impl PrimaryKeyDecode for crate::types::Ulid {
386 fn from_primary_key_value(key: StorageKey) -> Result<Self, InternalError> {
387 match key {
388 StorageKey::Ulid(value) => Ok(value),
389 other => Err(primary_key_variant_decode_failed(
390 ::std::any::type_name::<Self>(),
391 other,
392 "StorageKey::Ulid",
393 )),
394 }
395 }
396}
397
398impl PrimaryKeyCodec for () {
399 fn to_primary_key_value(&self) -> Result<StorageKey, StorageKeyEncodeError> {
400 Ok(StorageKey::Unit)
401 }
402}
403
404impl PrimaryKeyDecode for () {
405 fn from_primary_key_value(key: StorageKey) -> Result<Self, InternalError> {
406 match key {
407 StorageKey::Unit => Ok(()),
408 other => Err(primary_key_variant_decode_failed(
409 ::std::any::type_name::<Self>(),
410 other,
411 "StorageKey::Unit",
412 )),
413 }
414 }
415}
416
417pub trait RuntimeValueEncode {
429 fn to_value(&self) -> Value;
430}
431
432pub trait RuntimeValueDecode {
443 #[must_use]
444 fn from_value(value: &Value) -> Option<Self>
445 where
446 Self: Sized;
447}
448
449pub fn runtime_value_to_value<T>(value: &T) -> Value
458where
459 T: ?Sized + RuntimeValueEncode,
460{
461 value.to_value()
462}
463
464#[must_use]
473pub fn runtime_value_from_value<T>(value: &Value) -> Option<T>
474where
475 T: RuntimeValueDecode,
476{
477 T::from_value(value)
478}
479
480pub trait PersistedByKindCodec: Sized {
490 fn encode_persisted_slot_payload_by_kind(
492 &self,
493 kind: FieldKind,
494 field_name: &'static str,
495 ) -> Result<Vec<u8>, InternalError>;
496
497 fn decode_persisted_option_slot_payload_by_kind(
501 bytes: &[u8],
502 kind: FieldKind,
503 field_name: &'static str,
504 ) -> Result<Option<Self>, InternalError>;
505}
506
507pub trait PersistedStructuredFieldCodec {
519 fn encode_persisted_structured_payload(&self) -> Result<Vec<u8>, InternalError>;
521
522 fn decode_persisted_structured_payload(bytes: &[u8]) -> Result<Self, InternalError>
524 where
525 Self: Sized;
526}
527
528pub trait EntitySchema: EntityKey {
539 const NAME: &'static str;
540 const MODEL: &'static EntityModel;
541}
542
543pub trait EntityPlacement {
557 type Store: StoreKind;
558 type Canister: CanisterKind;
559}
560
561pub trait EntityKind: EntitySchema + EntityPlacement + Kind + TypeKind {
571 const ENTITY_TAG: EntityTag;
572}
573
574pub trait EntityValue: EntityKey + FieldProjection + Sized {
592 fn id(&self) -> Id<Self>;
593}
594
595pub struct EntityCreateMaterialization<E> {
604 entity: E,
605 authored_slots: Vec<usize>,
606}
607
608impl<E> EntityCreateMaterialization<E> {
609 #[must_use]
611 pub const fn new(entity: E, authored_slots: Vec<usize>) -> Self {
612 Self {
613 entity,
614 authored_slots,
615 }
616 }
617
618 #[must_use]
620 pub fn into_entity(self) -> E {
621 self.entity
622 }
623
624 #[must_use]
626 pub const fn authored_slots(&self) -> &[usize] {
627 self.authored_slots.as_slice()
628 }
629}
630
631pub trait EntityCreateInput: Sized {
640 type Entity: EntityValue;
641
642 fn materialize_create(self)
644 -> Result<EntityCreateMaterialization<Self::Entity>, InternalError>;
645}
646
647pub trait EntityCreateType: EntityValue {
657 type Create: EntityCreateInput<Entity = Self>;
658}
659
660pub trait SingletonEntity: EntityValue {}
662
663pub trait TypeKind:
681 Kind + Clone + DeserializeOwned + Sanitize + Validate + Visitable + PartialEq
682{
683}
684
685impl<T> TypeKind for T where
686 T: Kind + Clone + DeserializeOwned + PartialEq + Sanitize + Validate + Visitable
687{
688}
689
690pub trait FieldTypeMeta {
699 const KIND: FieldKind;
701
702 const STORAGE_DECODE: FieldStorageDecode;
704
705 const NESTED_FIELDS: &'static [FieldModel] = &[];
707}
708
709pub trait PersistedFieldMetaCodec: FieldTypeMeta + Sized {
720 fn encode_persisted_slot_payload_by_meta(
723 &self,
724 field_name: &'static str,
725 ) -> Result<Vec<u8>, InternalError>;
726
727 fn decode_persisted_slot_payload_by_meta(
730 bytes: &[u8],
731 field_name: &'static str,
732 ) -> Result<Self, InternalError>;
733
734 fn encode_persisted_option_slot_payload_by_meta(
737 value: &Option<Self>,
738 field_name: &'static str,
739 ) -> Result<Vec<u8>, InternalError>;
740
741 fn decode_persisted_option_slot_payload_by_meta(
744 bytes: &[u8],
745 field_name: &'static str,
746 ) -> Result<Option<Self>, InternalError>;
747}
748
749pub trait PersistedFieldSlotCodec: Sized {
759 fn encode_persisted_slot(&self, field_name: &'static str) -> Result<Vec<u8>, InternalError>;
762
763 fn decode_persisted_slot(bytes: &[u8], field_name: &'static str)
766 -> Result<Self, InternalError>;
767
768 fn encode_persisted_option_slot(
771 value: &Option<Self>,
772 field_name: &'static str,
773 ) -> Result<Vec<u8>, InternalError>;
774
775 fn decode_persisted_option_slot(
778 bytes: &[u8],
779 field_name: &'static str,
780 ) -> Result<Option<Self>, InternalError>;
781}
782
783impl<T> FieldTypeMeta for Option<T>
784where
785 T: FieldTypeMeta,
786{
787 const KIND: FieldKind = T::KIND;
788 const STORAGE_DECODE: FieldStorageDecode = T::STORAGE_DECODE;
789 const NESTED_FIELDS: &'static [FieldModel] = T::NESTED_FIELDS;
790}
791
792impl<T> FieldTypeMeta for Box<T>
793where
794 T: FieldTypeMeta,
795{
796 const KIND: FieldKind = T::KIND;
797 const STORAGE_DECODE: FieldStorageDecode = T::STORAGE_DECODE;
798 const NESTED_FIELDS: &'static [FieldModel] = T::NESTED_FIELDS;
799}
800
801impl<T> FieldTypeMeta for Vec<T>
805where
806 T: FieldTypeMeta,
807{
808 const KIND: FieldKind = FieldKind::List(&T::KIND);
809 const STORAGE_DECODE: FieldStorageDecode = FieldStorageDecode::Value;
810}
811
812impl<T> FieldTypeMeta for BTreeSet<T>
813where
814 T: FieldTypeMeta,
815{
816 const KIND: FieldKind = FieldKind::Set(&T::KIND);
817 const STORAGE_DECODE: FieldStorageDecode = FieldStorageDecode::Value;
818}
819
820impl<K, V> FieldTypeMeta for BTreeMap<K, V>
821where
822 K: FieldTypeMeta,
823 V: FieldTypeMeta,
824{
825 const KIND: FieldKind = FieldKind::Map {
826 key: &K::KIND,
827 value: &V::KIND,
828 };
829 const STORAGE_DECODE: FieldStorageDecode = FieldStorageDecode::Value;
830}
831
832pub trait Collection {
845 type Item;
846
847 type Iter<'a>: Iterator<Item = &'a Self::Item> + 'a
849 where
850 Self: 'a;
851
852 fn iter(&self) -> Self::Iter<'_>;
854
855 fn len(&self) -> usize;
857
858 fn is_empty(&self) -> bool {
860 self.len() == 0
861 }
862}
863
864pub trait MapCollection {
873 type Key;
874 type Value;
875
876 type Iter<'a>: Iterator<Item = (&'a Self::Key, &'a Self::Value)> + 'a
878 where
879 Self: 'a;
880
881 fn iter(&self) -> Self::Iter<'_>;
883
884 fn len(&self) -> usize;
886
887 fn is_empty(&self) -> bool {
889 self.len() == 0
890 }
891}
892
893impl<T> Collection for Vec<T> {
894 type Item = T;
895 type Iter<'a>
896 = std::slice::Iter<'a, T>
897 where
898 Self: 'a;
899
900 fn iter(&self) -> Self::Iter<'_> {
901 self.as_slice().iter()
902 }
903
904 fn len(&self) -> usize {
905 self.as_slice().len()
906 }
907}
908
909impl<T> Collection for BTreeSet<T> {
910 type Item = T;
911 type Iter<'a>
912 = std::collections::btree_set::Iter<'a, T>
913 where
914 Self: 'a;
915
916 fn iter(&self) -> Self::Iter<'_> {
917 self.iter()
918 }
919
920 fn len(&self) -> usize {
921 self.len()
922 }
923}
924
925impl<K, V> MapCollection for BTreeMap<K, V> {
926 type Key = K;
927 type Value = V;
928 type Iter<'a>
929 = std::collections::btree_map::Iter<'a, K, V>
930 where
931 Self: 'a;
932
933 fn iter(&self) -> Self::Iter<'_> {
934 self.iter()
935 }
936
937 fn len(&self) -> usize {
938 self.len()
939 }
940}
941
942pub trait EnumValue {
943 fn to_value_enum(&self) -> ValueEnum;
944}
945
946pub trait FieldProjection {
947 fn get_value_by_index(&self, index: usize) -> Option<Value>;
949}
950
951#[derive(Clone, Copy, Debug, Eq, PartialEq)]
959pub enum RuntimeValueKind {
960 Atomic,
962
963 Structured {
966 queryable: bool,
968 },
969}
970
971impl RuntimeValueKind {
972 #[must_use]
973 pub const fn is_queryable(self) -> bool {
974 match self {
975 Self::Atomic => true,
976 Self::Structured { queryable } => queryable,
977 }
978 }
979}
980
981pub trait RuntimeValueMeta {
990 fn kind() -> RuntimeValueKind
991 where
992 Self: Sized;
993}
994
995pub fn runtime_value_collection_to_value<C>(collection: &C) -> Value
1004where
1005 C: Collection,
1006 C::Item: RuntimeValueEncode,
1007{
1008 Value::List(
1009 collection
1010 .iter()
1011 .map(RuntimeValueEncode::to_value)
1012 .collect(),
1013 )
1014}
1015
1016#[must_use]
1025pub fn runtime_value_vec_from_value<T>(value: &Value) -> Option<Vec<T>>
1026where
1027 T: RuntimeValueDecode,
1028{
1029 let Value::List(values) = value else {
1030 return None;
1031 };
1032
1033 let mut out = Vec::with_capacity(values.len());
1034 for value in values {
1035 out.push(T::from_value(value)?);
1036 }
1037
1038 Some(out)
1039}
1040
1041#[must_use]
1050pub fn runtime_value_btree_set_from_value<T>(value: &Value) -> Option<BTreeSet<T>>
1051where
1052 T: Ord + RuntimeValueDecode,
1053{
1054 let Value::List(values) = value else {
1055 return None;
1056 };
1057
1058 let mut out = BTreeSet::new();
1059 for value in values {
1060 let item = T::from_value(value)?;
1061 if !out.insert(item) {
1062 return None;
1063 }
1064 }
1065
1066 Some(out)
1067}
1068
1069pub fn runtime_value_map_collection_to_value<M>(map: &M, path: &'static str) -> Value
1079where
1080 M: MapCollection,
1081 M::Key: RuntimeValueEncode,
1082 M::Value: RuntimeValueEncode,
1083{
1084 let mut entries: Vec<(Value, Value)> = map
1085 .iter()
1086 .map(|(key, value)| {
1087 (
1088 RuntimeValueEncode::to_value(key),
1089 RuntimeValueEncode::to_value(value),
1090 )
1091 })
1092 .collect();
1093
1094 if let Err(err) = Value::validate_map_entries(entries.as_slice()) {
1095 debug_assert!(false, "invalid map field value for {path}: {err}");
1096 return Value::Map(entries);
1097 }
1098
1099 Value::sort_map_entries_in_place(entries.as_mut_slice());
1100
1101 for i in 1..entries.len() {
1102 let (left_key, _) = &entries[i - 1];
1103 let (right_key, _) = &entries[i];
1104 if Value::canonical_cmp_key(left_key, right_key) == Ordering::Equal {
1105 debug_assert!(
1106 false,
1107 "duplicate map key in {path} after value-surface canonicalization",
1108 );
1109 break;
1110 }
1111 }
1112
1113 Value::Map(entries)
1114}
1115
1116#[must_use]
1125pub fn runtime_value_btree_map_from_value<K, V>(value: &Value) -> Option<BTreeMap<K, V>>
1126where
1127 K: Ord + RuntimeValueDecode,
1128 V: RuntimeValueDecode,
1129{
1130 let Value::Map(entries) = value else {
1131 return None;
1132 };
1133
1134 let normalized = Value::normalize_map_entries(entries.clone()).ok()?;
1135 if normalized.as_slice() != entries.as_slice() {
1136 return None;
1137 }
1138
1139 let mut map = BTreeMap::new();
1140 for (entry_key, entry_value) in normalized {
1141 let key = K::from_value(&entry_key)?;
1142 let value = V::from_value(&entry_value)?;
1143 map.insert(key, value);
1144 }
1145
1146 Some(map)
1147}
1148
1149#[must_use]
1158pub fn runtime_value_from_vec_into<T, I>(entries: Vec<I>) -> Vec<T>
1159where
1160 I: Into<T>,
1161{
1162 entries.into_iter().map(Into::into).collect()
1163}
1164
1165#[must_use]
1174pub fn runtime_value_from_vec_into_btree_set<T, I>(entries: Vec<I>) -> BTreeSet<T>
1175where
1176 I: Into<T>,
1177 T: Ord,
1178{
1179 entries.into_iter().map(Into::into).collect()
1180}
1181
1182#[must_use]
1191pub fn runtime_value_from_vec_into_btree_map<K, V, IK, IV>(entries: Vec<(IK, IV)>) -> BTreeMap<K, V>
1192where
1193 IK: Into<K>,
1194 IV: Into<V>,
1195 K: Ord,
1196{
1197 entries
1198 .into_iter()
1199 .map(|(key, value)| (key.into(), value.into()))
1200 .collect()
1201}
1202
1203#[must_use]
1212pub fn runtime_value_into<T, U>(value: U) -> T
1213where
1214 U: Into<T>,
1215{
1216 value.into()
1217}
1218
1219impl RuntimeValueMeta for &str {
1220 fn kind() -> RuntimeValueKind {
1221 RuntimeValueKind::Atomic
1222 }
1223}
1224
1225impl RuntimeValueEncode for &str {
1226 fn to_value(&self) -> Value {
1227 Value::Text((*self).to_string())
1228 }
1229}
1230
1231impl RuntimeValueDecode for &str {
1232 fn from_value(_value: &Value) -> Option<Self> {
1233 None
1234 }
1235}
1236
1237impl RuntimeValueMeta for String {
1238 fn kind() -> RuntimeValueKind {
1239 RuntimeValueKind::Atomic
1240 }
1241}
1242
1243impl RuntimeValueEncode for String {
1244 fn to_value(&self) -> Value {
1245 Value::Text(self.clone())
1246 }
1247}
1248
1249impl RuntimeValueDecode for String {
1250 fn from_value(value: &Value) -> Option<Self> {
1251 match value {
1252 Value::Text(v) => Some(v.clone()),
1253 _ => None,
1254 }
1255 }
1256}
1257
1258impl<T: RuntimeValueMeta> RuntimeValueMeta for Option<T> {
1259 fn kind() -> RuntimeValueKind {
1260 T::kind()
1261 }
1262}
1263
1264impl<T: RuntimeValueEncode> RuntimeValueEncode for Option<T> {
1265 fn to_value(&self) -> Value {
1266 match self {
1267 Some(v) => v.to_value(),
1268 None => Value::Null,
1269 }
1270 }
1271}
1272
1273impl<T: RuntimeValueDecode> RuntimeValueDecode for Option<T> {
1274 fn from_value(value: &Value) -> Option<Self> {
1275 if matches!(value, Value::Null) {
1276 return Some(None);
1277 }
1278
1279 T::from_value(value).map(Some)
1280 }
1281}
1282
1283impl<T: RuntimeValueMeta> RuntimeValueMeta for Box<T> {
1284 fn kind() -> RuntimeValueKind {
1285 T::kind()
1286 }
1287}
1288
1289impl<T: RuntimeValueEncode> RuntimeValueEncode for Box<T> {
1290 fn to_value(&self) -> Value {
1291 (**self).to_value()
1292 }
1293}
1294
1295impl<T: RuntimeValueDecode> RuntimeValueDecode for Box<T> {
1296 fn from_value(value: &Value) -> Option<Self> {
1297 T::from_value(value).map(Self::new)
1298 }
1299}
1300
1301impl<T> RuntimeValueMeta for Vec<T> {
1302 fn kind() -> RuntimeValueKind {
1303 RuntimeValueKind::Structured { queryable: true }
1304 }
1305}
1306
1307impl<T: RuntimeValueEncode> RuntimeValueEncode for Vec<T> {
1308 fn to_value(&self) -> Value {
1309 runtime_value_collection_to_value(self)
1310 }
1311}
1312
1313impl<T: RuntimeValueDecode> RuntimeValueDecode for Vec<T> {
1314 fn from_value(value: &Value) -> Option<Self> {
1315 runtime_value_vec_from_value(value)
1316 }
1317}
1318
1319impl<T> RuntimeValueMeta for BTreeSet<T>
1320where
1321 T: Ord,
1322{
1323 fn kind() -> RuntimeValueKind {
1324 RuntimeValueKind::Structured { queryable: true }
1325 }
1326}
1327
1328impl<T> RuntimeValueEncode for BTreeSet<T>
1329where
1330 T: Ord + RuntimeValueEncode,
1331{
1332 fn to_value(&self) -> Value {
1333 runtime_value_collection_to_value(self)
1334 }
1335}
1336
1337impl<T> RuntimeValueDecode for BTreeSet<T>
1338where
1339 T: Ord + RuntimeValueDecode,
1340{
1341 fn from_value(value: &Value) -> Option<Self> {
1342 runtime_value_btree_set_from_value(value)
1343 }
1344}
1345
1346impl<K, V> RuntimeValueMeta for BTreeMap<K, V>
1347where
1348 K: Ord,
1349{
1350 fn kind() -> RuntimeValueKind {
1351 RuntimeValueKind::Structured { queryable: true }
1352 }
1353}
1354
1355impl<K, V> RuntimeValueEncode for BTreeMap<K, V>
1356where
1357 K: Ord + RuntimeValueEncode,
1358 V: RuntimeValueEncode,
1359{
1360 fn to_value(&self) -> Value {
1361 runtime_value_map_collection_to_value(self, std::any::type_name::<Self>())
1362 }
1363}
1364
1365impl<K, V> RuntimeValueDecode for BTreeMap<K, V>
1366where
1367 K: Ord + RuntimeValueDecode,
1368 V: RuntimeValueDecode,
1369{
1370 fn from_value(value: &Value) -> Option<Self> {
1371 runtime_value_btree_map_from_value(value)
1372 }
1373}
1374
1375#[macro_export]
1377macro_rules! impl_runtime_value {
1378 ( $( $type:ty => $variant:ident ),* $(,)? ) => {
1379 $(
1380 impl RuntimeValueMeta for $type {
1381 fn kind() -> RuntimeValueKind {
1382 RuntimeValueKind::Atomic
1383 }
1384 }
1385
1386 impl RuntimeValueEncode for $type {
1387 fn to_value(&self) -> Value {
1388 Value::$variant((*self).into())
1389 }
1390 }
1391
1392 impl RuntimeValueDecode for $type {
1393 fn from_value(value: &Value) -> Option<Self> {
1394 match value {
1395 Value::$variant(v) => (*v).try_into().ok(),
1396 _ => None,
1397 }
1398 }
1399 }
1400 )*
1401 };
1402}
1403
1404impl_runtime_value!(
1405 i8 => Int,
1406 i16 => Int,
1407 i32 => Int,
1408 i64 => Int,
1409 u8 => Nat,
1410 u16 => Nat,
1411 u32 => Nat,
1412 u64 => Nat,
1413 bool => Bool,
1414);
1415
1416pub trait Inner<T> {
1427 fn inner(&self) -> &T;
1428 fn into_inner(self) -> T;
1429}
1430
1431pub trait Repr {
1438 type Inner;
1439
1440 fn repr(&self) -> Self::Inner;
1441 fn from_repr(inner: Self::Inner) -> Self;
1442}
1443
1444pub trait Sanitizer<T> {
1455 fn sanitize(&self, value: &mut T) -> Result<(), String>;
1456
1457 fn sanitize_with_context(
1458 &self,
1459 value: &mut T,
1460 ctx: &mut dyn VisitorContext,
1461 ) -> Result<(), String> {
1462 let _ = ctx;
1463
1464 self.sanitize(value)
1465 }
1466}
1467
1468pub trait Validator<T: ?Sized> {
1475 fn validate(&self, value: &T, ctx: &mut dyn VisitorContext);
1476}