1#[macro_use]
8mod macros;
9mod atomic;
10mod numeric_value;
11mod visitor;
12
13use crate::{
14 error::InternalError,
15 model::field::{FieldKind, FieldStorageDecode},
16 prelude::*,
17 types::{EntityTag, Id},
18 value::{StorageKey, StorageKeyEncodeError, Value, ValueEnum},
19 visitor::VisitorContext,
20};
21use std::collections::{BTreeMap, BTreeSet};
22
23pub use atomic::*;
24pub use numeric_value::*;
25pub use visitor::*;
26
27pub use canic_cdk::structures::storable::Storable;
32pub use serde::{Deserialize, Serialize, de::DeserializeOwned};
33pub use std::{
34 cmp::{Eq, Ordering, PartialEq},
35 convert::From,
36 default::Default,
37 fmt::Debug,
38 hash::Hash,
39 ops::{Add, AddAssign, Deref, DerefMut, Div, DivAssign, Mul, MulAssign, Rem, Sub, SubAssign},
40};
41
42pub trait Path {
56 const PATH: &'static str;
57}
58
59pub trait Kind: Path + 'static {}
65impl<T> Kind for T where T: Path + 'static {}
66
67pub trait CanisterKind: Kind {
73 const COMMIT_MEMORY_ID: u8;
75}
76
77pub trait StoreKind: Kind {
83 type Canister: CanisterKind;
84}
85
86pub trait EntityKey {
108 type Key: Copy
109 + Debug
110 + Eq
111 + Ord
112 + KeyValueCodec
113 + StorageKeyCodec
114 + StorageKeyDecode
115 + EntityKeyBytes
116 + 'static;
117}
118
119pub trait EntityKeyBytes {
124 const BYTE_LEN: usize;
126
127 fn write_bytes(&self, out: &mut [u8]);
129}
130
131macro_rules! impl_entity_key_bytes_numeric {
132 ($($ty:ty),* $(,)?) => {
133 $(
134 impl EntityKeyBytes for $ty {
135 const BYTE_LEN: usize = ::core::mem::size_of::<Self>();
136
137 fn write_bytes(&self, out: &mut [u8]) {
138 assert_eq!(out.len(), Self::BYTE_LEN);
139 out.copy_from_slice(&self.to_be_bytes());
140 }
141 }
142 )*
143 };
144}
145
146impl_entity_key_bytes_numeric!(i8, i16, i32, i64, u8, u16, u32, u64);
147
148impl EntityKeyBytes for () {
149 const BYTE_LEN: usize = 0;
150
151 fn write_bytes(&self, out: &mut [u8]) {
152 assert_eq!(out.len(), Self::BYTE_LEN);
153 }
154}
155
156pub trait KeyValueCodec {
166 fn to_key_value(&self) -> Value;
167
168 #[must_use]
169 fn from_key_value(value: &Value) -> Option<Self>
170 where
171 Self: Sized;
172}
173
174pub trait StorageKeyCodec {
182 fn to_storage_key(&self) -> Result<StorageKey, StorageKeyEncodeError>;
183}
184
185pub trait StorageKeyDecode: Sized {
194 fn from_storage_key(key: StorageKey) -> Result<Self, InternalError>;
195}
196
197fn storage_key_variant_decode_failed(
198 type_name: &'static str,
199 key: StorageKey,
200 expected: &'static str,
201) -> InternalError {
202 InternalError::store_corruption(format!(
203 "storage key decode failed for `{type_name}`: expected {expected}, found {key:?}",
204 ))
205}
206
207fn storage_key_range_decode_failed(type_name: &'static str, key: StorageKey) -> InternalError {
208 InternalError::store_corruption(format!(
209 "storage key decode failed for `{type_name}`: value out of range for {key:?}",
210 ))
211}
212
213macro_rules! impl_storage_key_codec_signed {
214 ($($ty:ty),* $(,)?) => {
215 $(
216 impl StorageKeyCodec for $ty {
217 fn to_storage_key(&self) -> Result<StorageKey, StorageKeyEncodeError> {
218 Ok(StorageKey::Int(i64::from(*self)))
219 }
220 }
221 )*
222 };
223}
224
225macro_rules! impl_storage_key_codec_unsigned {
226 ($($ty:ty),* $(,)?) => {
227 $(
228 impl StorageKeyCodec for $ty {
229 fn to_storage_key(&self) -> Result<StorageKey, StorageKeyEncodeError> {
230 Ok(StorageKey::Uint(u64::from(*self)))
231 }
232 }
233 )*
234 };
235}
236
237impl<T> KeyValueCodec for T
238where
239 T: RuntimeValueDecode + RuntimeValueEncode,
240{
241 fn to_key_value(&self) -> Value {
242 self.to_value()
243 }
244
245 fn from_key_value(value: &Value) -> Option<Self> {
246 Self::from_value(value)
247 }
248}
249
250impl_storage_key_codec_signed!(i8, i16, i32, i64);
251impl_storage_key_codec_unsigned!(u8, u16, u32, u64);
252
253macro_rules! impl_storage_key_decode_signed {
254 ($($ty:ty),* $(,)?) => {
255 $(
256 impl StorageKeyDecode for $ty {
257 fn from_storage_key(key: StorageKey) -> Result<Self, InternalError> {
258 let StorageKey::Int(value) = key else {
259 return Err(storage_key_variant_decode_failed(
260 ::std::any::type_name::<Self>(),
261 key,
262 "StorageKey::Int",
263 ));
264 };
265
266 Self::try_from(value).map_err(|_| {
267 storage_key_range_decode_failed(::std::any::type_name::<Self>(), key)
268 })
269 }
270 }
271 )*
272 };
273}
274
275macro_rules! impl_storage_key_decode_unsigned {
276 ($($ty:ty),* $(,)?) => {
277 $(
278 impl StorageKeyDecode for $ty {
279 fn from_storage_key(key: StorageKey) -> Result<Self, InternalError> {
280 let StorageKey::Uint(value) = key else {
281 return Err(storage_key_variant_decode_failed(
282 ::std::any::type_name::<Self>(),
283 key,
284 "StorageKey::Uint",
285 ));
286 };
287
288 Self::try_from(value).map_err(|_| {
289 storage_key_range_decode_failed(::std::any::type_name::<Self>(), key)
290 })
291 }
292 }
293 )*
294 };
295}
296
297impl_storage_key_decode_signed!(i8, i16, i32, i64);
298impl_storage_key_decode_unsigned!(u8, u16, u32, u64);
299
300impl StorageKeyCodec for crate::types::Principal {
301 fn to_storage_key(&self) -> Result<StorageKey, StorageKeyEncodeError> {
302 Ok(StorageKey::Principal(*self))
303 }
304}
305
306impl StorageKeyDecode for crate::types::Principal {
307 fn from_storage_key(key: StorageKey) -> Result<Self, InternalError> {
308 match key {
309 StorageKey::Principal(value) => Ok(value),
310 other => Err(storage_key_variant_decode_failed(
311 ::std::any::type_name::<Self>(),
312 other,
313 "StorageKey::Principal",
314 )),
315 }
316 }
317}
318
319impl StorageKeyCodec for crate::types::Subaccount {
320 fn to_storage_key(&self) -> Result<StorageKey, StorageKeyEncodeError> {
321 Ok(StorageKey::Subaccount(*self))
322 }
323}
324
325impl StorageKeyDecode for crate::types::Subaccount {
326 fn from_storage_key(key: StorageKey) -> Result<Self, InternalError> {
327 match key {
328 StorageKey::Subaccount(value) => Ok(value),
329 other => Err(storage_key_variant_decode_failed(
330 ::std::any::type_name::<Self>(),
331 other,
332 "StorageKey::Subaccount",
333 )),
334 }
335 }
336}
337
338impl StorageKeyCodec for crate::types::Account {
339 fn to_storage_key(&self) -> Result<StorageKey, StorageKeyEncodeError> {
340 Ok(StorageKey::Account(*self))
341 }
342}
343
344impl StorageKeyDecode for crate::types::Account {
345 fn from_storage_key(key: StorageKey) -> Result<Self, InternalError> {
346 match key {
347 StorageKey::Account(value) => Ok(value),
348 other => Err(storage_key_variant_decode_failed(
349 ::std::any::type_name::<Self>(),
350 other,
351 "StorageKey::Account",
352 )),
353 }
354 }
355}
356
357impl StorageKeyCodec for crate::types::Timestamp {
358 fn to_storage_key(&self) -> Result<StorageKey, StorageKeyEncodeError> {
359 Ok(StorageKey::Timestamp(*self))
360 }
361}
362
363impl StorageKeyDecode for crate::types::Timestamp {
364 fn from_storage_key(key: StorageKey) -> Result<Self, InternalError> {
365 match key {
366 StorageKey::Timestamp(value) => Ok(value),
367 other => Err(storage_key_variant_decode_failed(
368 ::std::any::type_name::<Self>(),
369 other,
370 "StorageKey::Timestamp",
371 )),
372 }
373 }
374}
375
376impl StorageKeyCodec for crate::types::Ulid {
377 fn to_storage_key(&self) -> Result<StorageKey, StorageKeyEncodeError> {
378 Ok(StorageKey::Ulid(*self))
379 }
380}
381
382impl StorageKeyDecode for crate::types::Ulid {
383 fn from_storage_key(key: StorageKey) -> Result<Self, InternalError> {
384 match key {
385 StorageKey::Ulid(value) => Ok(value),
386 other => Err(storage_key_variant_decode_failed(
387 ::std::any::type_name::<Self>(),
388 other,
389 "StorageKey::Ulid",
390 )),
391 }
392 }
393}
394
395impl StorageKeyCodec for () {
396 fn to_storage_key(&self) -> Result<StorageKey, StorageKeyEncodeError> {
397 Ok(StorageKey::Unit)
398 }
399}
400
401impl StorageKeyDecode for () {
402 fn from_storage_key(key: StorageKey) -> Result<Self, InternalError> {
403 match key {
404 StorageKey::Unit => Ok(()),
405 other => Err(storage_key_variant_decode_failed(
406 ::std::any::type_name::<Self>(),
407 other,
408 "StorageKey::Unit",
409 )),
410 }
411 }
412}
413
414pub trait RuntimeValueEncode {
426 fn to_value(&self) -> Value;
427}
428
429pub trait RuntimeValueDecode {
440 #[must_use]
441 fn from_value(value: &Value) -> Option<Self>
442 where
443 Self: Sized;
444}
445
446pub fn runtime_value_to_value<T>(value: &T) -> Value
455where
456 T: ?Sized + RuntimeValueEncode,
457{
458 value.to_value()
459}
460
461#[must_use]
470pub fn runtime_value_from_value<T>(value: &Value) -> Option<T>
471where
472 T: RuntimeValueDecode,
473{
474 T::from_value(value)
475}
476
477pub trait PersistedByKindCodec: Sized {
487 fn encode_persisted_slot_payload_by_kind(
489 &self,
490 kind: FieldKind,
491 field_name: &'static str,
492 ) -> Result<Vec<u8>, InternalError>;
493
494 fn decode_persisted_option_slot_payload_by_kind(
498 bytes: &[u8],
499 kind: FieldKind,
500 field_name: &'static str,
501 ) -> Result<Option<Self>, InternalError>;
502}
503
504pub trait PersistedStructuredFieldCodec {
516 fn encode_persisted_structured_payload(&self) -> Result<Vec<u8>, InternalError>;
518
519 fn decode_persisted_structured_payload(bytes: &[u8]) -> Result<Self, InternalError>
521 where
522 Self: Sized;
523}
524
525pub trait EntitySchema: EntityKey {
536 const NAME: &'static str;
537 const MODEL: &'static EntityModel;
538}
539
540pub trait EntityPlacement {
554 type Store: StoreKind;
555 type Canister: CanisterKind;
556}
557
558pub trait EntityKind: EntitySchema + EntityPlacement + Kind + TypeKind {
568 const ENTITY_TAG: EntityTag;
569}
570
571pub trait EntityValue: EntityKey + FieldProjection + Sized {
589 fn id(&self) -> Id<Self>;
590}
591
592pub struct EntityCreateMaterialization<E> {
601 entity: E,
602 authored_slots: Vec<usize>,
603}
604
605impl<E> EntityCreateMaterialization<E> {
606 #[must_use]
608 pub const fn new(entity: E, authored_slots: Vec<usize>) -> Self {
609 Self {
610 entity,
611 authored_slots,
612 }
613 }
614
615 #[must_use]
617 pub fn into_entity(self) -> E {
618 self.entity
619 }
620
621 #[must_use]
623 pub const fn authored_slots(&self) -> &[usize] {
624 self.authored_slots.as_slice()
625 }
626}
627
628pub trait EntityCreateInput: Sized {
637 type Entity: EntityValue + Default;
638
639 fn materialize_create(self) -> EntityCreateMaterialization<Self::Entity>;
641}
642
643pub trait EntityCreateType: EntityValue {
653 type Create: EntityCreateInput<Entity = Self>;
654}
655
656pub trait SingletonEntity: EntityValue {}
658
659pub trait TypeKind:
677 Kind + Clone + Default + DeserializeOwned + Sanitize + Validate + Visitable + PartialEq
678{
679}
680
681impl<T> TypeKind for T where
682 T: Kind + Clone + Default + DeserializeOwned + PartialEq + Sanitize + Validate + Visitable
683{
684}
685
686pub trait FieldTypeMeta {
695 const KIND: FieldKind;
697
698 const STORAGE_DECODE: FieldStorageDecode;
700}
701
702pub trait PersistedFieldMetaCodec: FieldTypeMeta + Sized {
713 fn encode_persisted_slot_payload_by_meta(
716 &self,
717 field_name: &'static str,
718 ) -> Result<Vec<u8>, InternalError>;
719
720 fn decode_persisted_slot_payload_by_meta(
723 bytes: &[u8],
724 field_name: &'static str,
725 ) -> Result<Self, InternalError>;
726
727 fn encode_persisted_option_slot_payload_by_meta(
730 value: &Option<Self>,
731 field_name: &'static str,
732 ) -> Result<Vec<u8>, InternalError>;
733
734 fn decode_persisted_option_slot_payload_by_meta(
737 bytes: &[u8],
738 field_name: &'static str,
739 ) -> Result<Option<Self>, InternalError>;
740}
741
742impl<T> FieldTypeMeta for Option<T>
743where
744 T: FieldTypeMeta,
745{
746 const KIND: FieldKind = T::KIND;
747 const STORAGE_DECODE: FieldStorageDecode = T::STORAGE_DECODE;
748}
749
750impl<T> FieldTypeMeta for Box<T>
751where
752 T: FieldTypeMeta,
753{
754 const KIND: FieldKind = T::KIND;
755 const STORAGE_DECODE: FieldStorageDecode = T::STORAGE_DECODE;
756}
757
758impl<T> FieldTypeMeta for Vec<T>
762where
763 T: FieldTypeMeta,
764{
765 const KIND: FieldKind = FieldKind::List(&T::KIND);
766 const STORAGE_DECODE: FieldStorageDecode = FieldStorageDecode::Value;
767}
768
769impl<T> FieldTypeMeta for BTreeSet<T>
770where
771 T: FieldTypeMeta,
772{
773 const KIND: FieldKind = FieldKind::Set(&T::KIND);
774 const STORAGE_DECODE: FieldStorageDecode = FieldStorageDecode::Value;
775}
776
777impl<K, V> FieldTypeMeta for BTreeMap<K, V>
778where
779 K: FieldTypeMeta,
780 V: FieldTypeMeta,
781{
782 const KIND: FieldKind = FieldKind::Map {
783 key: &K::KIND,
784 value: &V::KIND,
785 };
786 const STORAGE_DECODE: FieldStorageDecode = FieldStorageDecode::Value;
787}
788
789pub trait Collection {
802 type Item;
803
804 type Iter<'a>: Iterator<Item = &'a Self::Item> + 'a
806 where
807 Self: 'a;
808
809 fn iter(&self) -> Self::Iter<'_>;
811
812 fn len(&self) -> usize;
814
815 fn is_empty(&self) -> bool {
817 self.len() == 0
818 }
819}
820
821pub trait MapCollection {
830 type Key;
831 type Value;
832
833 type Iter<'a>: Iterator<Item = (&'a Self::Key, &'a Self::Value)> + 'a
835 where
836 Self: 'a;
837
838 fn iter(&self) -> Self::Iter<'_>;
840
841 fn len(&self) -> usize;
843
844 fn is_empty(&self) -> bool {
846 self.len() == 0
847 }
848}
849
850impl<T> Collection for Vec<T> {
851 type Item = T;
852 type Iter<'a>
853 = std::slice::Iter<'a, T>
854 where
855 Self: 'a;
856
857 fn iter(&self) -> Self::Iter<'_> {
858 self.as_slice().iter()
859 }
860
861 fn len(&self) -> usize {
862 self.as_slice().len()
863 }
864}
865
866impl<T> Collection for BTreeSet<T> {
867 type Item = T;
868 type Iter<'a>
869 = std::collections::btree_set::Iter<'a, T>
870 where
871 Self: 'a;
872
873 fn iter(&self) -> Self::Iter<'_> {
874 self.iter()
875 }
876
877 fn len(&self) -> usize {
878 self.len()
879 }
880}
881
882impl<K, V> MapCollection for BTreeMap<K, V> {
883 type Key = K;
884 type Value = V;
885 type Iter<'a>
886 = std::collections::btree_map::Iter<'a, K, V>
887 where
888 Self: 'a;
889
890 fn iter(&self) -> Self::Iter<'_> {
891 self.iter()
892 }
893
894 fn len(&self) -> usize {
895 self.len()
896 }
897}
898
899pub trait EnumValue {
900 fn to_value_enum(&self) -> ValueEnum;
901}
902
903pub trait FieldProjection {
904 fn get_value_by_index(&self, index: usize) -> Option<Value>;
906}
907
908#[derive(Clone, Copy, Debug, Eq, PartialEq)]
916pub enum RuntimeValueKind {
917 Atomic,
919
920 Structured {
923 queryable: bool,
925 },
926}
927
928impl RuntimeValueKind {
929 #[must_use]
930 pub const fn is_queryable(self) -> bool {
931 match self {
932 Self::Atomic => true,
933 Self::Structured { queryable } => queryable,
934 }
935 }
936}
937
938pub trait RuntimeValueMeta {
947 fn kind() -> RuntimeValueKind
948 where
949 Self: Sized;
950}
951
952pub fn runtime_value_collection_to_value<C>(collection: &C) -> Value
961where
962 C: Collection,
963 C::Item: RuntimeValueEncode,
964{
965 Value::List(
966 collection
967 .iter()
968 .map(RuntimeValueEncode::to_value)
969 .collect(),
970 )
971}
972
973#[must_use]
982pub fn runtime_value_vec_from_value<T>(value: &Value) -> Option<Vec<T>>
983where
984 T: RuntimeValueDecode,
985{
986 let Value::List(values) = value else {
987 return None;
988 };
989
990 let mut out = Vec::with_capacity(values.len());
991 for value in values {
992 out.push(T::from_value(value)?);
993 }
994
995 Some(out)
996}
997
998#[must_use]
1007pub fn runtime_value_btree_set_from_value<T>(value: &Value) -> Option<BTreeSet<T>>
1008where
1009 T: Ord + RuntimeValueDecode,
1010{
1011 let Value::List(values) = value else {
1012 return None;
1013 };
1014
1015 let mut out = BTreeSet::new();
1016 for value in values {
1017 let item = T::from_value(value)?;
1018 if !out.insert(item) {
1019 return None;
1020 }
1021 }
1022
1023 Some(out)
1024}
1025
1026pub fn runtime_value_map_collection_to_value<M>(map: &M, path: &'static str) -> Value
1036where
1037 M: MapCollection,
1038 M::Key: RuntimeValueEncode,
1039 M::Value: RuntimeValueEncode,
1040{
1041 let mut entries: Vec<(Value, Value)> = map
1042 .iter()
1043 .map(|(key, value)| {
1044 (
1045 RuntimeValueEncode::to_value(key),
1046 RuntimeValueEncode::to_value(value),
1047 )
1048 })
1049 .collect();
1050
1051 if let Err(err) = Value::validate_map_entries(entries.as_slice()) {
1052 debug_assert!(false, "invalid map field value for {path}: {err}");
1053 return Value::Map(entries);
1054 }
1055
1056 Value::sort_map_entries_in_place(entries.as_mut_slice());
1057
1058 for i in 1..entries.len() {
1059 let (left_key, _) = &entries[i - 1];
1060 let (right_key, _) = &entries[i];
1061 if Value::canonical_cmp_key(left_key, right_key) == Ordering::Equal {
1062 debug_assert!(
1063 false,
1064 "duplicate map key in {path} after value-surface canonicalization",
1065 );
1066 break;
1067 }
1068 }
1069
1070 Value::Map(entries)
1071}
1072
1073#[must_use]
1082pub fn runtime_value_btree_map_from_value<K, V>(value: &Value) -> Option<BTreeMap<K, V>>
1083where
1084 K: Ord + RuntimeValueDecode,
1085 V: RuntimeValueDecode,
1086{
1087 let Value::Map(entries) = value else {
1088 return None;
1089 };
1090
1091 let normalized = Value::normalize_map_entries(entries.clone()).ok()?;
1092 if normalized.as_slice() != entries.as_slice() {
1093 return None;
1094 }
1095
1096 let mut map = BTreeMap::new();
1097 for (entry_key, entry_value) in normalized {
1098 let key = K::from_value(&entry_key)?;
1099 let value = V::from_value(&entry_value)?;
1100 map.insert(key, value);
1101 }
1102
1103 Some(map)
1104}
1105
1106#[must_use]
1115pub fn runtime_value_from_vec_into<T, I>(entries: Vec<I>) -> Vec<T>
1116where
1117 I: Into<T>,
1118{
1119 entries.into_iter().map(Into::into).collect()
1120}
1121
1122#[must_use]
1131pub fn runtime_value_from_vec_into_btree_set<T, I>(entries: Vec<I>) -> BTreeSet<T>
1132where
1133 I: Into<T>,
1134 T: Ord,
1135{
1136 entries.into_iter().map(Into::into).collect()
1137}
1138
1139#[must_use]
1148pub fn runtime_value_from_vec_into_btree_map<K, V, IK, IV>(entries: Vec<(IK, IV)>) -> BTreeMap<K, V>
1149where
1150 IK: Into<K>,
1151 IV: Into<V>,
1152 K: Ord,
1153{
1154 entries
1155 .into_iter()
1156 .map(|(key, value)| (key.into(), value.into()))
1157 .collect()
1158}
1159
1160#[must_use]
1169pub fn runtime_value_into<T, U>(value: U) -> T
1170where
1171 U: Into<T>,
1172{
1173 value.into()
1174}
1175
1176impl RuntimeValueMeta for &str {
1177 fn kind() -> RuntimeValueKind {
1178 RuntimeValueKind::Atomic
1179 }
1180}
1181
1182impl RuntimeValueEncode for &str {
1183 fn to_value(&self) -> Value {
1184 Value::Text((*self).to_string())
1185 }
1186}
1187
1188impl RuntimeValueDecode for &str {
1189 fn from_value(_value: &Value) -> Option<Self> {
1190 None
1191 }
1192}
1193
1194impl RuntimeValueMeta for String {
1195 fn kind() -> RuntimeValueKind {
1196 RuntimeValueKind::Atomic
1197 }
1198}
1199
1200impl RuntimeValueEncode for String {
1201 fn to_value(&self) -> Value {
1202 Value::Text(self.clone())
1203 }
1204}
1205
1206impl RuntimeValueDecode for String {
1207 fn from_value(value: &Value) -> Option<Self> {
1208 match value {
1209 Value::Text(v) => Some(v.clone()),
1210 _ => None,
1211 }
1212 }
1213}
1214
1215impl<T: RuntimeValueMeta> RuntimeValueMeta for Option<T> {
1216 fn kind() -> RuntimeValueKind {
1217 T::kind()
1218 }
1219}
1220
1221impl<T: RuntimeValueEncode> RuntimeValueEncode for Option<T> {
1222 fn to_value(&self) -> Value {
1223 match self {
1224 Some(v) => v.to_value(),
1225 None => Value::Null,
1226 }
1227 }
1228}
1229
1230impl<T: RuntimeValueDecode> RuntimeValueDecode for Option<T> {
1231 fn from_value(value: &Value) -> Option<Self> {
1232 if matches!(value, Value::Null) {
1233 return Some(None);
1234 }
1235
1236 T::from_value(value).map(Some)
1237 }
1238}
1239
1240impl<T: RuntimeValueMeta> RuntimeValueMeta for Box<T> {
1241 fn kind() -> RuntimeValueKind {
1242 T::kind()
1243 }
1244}
1245
1246impl<T: RuntimeValueEncode> RuntimeValueEncode for Box<T> {
1247 fn to_value(&self) -> Value {
1248 (**self).to_value()
1249 }
1250}
1251
1252impl<T: RuntimeValueDecode> RuntimeValueDecode for Box<T> {
1253 fn from_value(value: &Value) -> Option<Self> {
1254 T::from_value(value).map(Self::new)
1255 }
1256}
1257
1258impl<T> RuntimeValueMeta for Vec<T> {
1259 fn kind() -> RuntimeValueKind {
1260 RuntimeValueKind::Structured { queryable: true }
1261 }
1262}
1263
1264impl<T: RuntimeValueEncode> RuntimeValueEncode for Vec<T> {
1265 fn to_value(&self) -> Value {
1266 runtime_value_collection_to_value(self)
1267 }
1268}
1269
1270impl<T: RuntimeValueDecode> RuntimeValueDecode for Vec<T> {
1271 fn from_value(value: &Value) -> Option<Self> {
1272 runtime_value_vec_from_value(value)
1273 }
1274}
1275
1276impl<T> RuntimeValueMeta for BTreeSet<T>
1277where
1278 T: Ord,
1279{
1280 fn kind() -> RuntimeValueKind {
1281 RuntimeValueKind::Structured { queryable: true }
1282 }
1283}
1284
1285impl<T> RuntimeValueEncode for BTreeSet<T>
1286where
1287 T: Ord + RuntimeValueEncode,
1288{
1289 fn to_value(&self) -> Value {
1290 runtime_value_collection_to_value(self)
1291 }
1292}
1293
1294impl<T> RuntimeValueDecode for BTreeSet<T>
1295where
1296 T: Ord + RuntimeValueDecode,
1297{
1298 fn from_value(value: &Value) -> Option<Self> {
1299 runtime_value_btree_set_from_value(value)
1300 }
1301}
1302
1303impl<K, V> RuntimeValueMeta for BTreeMap<K, V>
1304where
1305 K: Ord,
1306{
1307 fn kind() -> RuntimeValueKind {
1308 RuntimeValueKind::Structured { queryable: true }
1309 }
1310}
1311
1312impl<K, V> RuntimeValueEncode for BTreeMap<K, V>
1313where
1314 K: Ord + RuntimeValueEncode,
1315 V: RuntimeValueEncode,
1316{
1317 fn to_value(&self) -> Value {
1318 runtime_value_map_collection_to_value(self, std::any::type_name::<Self>())
1319 }
1320}
1321
1322impl<K, V> RuntimeValueDecode for BTreeMap<K, V>
1323where
1324 K: Ord + RuntimeValueDecode,
1325 V: RuntimeValueDecode,
1326{
1327 fn from_value(value: &Value) -> Option<Self> {
1328 runtime_value_btree_map_from_value(value)
1329 }
1330}
1331
1332#[macro_export]
1334macro_rules! impl_runtime_value {
1335 ( $( $type:ty => $variant:ident ),* $(,)? ) => {
1336 $(
1337 impl RuntimeValueMeta for $type {
1338 fn kind() -> RuntimeValueKind {
1339 RuntimeValueKind::Atomic
1340 }
1341 }
1342
1343 impl RuntimeValueEncode for $type {
1344 fn to_value(&self) -> Value {
1345 Value::$variant((*self).into())
1346 }
1347 }
1348
1349 impl RuntimeValueDecode for $type {
1350 fn from_value(value: &Value) -> Option<Self> {
1351 match value {
1352 Value::$variant(v) => (*v).try_into().ok(),
1353 _ => None,
1354 }
1355 }
1356 }
1357 )*
1358 };
1359}
1360
1361impl_runtime_value!(
1362 i8 => Int,
1363 i16 => Int,
1364 i32 => Int,
1365 i64 => Int,
1366 u8 => Uint,
1367 u16 => Uint,
1368 u32 => Uint,
1369 u64 => Uint,
1370 bool => Bool,
1371);
1372
1373pub trait Inner<T> {
1384 fn inner(&self) -> &T;
1385 fn into_inner(self) -> T;
1386}
1387
1388impl<T> Inner<T> for T
1389where
1390 T: Atomic,
1391{
1392 fn inner(&self) -> &T {
1393 self
1394 }
1395
1396 fn into_inner(self) -> T {
1397 self
1398 }
1399}
1400
1401pub trait Repr {
1408 type Inner;
1409
1410 fn repr(&self) -> Self::Inner;
1411 fn from_repr(inner: Self::Inner) -> Self;
1412}
1413
1414pub trait Sanitizer<T> {
1425 fn sanitize(&self, value: &mut T) -> Result<(), String>;
1426
1427 fn sanitize_with_context(
1428 &self,
1429 value: &mut T,
1430 ctx: &mut dyn VisitorContext,
1431 ) -> Result<(), String> {
1432 let _ = ctx;
1433
1434 self.sanitize(value)
1435 }
1436}
1437
1438pub trait Validator<T: ?Sized> {
1445 fn validate(&self, value: &T, ctx: &mut dyn VisitorContext);
1446}