1#[macro_use]
8mod macros;
9mod numeric_value;
10mod visitor;
11
12use crate::{
13 db::{CompositePrimaryKeyValueError, PrimaryKeyComponent, PrimaryKeyValue},
14 error::InternalError,
15 model::field::{FieldKind, FieldModel, FieldStorageDecode},
16 prelude::*,
17 types::{EntityTag, Id},
18 value::{Value, ValueEnum},
19 visitor::VisitorContext,
20};
21use std::collections::{BTreeMap, BTreeSet};
22
23pub use numeric_value::*;
24pub use visitor::*;
25
26pub use ic_memory::stable_structures::storable::Storable;
31pub use serde::{Deserialize, Serialize, de::DeserializeOwned};
32pub use std::{
33 cmp::{Eq, Ordering, PartialEq},
34 convert::From,
35 default::Default,
36 fmt::Debug,
37 hash::Hash,
38 ops::{Add, AddAssign, Deref, DerefMut, Div, DivAssign, Mul, MulAssign, Rem, Sub, SubAssign},
39};
40
41pub trait Path {
55 const PATH: &'static str;
56}
57
58pub trait Kind: Path + 'static {}
64impl<T> Kind for T where T: Path + 'static {}
65
66pub trait CanisterKind: Kind {
72 const COMMIT_MEMORY_ID: u8;
74
75 const COMMIT_STABLE_KEY: &'static str;
77}
78
79pub trait StoreKind: Kind {
85 type Canister: CanisterKind;
86}
87
88pub trait EntityKey {
110 type Key: Copy
111 + Debug
112 + Eq
113 + Ord
114 + KeyValueCodec
115 + PrimaryKeyCodec
116 + PrimaryKeyDecode
117 + EntityKeyBytes
118 + 'static;
119}
120
121pub trait EntityKeyBytes {
126 const BYTE_LEN: usize;
128
129 fn write_bytes(&self, out: &mut [u8]);
131}
132
133macro_rules! impl_entity_key_bytes_numeric {
134 ($($ty:ty),* $(,)?) => {
135 $(
136 impl EntityKeyBytes for $ty {
137 const BYTE_LEN: usize = ::core::mem::size_of::<Self>();
138
139 fn write_bytes(&self, out: &mut [u8]) {
140 assert_eq!(out.len(), Self::BYTE_LEN);
141 out.copy_from_slice(&self.to_be_bytes());
142 }
143 }
144 )*
145 };
146}
147
148impl_entity_key_bytes_numeric!(i8, i16, i32, i64, i128, u8, u16, u32, u64, u128);
149
150impl EntityKeyBytes for () {
151 const BYTE_LEN: usize = 0;
152
153 fn write_bytes(&self, out: &mut [u8]) {
154 assert_eq!(out.len(), Self::BYTE_LEN);
155 }
156}
157
158pub trait ScalarRelationTargetKey {}
166
167macro_rules! impl_scalar_relation_target_key {
168 ($($ty:ty),* $(,)?) => {
169 $(
170 impl ScalarRelationTargetKey for $ty {}
171 )*
172 };
173}
174
175impl_scalar_relation_target_key!(
176 i8,
177 i16,
178 i32,
179 i64,
180 i128,
181 u8,
182 u16,
183 u32,
184 u64,
185 u128,
186 crate::types::Account,
187 crate::types::Principal,
188 crate::types::Subaccount,
189 crate::types::Timestamp,
190 crate::types::Ulid,
191 crate::types::Unit,
192 (),
193);
194
195pub trait ScalarRelationTargetKeyMatchesDeclaredPrimitive<Declared> {}
204
205impl<T> ScalarRelationTargetKeyMatchesDeclaredPrimitive<T> for T where T: ScalarRelationTargetKey {}
206
207pub trait KeyValueCodec {
217 fn to_key_value(&self) -> Value;
218
219 #[must_use]
220 fn from_key_value(value: &Value) -> Option<Self>
221 where
222 Self: Sized;
223}
224
225#[derive(Debug)]
234pub enum PrimaryKeyEncodeError {
235 UnsupportedComponentKind { kind: &'static str },
236
237 TooFewComponents { count: usize, min: usize },
238
239 TooManyComponents { count: usize, max: usize },
240
241 UnitComponent { index: usize },
242}
243
244impl From<CompositePrimaryKeyValueError> for PrimaryKeyEncodeError {
245 fn from(err: CompositePrimaryKeyValueError) -> Self {
246 match err {
247 CompositePrimaryKeyValueError::TooFewComponents { count, min } => {
248 Self::TooFewComponents { count, min }
249 }
250 CompositePrimaryKeyValueError::TooManyComponents { count, max } => {
251 Self::TooManyComponents { count, max }
252 }
253 CompositePrimaryKeyValueError::UnitComponent { index } => Self::UnitComponent { index },
254 }
255 }
256}
257
258impl From<PrimaryKeyEncodeError> for InternalError {
259 fn from(_err: PrimaryKeyEncodeError) -> Self {
260 Self::serialize_unsupported()
261 }
262}
263
264pub trait PrimaryKeyCodec {
273 fn to_primary_key_value(&self) -> Result<PrimaryKeyValue, PrimaryKeyEncodeError>;
274}
275
276pub trait PrimaryKeyDecode: Sized {
286 fn from_primary_key_value(key: &PrimaryKeyValue) -> Result<Self, InternalError>;
287}
288
289fn primary_key_variant_decode_failed(
290 _type_name: &'static str,
291 _key: &PrimaryKeyValue,
292 _expected: &'static str,
293) -> InternalError {
294 InternalError::store_corruption()
295}
296
297fn primary_key_range_decode_failed(
298 _type_name: &'static str,
299 _key: &PrimaryKeyValue,
300) -> InternalError {
301 InternalError::store_corruption()
302}
303
304macro_rules! impl_primary_key_codec_signed {
305 ($($ty:ty),* $(,)?) => {
306 $(
307 impl PrimaryKeyCodec for $ty {
308 fn to_primary_key_value(&self) -> Result<PrimaryKeyValue, PrimaryKeyEncodeError> {
309 Ok(PrimaryKeyValue::Scalar(PrimaryKeyComponent::Int64(i64::from(*self))))
310 }
311 }
312 )*
313 };
314}
315
316macro_rules! impl_primary_key_codec_unsigned {
317 ($($ty:ty),* $(,)?) => {
318 $(
319 impl PrimaryKeyCodec for $ty {
320 fn to_primary_key_value(&self) -> Result<PrimaryKeyValue, PrimaryKeyEncodeError> {
321 Ok(PrimaryKeyValue::Scalar(PrimaryKeyComponent::Nat64(u64::from(*self))))
322 }
323 }
324 )*
325 };
326}
327
328impl<T> KeyValueCodec for T
329where
330 T: RuntimeValueDecode + RuntimeValueEncode,
331{
332 fn to_key_value(&self) -> Value {
333 self.to_value()
334 }
335
336 fn from_key_value(value: &Value) -> Option<Self> {
337 Self::from_value(value)
338 }
339}
340
341impl_primary_key_codec_signed!(i8, i16, i32, i64);
342impl_primary_key_codec_unsigned!(u8, u16, u32, u64);
343
344impl PrimaryKeyCodec for i128 {
345 fn to_primary_key_value(&self) -> Result<PrimaryKeyValue, PrimaryKeyEncodeError> {
346 Ok(PrimaryKeyValue::Scalar(PrimaryKeyComponent::Int128(*self)))
347 }
348}
349
350impl PrimaryKeyCodec for u128 {
351 fn to_primary_key_value(&self) -> Result<PrimaryKeyValue, PrimaryKeyEncodeError> {
352 Ok(PrimaryKeyValue::Scalar(PrimaryKeyComponent::Nat128(*self)))
353 }
354}
355
356macro_rules! impl_primary_key_decode_signed {
357 ($($ty:ty),* $(,)?) => {
358 $(
359 impl PrimaryKeyDecode for $ty {
360 fn from_primary_key_value(key: &PrimaryKeyValue) -> Result<Self, InternalError> {
361 let PrimaryKeyValue::Scalar(PrimaryKeyComponent::Int64(value)) = *key else {
362 return Err(primary_key_variant_decode_failed(
363 ::std::any::type_name::<Self>(),
364 key,
365 "PrimaryKeyComponent::Int64",
366 ));
367 };
368
369 Self::try_from(value).map_err(|_| {
370 primary_key_range_decode_failed(::std::any::type_name::<Self>(), key)
371 })
372 }
373 }
374 )*
375 };
376}
377
378macro_rules! impl_primary_key_decode_unsigned {
379 ($($ty:ty),* $(,)?) => {
380 $(
381 impl PrimaryKeyDecode for $ty {
382 fn from_primary_key_value(key: &PrimaryKeyValue) -> Result<Self, InternalError> {
383 let PrimaryKeyValue::Scalar(PrimaryKeyComponent::Nat64(value)) = *key else {
384 return Err(primary_key_variant_decode_failed(
385 ::std::any::type_name::<Self>(),
386 key,
387 "PrimaryKeyComponent::Nat64",
388 ));
389 };
390
391 Self::try_from(value).map_err(|_| {
392 primary_key_range_decode_failed(::std::any::type_name::<Self>(), key)
393 })
394 }
395 }
396 )*
397 };
398}
399
400impl_primary_key_decode_signed!(i8, i16, i32, i64);
401impl_primary_key_decode_unsigned!(u8, u16, u32, u64);
402
403impl PrimaryKeyDecode for i128 {
404 fn from_primary_key_value(key: &PrimaryKeyValue) -> Result<Self, InternalError> {
405 match *key {
406 PrimaryKeyValue::Scalar(PrimaryKeyComponent::Int128(value)) => Ok(value),
407 _ => Err(primary_key_variant_decode_failed(
408 ::std::any::type_name::<Self>(),
409 key,
410 "PrimaryKeyComponent::Int128",
411 )),
412 }
413 }
414}
415
416impl PrimaryKeyDecode for u128 {
417 fn from_primary_key_value(key: &PrimaryKeyValue) -> Result<Self, InternalError> {
418 match *key {
419 PrimaryKeyValue::Scalar(PrimaryKeyComponent::Nat128(value)) => Ok(value),
420 _ => Err(primary_key_variant_decode_failed(
421 ::std::any::type_name::<Self>(),
422 key,
423 "PrimaryKeyComponent::Nat128",
424 )),
425 }
426 }
427}
428
429impl PrimaryKeyCodec for crate::types::Principal {
430 fn to_primary_key_value(&self) -> Result<PrimaryKeyValue, PrimaryKeyEncodeError> {
431 Ok(PrimaryKeyValue::Scalar(PrimaryKeyComponent::Principal(
432 *self,
433 )))
434 }
435}
436
437impl PrimaryKeyDecode for crate::types::Principal {
438 fn from_primary_key_value(key: &PrimaryKeyValue) -> Result<Self, InternalError> {
439 match *key {
440 PrimaryKeyValue::Scalar(PrimaryKeyComponent::Principal(value)) => Ok(value),
441 _ => Err(primary_key_variant_decode_failed(
442 ::std::any::type_name::<Self>(),
443 key,
444 "PrimaryKeyComponent::Principal",
445 )),
446 }
447 }
448}
449
450impl PrimaryKeyCodec for crate::types::Subaccount {
451 fn to_primary_key_value(&self) -> Result<PrimaryKeyValue, PrimaryKeyEncodeError> {
452 Ok(PrimaryKeyValue::Scalar(PrimaryKeyComponent::Subaccount(
453 *self,
454 )))
455 }
456}
457
458impl PrimaryKeyDecode for crate::types::Subaccount {
459 fn from_primary_key_value(key: &PrimaryKeyValue) -> Result<Self, InternalError> {
460 match *key {
461 PrimaryKeyValue::Scalar(PrimaryKeyComponent::Subaccount(value)) => Ok(value),
462 _ => Err(primary_key_variant_decode_failed(
463 ::std::any::type_name::<Self>(),
464 key,
465 "PrimaryKeyComponent::Subaccount",
466 )),
467 }
468 }
469}
470
471impl PrimaryKeyCodec for crate::types::Account {
472 fn to_primary_key_value(&self) -> Result<PrimaryKeyValue, PrimaryKeyEncodeError> {
473 Ok(PrimaryKeyValue::Scalar(PrimaryKeyComponent::Account(*self)))
474 }
475}
476
477impl PrimaryKeyDecode for crate::types::Account {
478 fn from_primary_key_value(key: &PrimaryKeyValue) -> Result<Self, InternalError> {
479 match *key {
480 PrimaryKeyValue::Scalar(PrimaryKeyComponent::Account(value)) => Ok(value),
481 _ => Err(primary_key_variant_decode_failed(
482 ::std::any::type_name::<Self>(),
483 key,
484 "PrimaryKeyComponent::Account",
485 )),
486 }
487 }
488}
489
490impl PrimaryKeyCodec for crate::types::Timestamp {
491 fn to_primary_key_value(&self) -> Result<PrimaryKeyValue, PrimaryKeyEncodeError> {
492 Ok(PrimaryKeyValue::Scalar(PrimaryKeyComponent::Timestamp(
493 *self,
494 )))
495 }
496}
497
498impl PrimaryKeyDecode for crate::types::Timestamp {
499 fn from_primary_key_value(key: &PrimaryKeyValue) -> Result<Self, InternalError> {
500 match *key {
501 PrimaryKeyValue::Scalar(PrimaryKeyComponent::Timestamp(value)) => Ok(value),
502 _ => Err(primary_key_variant_decode_failed(
503 ::std::any::type_name::<Self>(),
504 key,
505 "PrimaryKeyComponent::Timestamp",
506 )),
507 }
508 }
509}
510
511impl PrimaryKeyCodec for crate::types::Ulid {
512 fn to_primary_key_value(&self) -> Result<PrimaryKeyValue, PrimaryKeyEncodeError> {
513 Ok(PrimaryKeyValue::Scalar(PrimaryKeyComponent::Ulid(*self)))
514 }
515}
516
517impl PrimaryKeyDecode for crate::types::Ulid {
518 fn from_primary_key_value(key: &PrimaryKeyValue) -> Result<Self, InternalError> {
519 match *key {
520 PrimaryKeyValue::Scalar(PrimaryKeyComponent::Ulid(value)) => Ok(value),
521 _ => Err(primary_key_variant_decode_failed(
522 ::std::any::type_name::<Self>(),
523 key,
524 "PrimaryKeyComponent::Ulid",
525 )),
526 }
527 }
528}
529
530impl PrimaryKeyCodec for () {
531 fn to_primary_key_value(&self) -> Result<PrimaryKeyValue, PrimaryKeyEncodeError> {
532 Ok(PrimaryKeyValue::Scalar(PrimaryKeyComponent::Unit))
533 }
534}
535
536impl PrimaryKeyDecode for () {
537 fn from_primary_key_value(key: &PrimaryKeyValue) -> Result<Self, InternalError> {
538 match *key {
539 PrimaryKeyValue::Scalar(PrimaryKeyComponent::Unit) => Ok(()),
540 _ => Err(primary_key_variant_decode_failed(
541 ::std::any::type_name::<Self>(),
542 key,
543 "PrimaryKeyComponent::Unit",
544 )),
545 }
546 }
547}
548
549pub trait RuntimeValueEncode {
561 fn to_value(&self) -> Value;
562}
563
564pub trait RuntimeValueDecode {
575 #[must_use]
576 fn from_value(value: &Value) -> Option<Self>
577 where
578 Self: Sized;
579}
580
581pub fn runtime_value_to_value<T>(value: &T) -> Value
590where
591 T: ?Sized + RuntimeValueEncode,
592{
593 value.to_value()
594}
595
596#[must_use]
605pub fn runtime_value_from_value<T>(value: &Value) -> Option<T>
606where
607 T: RuntimeValueDecode,
608{
609 T::from_value(value)
610}
611
612pub trait PersistedByKindCodec: Sized {
622 fn encode_persisted_slot_payload_by_kind(
624 &self,
625 kind: FieldKind,
626 field_name: &'static str,
627 ) -> Result<Vec<u8>, InternalError>;
628
629 fn decode_persisted_option_slot_payload_by_kind(
633 bytes: &[u8],
634 kind: FieldKind,
635 field_name: &'static str,
636 ) -> Result<Option<Self>, InternalError>;
637}
638
639pub trait PersistedStructuredFieldCodec {
651 fn encode_persisted_structured_payload(&self) -> Result<Vec<u8>, InternalError>;
653
654 fn decode_persisted_structured_payload(bytes: &[u8]) -> Result<Self, InternalError>
656 where
657 Self: Sized;
658}
659
660pub trait EntitySchema: EntityKey {
671 const NAME: &'static str;
672 const MODEL: &'static EntityModel;
673}
674
675pub trait EntityPlacement {
689 type Store: StoreKind;
690 type Canister: CanisterKind;
691}
692
693pub trait EntityKind: EntitySchema + EntityPlacement + Kind + TypeKind {
703 const ENTITY_TAG: EntityTag;
704}
705
706pub trait EntityValue: EntityKey + FieldProjection + Sized {
724 fn id(&self) -> Id<Self>;
725}
726
727pub struct EntityCreateMaterialization<E> {
736 entity: E,
737 authored_slots: Vec<usize>,
738}
739
740impl<E> EntityCreateMaterialization<E> {
741 #[must_use]
743 pub const fn new(entity: E, authored_slots: Vec<usize>) -> Self {
744 Self {
745 entity,
746 authored_slots,
747 }
748 }
749
750 #[must_use]
752 pub fn into_entity(self) -> E {
753 self.entity
754 }
755
756 #[must_use]
758 pub const fn authored_slots(&self) -> &[usize] {
759 self.authored_slots.as_slice()
760 }
761}
762
763pub trait EntityCreateInput: Sized {
772 type Entity: EntityValue;
773
774 fn materialize_create(self)
776 -> Result<EntityCreateMaterialization<Self::Entity>, InternalError>;
777}
778
779pub trait EntityCreateType: EntityValue {
789 type Create: EntityCreateInput<Entity = Self>;
790}
791
792pub trait SingletonEntity: EntityValue {}
794
795pub trait TypeKind:
813 Kind + Clone + DeserializeOwned + Sanitize + Validate + Visitable + PartialEq
814{
815}
816
817impl<T> TypeKind for T where
818 T: Kind + Clone + DeserializeOwned + PartialEq + Sanitize + Validate + Visitable
819{
820}
821
822pub trait FieldTypeMeta {
831 const KIND: FieldKind;
833
834 const STORAGE_DECODE: FieldStorageDecode;
836
837 const NESTED_FIELDS: &'static [FieldModel] = &[];
839}
840
841pub trait PersistedFieldMetaCodec: FieldTypeMeta + Sized {
852 fn encode_persisted_slot_payload_by_meta(
855 &self,
856 field_name: &'static str,
857 ) -> Result<Vec<u8>, InternalError>;
858
859 fn decode_persisted_slot_payload_by_meta(
862 bytes: &[u8],
863 field_name: &'static str,
864 ) -> Result<Self, InternalError>;
865
866 fn encode_persisted_option_slot_payload_by_meta(
869 value: &Option<Self>,
870 field_name: &'static str,
871 ) -> Result<Vec<u8>, InternalError>;
872
873 fn decode_persisted_option_slot_payload_by_meta(
876 bytes: &[u8],
877 field_name: &'static str,
878 ) -> Result<Option<Self>, InternalError>;
879}
880
881pub trait PersistedFieldSlotCodec: Sized {
891 fn encode_persisted_slot(&self, field_name: &'static str) -> Result<Vec<u8>, InternalError>;
894
895 fn decode_persisted_slot(bytes: &[u8], field_name: &'static str)
898 -> Result<Self, InternalError>;
899
900 fn encode_persisted_option_slot(
903 value: &Option<Self>,
904 field_name: &'static str,
905 ) -> Result<Vec<u8>, InternalError>;
906
907 fn decode_persisted_option_slot(
910 bytes: &[u8],
911 field_name: &'static str,
912 ) -> Result<Option<Self>, InternalError>;
913}
914
915impl<T> FieldTypeMeta for Option<T>
916where
917 T: FieldTypeMeta,
918{
919 const KIND: FieldKind = T::KIND;
920 const STORAGE_DECODE: FieldStorageDecode = T::STORAGE_DECODE;
921 const NESTED_FIELDS: &'static [FieldModel] = T::NESTED_FIELDS;
922}
923
924impl<T> FieldTypeMeta for Box<T>
925where
926 T: FieldTypeMeta,
927{
928 const KIND: FieldKind = T::KIND;
929 const STORAGE_DECODE: FieldStorageDecode = T::STORAGE_DECODE;
930 const NESTED_FIELDS: &'static [FieldModel] = T::NESTED_FIELDS;
931}
932
933impl<T> FieldTypeMeta for Vec<T>
937where
938 T: FieldTypeMeta,
939{
940 const KIND: FieldKind = FieldKind::List(&T::KIND);
941 const STORAGE_DECODE: FieldStorageDecode = FieldStorageDecode::Value;
942}
943
944impl<T> FieldTypeMeta for BTreeSet<T>
945where
946 T: FieldTypeMeta,
947{
948 const KIND: FieldKind = FieldKind::Set(&T::KIND);
949 const STORAGE_DECODE: FieldStorageDecode = FieldStorageDecode::Value;
950}
951
952impl<K, V> FieldTypeMeta for BTreeMap<K, V>
953where
954 K: FieldTypeMeta,
955 V: FieldTypeMeta,
956{
957 const KIND: FieldKind = FieldKind::Map {
958 key: &K::KIND,
959 value: &V::KIND,
960 };
961 const STORAGE_DECODE: FieldStorageDecode = FieldStorageDecode::Value;
962}
963
964pub trait Collection {
977 type Item;
978
979 type Iter<'a>: Iterator<Item = &'a Self::Item> + 'a
981 where
982 Self: 'a;
983
984 fn iter(&self) -> Self::Iter<'_>;
986
987 fn len(&self) -> usize;
989
990 fn is_empty(&self) -> bool {
992 self.len() == 0
993 }
994}
995
996pub trait MapCollection {
1005 type Key;
1006 type Value;
1007
1008 type Iter<'a>: Iterator<Item = (&'a Self::Key, &'a Self::Value)> + 'a
1010 where
1011 Self: 'a;
1012
1013 fn iter(&self) -> Self::Iter<'_>;
1015
1016 fn len(&self) -> usize;
1018
1019 fn is_empty(&self) -> bool {
1021 self.len() == 0
1022 }
1023}
1024
1025impl<T> Collection for Vec<T> {
1026 type Item = T;
1027 type Iter<'a>
1028 = std::slice::Iter<'a, T>
1029 where
1030 Self: 'a;
1031
1032 fn iter(&self) -> Self::Iter<'_> {
1033 self.as_slice().iter()
1034 }
1035
1036 fn len(&self) -> usize {
1037 self.as_slice().len()
1038 }
1039}
1040
1041impl<T> Collection for BTreeSet<T> {
1042 type Item = T;
1043 type Iter<'a>
1044 = std::collections::btree_set::Iter<'a, T>
1045 where
1046 Self: 'a;
1047
1048 fn iter(&self) -> Self::Iter<'_> {
1049 self.iter()
1050 }
1051
1052 fn len(&self) -> usize {
1053 self.len()
1054 }
1055}
1056
1057impl<K, V> MapCollection for BTreeMap<K, V> {
1058 type Key = K;
1059 type Value = V;
1060 type Iter<'a>
1061 = std::collections::btree_map::Iter<'a, K, V>
1062 where
1063 Self: 'a;
1064
1065 fn iter(&self) -> Self::Iter<'_> {
1066 self.iter()
1067 }
1068
1069 fn len(&self) -> usize {
1070 self.len()
1071 }
1072}
1073
1074pub trait EnumValue {
1075 fn to_value_enum(&self) -> ValueEnum;
1076}
1077
1078pub trait FieldProjection {
1079 fn get_value_by_index(&self, index: usize) -> Option<Value>;
1081}
1082
1083#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1091pub enum RuntimeValueKind {
1092 Atomic,
1094
1095 Structured {
1098 queryable: bool,
1100 },
1101}
1102
1103impl RuntimeValueKind {
1104 #[must_use]
1105 pub const fn is_queryable(self) -> bool {
1106 match self {
1107 Self::Atomic => true,
1108 Self::Structured { queryable } => queryable,
1109 }
1110 }
1111}
1112
1113pub trait RuntimeValueMeta {
1122 fn kind() -> RuntimeValueKind
1123 where
1124 Self: Sized;
1125}
1126
1127pub fn runtime_value_collection_to_value<C>(collection: &C) -> Value
1136where
1137 C: Collection,
1138 C::Item: RuntimeValueEncode,
1139{
1140 Value::List(
1141 collection
1142 .iter()
1143 .map(RuntimeValueEncode::to_value)
1144 .collect(),
1145 )
1146}
1147
1148#[must_use]
1157pub fn runtime_value_vec_from_value<T>(value: &Value) -> Option<Vec<T>>
1158where
1159 T: RuntimeValueDecode,
1160{
1161 let Value::List(values) = value else {
1162 return None;
1163 };
1164
1165 let mut out = Vec::with_capacity(values.len());
1166 for value in values {
1167 out.push(T::from_value(value)?);
1168 }
1169
1170 Some(out)
1171}
1172
1173#[must_use]
1182pub fn runtime_value_btree_set_from_value<T>(value: &Value) -> Option<BTreeSet<T>>
1183where
1184 T: Ord + RuntimeValueDecode,
1185{
1186 let Value::List(values) = value else {
1187 return None;
1188 };
1189
1190 let mut out = BTreeSet::new();
1191 for value in values {
1192 let item = T::from_value(value)?;
1193 if !out.insert(item) {
1194 return None;
1195 }
1196 }
1197
1198 Some(out)
1199}
1200
1201pub fn runtime_value_map_collection_to_value<M>(map: &M, path: &'static str) -> Value
1211where
1212 M: MapCollection,
1213 M::Key: RuntimeValueEncode,
1214 M::Value: RuntimeValueEncode,
1215{
1216 let mut entries: Vec<(Value, Value)> = map
1217 .iter()
1218 .map(|(key, value)| {
1219 (
1220 RuntimeValueEncode::to_value(key),
1221 RuntimeValueEncode::to_value(value),
1222 )
1223 })
1224 .collect();
1225
1226 if let Err(err) = Value::validate_map_entries(entries.as_slice()) {
1227 debug_assert!(false, "invalid map field value for {path}: {err}");
1228 return Value::Map(entries);
1229 }
1230
1231 Value::sort_map_entries_in_place(entries.as_mut_slice());
1232
1233 for i in 1..entries.len() {
1234 let (left_key, _) = &entries[i - 1];
1235 let (right_key, _) = &entries[i];
1236 if Value::canonical_cmp_key(left_key, right_key) == Ordering::Equal {
1237 debug_assert!(
1238 false,
1239 "duplicate map key in {path} after value-surface canonicalization",
1240 );
1241 break;
1242 }
1243 }
1244
1245 Value::Map(entries)
1246}
1247
1248#[must_use]
1257pub fn runtime_value_btree_map_from_value<K, V>(value: &Value) -> Option<BTreeMap<K, V>>
1258where
1259 K: Ord + RuntimeValueDecode,
1260 V: RuntimeValueDecode,
1261{
1262 let Value::Map(entries) = value else {
1263 return None;
1264 };
1265
1266 let normalized = Value::normalize_map_entries(entries.clone()).ok()?;
1267 if normalized.as_slice() != entries.as_slice() {
1268 return None;
1269 }
1270
1271 let mut map = BTreeMap::new();
1272 for (entry_key, entry_value) in normalized {
1273 let key = K::from_value(&entry_key)?;
1274 let value = V::from_value(&entry_value)?;
1275 map.insert(key, value);
1276 }
1277
1278 Some(map)
1279}
1280
1281#[must_use]
1290pub fn runtime_value_from_vec_into<T, I>(entries: Vec<I>) -> Vec<T>
1291where
1292 I: Into<T>,
1293{
1294 entries.into_iter().map(Into::into).collect()
1295}
1296
1297#[must_use]
1306pub fn runtime_value_from_vec_into_btree_set<T, I>(entries: Vec<I>) -> BTreeSet<T>
1307where
1308 I: Into<T>,
1309 T: Ord,
1310{
1311 entries.into_iter().map(Into::into).collect()
1312}
1313
1314#[must_use]
1323pub fn runtime_value_from_vec_into_btree_map<K, V, IK, IV>(entries: Vec<(IK, IV)>) -> BTreeMap<K, V>
1324where
1325 IK: Into<K>,
1326 IV: Into<V>,
1327 K: Ord,
1328{
1329 entries
1330 .into_iter()
1331 .map(|(key, value)| (key.into(), value.into()))
1332 .collect()
1333}
1334
1335#[must_use]
1344pub fn runtime_value_into<T, U>(value: U) -> T
1345where
1346 U: Into<T>,
1347{
1348 value.into()
1349}
1350
1351impl RuntimeValueMeta for &str {
1352 fn kind() -> RuntimeValueKind {
1353 RuntimeValueKind::Atomic
1354 }
1355}
1356
1357impl RuntimeValueEncode for &str {
1358 fn to_value(&self) -> Value {
1359 Value::Text((*self).to_string())
1360 }
1361}
1362
1363impl RuntimeValueDecode for &str {
1364 fn from_value(_value: &Value) -> Option<Self> {
1365 None
1366 }
1367}
1368
1369impl RuntimeValueMeta for String {
1370 fn kind() -> RuntimeValueKind {
1371 RuntimeValueKind::Atomic
1372 }
1373}
1374
1375impl RuntimeValueEncode for String {
1376 fn to_value(&self) -> Value {
1377 Value::Text(self.clone())
1378 }
1379}
1380
1381impl RuntimeValueDecode for String {
1382 fn from_value(value: &Value) -> Option<Self> {
1383 match value {
1384 Value::Text(v) => Some(v.clone()),
1385 _ => None,
1386 }
1387 }
1388}
1389
1390impl<T: RuntimeValueMeta> RuntimeValueMeta for Option<T> {
1391 fn kind() -> RuntimeValueKind {
1392 T::kind()
1393 }
1394}
1395
1396impl<T: RuntimeValueEncode> RuntimeValueEncode for Option<T> {
1397 fn to_value(&self) -> Value {
1398 match self {
1399 Some(v) => v.to_value(),
1400 None => Value::Null,
1401 }
1402 }
1403}
1404
1405impl<T: RuntimeValueDecode> RuntimeValueDecode for Option<T> {
1406 fn from_value(value: &Value) -> Option<Self> {
1407 if matches!(value, Value::Null) {
1408 return Some(None);
1409 }
1410
1411 T::from_value(value).map(Some)
1412 }
1413}
1414
1415impl<T: RuntimeValueMeta> RuntimeValueMeta for Box<T> {
1416 fn kind() -> RuntimeValueKind {
1417 T::kind()
1418 }
1419}
1420
1421impl<T: RuntimeValueEncode> RuntimeValueEncode for Box<T> {
1422 fn to_value(&self) -> Value {
1423 (**self).to_value()
1424 }
1425}
1426
1427impl<T: RuntimeValueDecode> RuntimeValueDecode for Box<T> {
1428 fn from_value(value: &Value) -> Option<Self> {
1429 T::from_value(value).map(Self::new)
1430 }
1431}
1432
1433impl<T> RuntimeValueMeta for Vec<T> {
1434 fn kind() -> RuntimeValueKind {
1435 RuntimeValueKind::Structured { queryable: true }
1436 }
1437}
1438
1439impl<T: RuntimeValueEncode> RuntimeValueEncode for Vec<T> {
1440 fn to_value(&self) -> Value {
1441 runtime_value_collection_to_value(self)
1442 }
1443}
1444
1445impl<T: RuntimeValueDecode> RuntimeValueDecode for Vec<T> {
1446 fn from_value(value: &Value) -> Option<Self> {
1447 runtime_value_vec_from_value(value)
1448 }
1449}
1450
1451impl<T> RuntimeValueMeta for BTreeSet<T>
1452where
1453 T: Ord,
1454{
1455 fn kind() -> RuntimeValueKind {
1456 RuntimeValueKind::Structured { queryable: true }
1457 }
1458}
1459
1460impl<T> RuntimeValueEncode for BTreeSet<T>
1461where
1462 T: Ord + RuntimeValueEncode,
1463{
1464 fn to_value(&self) -> Value {
1465 runtime_value_collection_to_value(self)
1466 }
1467}
1468
1469impl<T> RuntimeValueDecode for BTreeSet<T>
1470where
1471 T: Ord + RuntimeValueDecode,
1472{
1473 fn from_value(value: &Value) -> Option<Self> {
1474 runtime_value_btree_set_from_value(value)
1475 }
1476}
1477
1478impl<K, V> RuntimeValueMeta for BTreeMap<K, V>
1479where
1480 K: Ord,
1481{
1482 fn kind() -> RuntimeValueKind {
1483 RuntimeValueKind::Structured { queryable: true }
1484 }
1485}
1486
1487impl<K, V> RuntimeValueEncode for BTreeMap<K, V>
1488where
1489 K: Ord + RuntimeValueEncode,
1490 V: RuntimeValueEncode,
1491{
1492 fn to_value(&self) -> Value {
1493 runtime_value_map_collection_to_value(self, std::any::type_name::<Self>())
1494 }
1495}
1496
1497impl<K, V> RuntimeValueDecode for BTreeMap<K, V>
1498where
1499 K: Ord + RuntimeValueDecode,
1500 V: RuntimeValueDecode,
1501{
1502 fn from_value(value: &Value) -> Option<Self> {
1503 runtime_value_btree_map_from_value(value)
1504 }
1505}
1506
1507#[macro_export]
1509macro_rules! impl_runtime_value {
1510 ( $( $type:ty => $variant:ident ),* $(,)? ) => {
1511 $(
1512 impl RuntimeValueMeta for $type {
1513 fn kind() -> RuntimeValueKind {
1514 RuntimeValueKind::Atomic
1515 }
1516 }
1517
1518 impl RuntimeValueEncode for $type {
1519 fn to_value(&self) -> Value {
1520 Value::$variant((*self).into())
1521 }
1522 }
1523
1524 impl RuntimeValueDecode for $type {
1525 fn from_value(value: &Value) -> Option<Self> {
1526 match value {
1527 Value::$variant(v) => (*v).try_into().ok(),
1528 _ => None,
1529 }
1530 }
1531 }
1532 )*
1533 };
1534}
1535
1536impl_runtime_value!(
1537 i8 => Int64,
1538 i16 => Int64,
1539 i32 => Int64,
1540 i64 => Int64,
1541 i128 => Int128,
1542 u8 => Nat64,
1543 u16 => Nat64,
1544 u32 => Nat64,
1545 u64 => Nat64,
1546 u128 => Nat128,
1547 bool => Bool,
1548);
1549
1550pub trait Inner<T> {
1561 fn inner(&self) -> &T;
1562 fn into_inner(self) -> T;
1563}
1564
1565pub trait Repr {
1572 type Inner;
1573
1574 fn repr(&self) -> Self::Inner;
1575 fn from_repr(inner: Self::Inner) -> Self;
1576}
1577
1578pub trait Sanitizer<T> {
1589 fn sanitize(&self, value: &mut T) -> Result<(), String>;
1590
1591 fn sanitize_with_context(
1592 &self,
1593 value: &mut T,
1594 ctx: &mut dyn VisitorContext,
1595 ) -> Result<(), String> {
1596 let _ = ctx;
1597
1598 self.sanitize(value)
1599 }
1600}
1601
1602pub trait Validator<T: ?Sized> {
1609 fn validate(&self, value: &T, ctx: &mut dyn VisitorContext);
1610}