1extern crate alloc;
2
3use alloc::{
4 borrow::ToOwned as _, boxed::Box, collections::BTreeMap, format, string::String, vec, vec::Vec,
5};
6use core::fmt::{self, Display};
7
8pub use aranya_id::BaseId;
9use aranya_id::{Id, IdTag};
10use aranya_policy_ast::{Ident, Identifier, Span, Text, TypeKind, VType};
11use serde::{Deserialize, Serialize};
12
13use super::ffi::Type;
14
15#[derive(Debug, thiserror::Error)]
16pub enum ValueConversionError {
18 #[error("expected type {want}, but got {got}: {msg}")]
20 InvalidType {
21 want: String,
23 got: String,
25 msg: String,
27 },
28 #[error("invalid struct member `{0}`")]
30 InvalidStructMember(Identifier),
31 #[error("value out of range")]
33 OutOfRange,
34 #[error("bad state")]
36 BadState,
37}
38
39impl ValueConversionError {
40 pub fn invalid_type(
42 want: impl Into<String>,
43 got: impl Into<String>,
44 msg: impl Into<String>,
45 ) -> Self {
46 Self::InvalidType {
47 want: want.into(),
48 got: got.into(),
49 msg: msg.into(),
50 }
51 }
52}
53
54pub trait Typed {
57 const TYPE: Type<'static>;
59}
60
61macro_rules! impl_typed {
62 ($name:ty => $type:ident) => {
63 impl Typed for $name {
64 const TYPE: Type<'static> = Type::$type;
65 }
66 };
67}
68
69impl_typed!(Text => String);
70
71impl_typed!(Vec<u8> => Bytes);
72impl_typed!(&[u8] => Bytes);
73
74impl_typed!(isize => Int);
75impl_typed!(i64 => Int);
76impl_typed!(i32 => Int);
77impl_typed!(i16 => Int);
78impl_typed!(i8 => Int);
79
80impl_typed!(usize => Int);
81impl_typed!(u64 => Int);
82impl_typed!(u32 => Int);
83impl_typed!(u16 => Int);
84impl_typed!(u8 => Int);
85
86impl_typed!(bool => Bool);
87
88impl<Tag: IdTag> Typed for Id<Tag> {
89 const TYPE: Type<'static> = Type::Id;
90}
91
92impl<T: Typed> Typed for Option<T> {
93 const TYPE: Type<'static> = Type::Optional(const { &T::TYPE });
94}
95
96#[derive(
98 Debug,
99 Clone,
100 PartialEq,
101 Eq,
102 Serialize,
103 Deserialize,
104 rkyv::Archive,
105 rkyv::Deserialize,
106 rkyv::Serialize,
107)]
108#[rkyv(serialize_bounds(
109 __S: rkyv::ser::Writer + rkyv::ser::Allocator,
110 __S::Error: rkyv::rancor::Source,
111))]
112#[rkyv(deserialize_bounds(__D::Error: rkyv::rancor::Source))]
113#[rkyv(bytecheck(
114 bounds(
115 __C: rkyv::validation::ArchiveContext,
116 __C::Error: rkyv::rancor::Source,
117 )
118))]
119pub enum Value {
120 Int(i64),
122 Bool(bool),
124 String(Text),
126 Bytes(Vec<u8>),
128 Struct(#[rkyv(omit_bounds)] Struct),
130 Fact(Fact),
132 Id(BaseId),
134 Enum(Identifier, i64),
136 Identifier(Identifier),
138 Option(#[rkyv(omit_bounds)] Option<Box<Self>>),
140}
141
142impl Value {
143 pub const NONE: Self = Self::Option(None);
145}
146
147pub trait TryFromValue: Sized {
152 fn try_from_value(value: Value) -> Result<Self, ValueConversionError>;
154}
155
156impl<T: TryFromValue> TryFromValue for Option<T> {
157 fn try_from_value(value: Value) -> Result<Self, ValueConversionError> {
158 let Value::Option(opt) = value else {
159 return Err(ValueConversionError::InvalidType {
160 want: "Option".into(),
161 got: value.type_name(),
162 msg: format!("Value -> {}", core::any::type_name::<Self>()),
163 });
164 };
165 opt.map(|v| T::try_from_value(*v)).transpose()
166 }
167}
168
169impl<T: TryFrom<Value, Error = ValueConversionError>> TryFromValue for T {
170 fn try_from_value(value: Value) -> Result<Self, ValueConversionError> {
171 Self::try_from(value)
172 }
173}
174
175pub trait TryAsMut<T: ?Sized> {
177 type Error;
179
180 fn try_as_mut(&mut self) -> Result<&mut T, Self::Error>;
183}
184
185impl Value {
186 pub fn vtype(&self) -> Option<TypeKind> {
188 match self {
189 Self::Int(_) => Some(TypeKind::Int),
190 Self::Bool(_) => Some(TypeKind::Bool),
191 Self::String(_) => Some(TypeKind::String),
192 Self::Bytes(_) => Some(TypeKind::Bytes),
193 Self::Id(_) => Some(TypeKind::Id),
194 Self::Enum(name, _) => Some(TypeKind::Enum(Ident {
195 name: name.to_owned(),
196 span: Span::default(),
197 })),
198 Self::Struct(s) => Some(TypeKind::Struct(Ident {
199 name: s.name.clone(),
200 span: Span::default(),
201 })),
202 _ => None,
203 }
204 }
205
206 pub fn type_name(&self) -> String {
208 match self {
209 Self::Int(_) => String::from("Int"),
210 Self::Bool(_) => String::from("Bool"),
211 Self::String(_) => String::from("String"),
212 Self::Bytes(_) => String::from("Bytes"),
213 Self::Struct(s) => format!("Struct {}", s.name),
214 Self::Fact(f) => format!("Fact {}", f.name),
215 Self::Id(_) => String::from("Id"),
216 Self::Enum(name, _) => format!("Enum {}", name),
217 Self::Identifier(_) => String::from("Identifier"),
218 Self::Option(Some(inner)) => format!("Option[{}]", inner.type_name()),
219 Self::Option(None) => String::from("Option[_]"),
220 }
221 }
222
223 pub fn fits_type(&self, expected_type: &VType) -> bool {
237 use aranya_policy_ast::TypeKind;
238 match (self, &expected_type.kind) {
239 (Self::Int(_), TypeKind::Int) => true,
240 (Self::Bool(_), TypeKind::Bool) => true,
241 (Self::String(_), TypeKind::String) => true,
242 (Self::Bytes(_), TypeKind::Bytes) => true,
243 (Self::Struct(s), TypeKind::Struct(ident)) => s.name == ident.name,
244 (Self::Id(_), TypeKind::Id) => true,
245 (Self::Enum(name, _), TypeKind::Enum(ident)) => *name == ident.name,
246 (Self::Option(Some(value)), TypeKind::Optional(ty)) => value.fits_type(ty),
247 (Self::Option(None), TypeKind::Optional(_)) => true,
248 _ => false,
249 }
250 }
251}
252
253impl<T: Into<Self>> From<Option<T>> for Value {
254 fn from(value: Option<T>) -> Self {
255 Self::Option(value.map(Into::into).map(Box::new))
256 }
257}
258
259impl From<i64> for Value {
260 fn from(value: i64) -> Self {
261 Self::Int(value)
262 }
263}
264
265impl From<bool> for Value {
266 fn from(value: bool) -> Self {
267 Self::Bool(value)
268 }
269}
270
271impl From<Text> for Value {
272 fn from(value: Text) -> Self {
273 Self::String(value)
274 }
275}
276
277impl From<Identifier> for Value {
278 fn from(value: Identifier) -> Self {
279 Self::Identifier(value)
280 }
281}
282
283impl From<&[u8]> for Value {
284 fn from(value: &[u8]) -> Self {
285 Self::Bytes(value.to_owned())
286 }
287}
288
289impl From<Vec<u8>> for Value {
290 fn from(value: Vec<u8>) -> Self {
291 Self::Bytes(value)
292 }
293}
294
295impl From<Struct> for Value {
296 fn from(value: Struct) -> Self {
297 Self::Struct(value)
298 }
299}
300
301impl From<Fact> for Value {
302 fn from(value: Fact) -> Self {
303 Self::Fact(value)
304 }
305}
306
307impl<Tag: IdTag> From<Id<Tag>> for Value {
308 fn from(id: Id<Tag>) -> Self {
309 Self::Id(id.as_base())
310 }
311}
312
313impl TryFrom<Value> for i64 {
314 type Error = ValueConversionError;
315
316 fn try_from(value: Value) -> Result<Self, Self::Error> {
317 if let Value::Int(i) = value {
318 return Ok(i);
319 }
320 Err(ValueConversionError::invalid_type(
321 "Int",
322 value.type_name(),
323 "Value -> i64",
324 ))
325 }
326}
327
328impl TryFrom<Value> for bool {
329 type Error = ValueConversionError;
330
331 fn try_from(value: Value) -> Result<Self, Self::Error> {
332 if let Value::Bool(b) = value {
333 return Ok(b);
334 }
335 Err(ValueConversionError::invalid_type(
336 "Bool",
337 value.type_name(),
338 "Value -> bool",
339 ))
340 }
341}
342
343impl TryFrom<Value> for Text {
344 type Error = ValueConversionError;
345
346 fn try_from(value: Value) -> Result<Self, Self::Error> {
347 if let Value::String(s) = value {
348 return Ok(s);
349 }
350 Err(ValueConversionError::invalid_type(
351 "String",
352 value.type_name(),
353 "Value -> Text",
354 ))
355 }
356}
357
358impl TryFrom<Value> for Identifier {
359 type Error = ValueConversionError;
360
361 fn try_from(value: Value) -> Result<Self, Self::Error> {
362 let Value::Identifier(text) = value else {
363 return Err(ValueConversionError::invalid_type(
364 "Identifier",
365 value.type_name(),
366 "Value -> Identifier",
367 ));
368 };
369 Ok(text)
370 }
371}
372
373impl TryFrom<Value> for Vec<u8> {
374 type Error = ValueConversionError;
375
376 fn try_from(value: Value) -> Result<Self, Self::Error> {
377 if let Value::Bytes(v) = value {
378 return Ok(v);
379 }
380 Err(ValueConversionError::invalid_type(
381 "Bytes",
382 value.type_name(),
383 "Value -> Vec<u8>",
384 ))
385 }
386}
387
388impl TryFrom<Value> for Struct {
389 type Error = ValueConversionError;
390
391 fn try_from(value: Value) -> Result<Self, Self::Error> {
392 if let Value::Struct(s) = value {
393 return Ok(s);
394 }
395 Err(ValueConversionError::invalid_type(
396 "Struct",
397 value.type_name(),
398 "Value -> Struct",
399 ))
400 }
401}
402
403impl TryFrom<Value> for Fact {
404 type Error = ValueConversionError;
405
406 fn try_from(value: Value) -> Result<Self, Self::Error> {
407 if let Value::Fact(f) = value {
408 return Ok(f);
409 }
410 Err(ValueConversionError::invalid_type(
411 "Fact",
412 value.type_name(),
413 "Value -> Fact",
414 ))
415 }
416}
417
418impl<Tag: IdTag> TryFrom<Value> for Id<Tag> {
419 type Error = ValueConversionError;
420
421 fn try_from(value: Value) -> Result<Self, Self::Error> {
422 if let Value::Id(id) = value {
423 Ok(Self::from_base(id))
424 } else {
425 Err(ValueConversionError::invalid_type(
426 "Id",
427 value.type_name(),
428 "Value -> Id",
429 ))
430 }
431 }
432}
433
434impl TryAsMut<i64> for Value {
435 type Error = ValueConversionError;
436 fn try_as_mut(&mut self) -> Result<&mut i64, Self::Error> {
437 if let Self::Int(s) = self {
438 return Ok(s);
439 }
440 Err(ValueConversionError::invalid_type(
441 "i64",
442 self.type_name(),
443 "Value -> i64",
444 ))
445 }
446}
447
448impl TryAsMut<bool> for Value {
449 type Error = ValueConversionError;
450 fn try_as_mut(&mut self) -> Result<&mut bool, Self::Error> {
451 if let Self::Bool(b) = self {
452 return Ok(b);
453 }
454 Err(ValueConversionError::invalid_type(
455 "bool",
456 self.type_name(),
457 "Value -> bool",
458 ))
459 }
460}
461
462impl TryAsMut<[u8]> for Value {
463 type Error = ValueConversionError;
464 fn try_as_mut(&mut self) -> Result<&mut [u8], Self::Error> {
465 if let Self::Bytes(v) = self {
466 return Ok(v);
467 }
468 Err(ValueConversionError::invalid_type(
469 "Vec<u8>",
470 self.type_name(),
471 "Value -> [u8]",
472 ))
473 }
474}
475
476impl TryAsMut<Struct> for Value {
477 type Error = ValueConversionError;
478 fn try_as_mut(&mut self) -> Result<&mut Struct, Self::Error> {
479 if let Self::Struct(s) = self {
480 return Ok(s);
481 }
482 Err(ValueConversionError::invalid_type(
483 "Struct",
484 self.type_name(),
485 "Value -> Struct",
486 ))
487 }
488}
489
490impl TryAsMut<Fact> for Value {
491 type Error = ValueConversionError;
492 fn try_as_mut(&mut self) -> Result<&mut Fact, Self::Error> {
493 if let Self::Fact(f) = self {
494 return Ok(f);
495 }
496 Err(ValueConversionError::invalid_type(
497 "Fact",
498 self.type_name(),
499 "Value -> Fact",
500 ))
501 }
502}
503
504impl Display for Value {
505 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
506 match self {
507 Self::Int(i) => write!(f, "{}", i),
508 Self::Bool(b) => write!(f, "{}", b),
509 Self::String(s) => write!(f, "\"{}\"", s),
510 Self::Bytes(v) => {
511 write!(f, "b:")?;
512 for b in v {
513 write!(f, "{:02X}", b)?;
514 }
515 Ok(())
516 }
517 Self::Struct(s) => s.fmt(f),
518 Self::Fact(fa) => fa.fmt(f),
519 Self::Id(id) => id.fmt(f),
520 Self::Enum(name, value) => write!(f, "{name}::{value}"),
521 Self::Identifier(name) => write!(f, "{name}"),
522 Self::Option(Some(v)) => write!(f, "Some({v})"),
523 Self::Option(None) => write!(f, "None"),
524 }
525 }
526}
527
528#[derive(
531 Debug,
532 Clone,
533 PartialEq,
534 Eq,
535 Hash,
536 PartialOrd,
537 Ord,
538 Serialize,
539 Deserialize,
540 rkyv::Archive,
541 rkyv::Deserialize,
542 rkyv::Serialize,
543)]
544#[cfg_attr(feature = "proptest", derive(proptest_derive::Arbitrary))]
545pub enum HashableValue {
546 Int(i64),
548 Bool(bool),
550 String(Text),
552 Id(BaseId),
554 Enum(Identifier, i64),
556}
557
558impl HashableValue {
559 pub fn vtype(&self) -> TypeKind {
562 use aranya_policy_ast::TypeKind;
563 match self {
564 Self::Int(_) => TypeKind::Int,
565 Self::Bool(_) => TypeKind::Bool,
566 Self::String(_) => TypeKind::String,
567 Self::Id(_) => TypeKind::Id,
568 Self::Enum(id, _) => TypeKind::Enum(Ident {
569 name: id.clone(),
570 span: Span::default(),
571 }),
572 }
573 }
574}
575
576impl TryFrom<Value> for HashableValue {
577 type Error = ValueConversionError;
578
579 fn try_from(value: Value) -> Result<Self, Self::Error> {
580 match value {
581 Value::Int(v) => Ok(Self::Int(v)),
582 Value::Bool(v) => Ok(Self::Bool(v)),
583 Value::String(v) => Ok(Self::String(v)),
584 Value::Id(v) => Ok(Self::Id(v)),
585 Value::Enum(id, value) => Ok(Self::Enum(id, value)),
586 _ => Err(ValueConversionError::invalid_type(
587 "Int | Bool | String | Id | Enum",
588 value.type_name(),
589 "Value -> HashableValue",
590 )),
591 }
592 }
593}
594
595impl From<HashableValue> for Value {
596 fn from(value: HashableValue) -> Self {
597 match value {
598 HashableValue::Int(v) => Self::Int(v),
599 HashableValue::Bool(v) => Self::Bool(v),
600 HashableValue::String(v) => Self::String(v),
601 HashableValue::Id(v) => Self::Id(v),
602 HashableValue::Enum(id, value) => Self::Enum(id, value),
603 }
604 }
605}
606
607impl Display for HashableValue {
608 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
609 let real_value: Value = self.to_owned().into();
610 write!(f, "{}", real_value)
611 }
612}
613
614#[derive(
617 Debug,
618 Clone,
619 PartialEq,
620 Eq,
621 PartialOrd,
622 Ord,
623 Hash,
624 Serialize,
625 Deserialize,
626 rkyv::Archive,
627 rkyv::Deserialize,
628 rkyv::Serialize,
629)]
630#[cfg_attr(feature = "proptest", derive(proptest_derive::Arbitrary))]
631pub struct FactKey {
632 pub identifier: Identifier,
634 pub value: HashableValue,
636}
637
638impl FactKey {
639 pub fn new(name: Identifier, value: HashableValue) -> Self {
641 Self {
642 identifier: name,
643 value,
644 }
645 }
646}
647
648impl Display for FactKey {
649 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
650 write!(f, "{}: {}", self.identifier, self.value)
651 }
652}
653
654#[derive(
656 Debug,
657 Clone,
658 PartialEq,
659 Eq,
660 Serialize,
661 Deserialize,
662 rkyv::Archive,
663 rkyv::Deserialize,
664 rkyv::Serialize,
665)]
666pub struct FactValue {
667 pub identifier: Identifier,
669 pub value: Value,
671}
672
673impl FactValue {
674 pub fn new(name: Identifier, value: Value) -> Self {
676 Self {
677 identifier: name,
678 value,
679 }
680 }
681}
682
683impl Display for FactValue {
684 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
685 write!(f, "{}: {}", self.identifier, self.value)
686 }
687}
688
689pub type FactKeyList = Vec<FactKey>;
691
692pub type FactValueList = Vec<FactValue>;
694
695#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
699pub struct KVPair(Identifier, Value);
700
701impl KVPair {
702 pub fn new(key: Identifier, value: Value) -> Self {
704 Self(key, value)
705 }
706
707 pub fn new_int(key: Identifier, value: i64) -> Self {
709 Self(key, Value::Int(value))
710 }
711
712 pub fn key(&self) -> &Identifier {
714 &self.0
715 }
716
717 pub fn value(&self) -> &Value {
719 &self.1
720 }
721}
722
723impl Display for KVPair {
724 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
725 write!(f, "{}: {}", self.0, self.1)
726 }
727}
728
729impl From<KVPair> for (Identifier, Value) {
730 fn from(kv: KVPair) -> Self {
731 (kv.0, kv.1)
732 }
733}
734
735impl From<&KVPair> for (Identifier, Value) {
736 fn from(value: &KVPair) -> Self {
737 (value.0.clone(), value.1.clone())
738 }
739}
740
741impl From<FactKey> for KVPair {
742 fn from(value: FactKey) -> Self {
743 Self(value.identifier, value.value.into())
744 }
745}
746
747impl From<FactValue> for KVPair {
748 fn from(value: FactValue) -> Self {
749 Self(value.identifier, value.value)
750 }
751}
752
753#[derive(
755 Debug,
756 Clone,
757 PartialEq,
758 Eq,
759 Serialize,
760 Deserialize,
761 rkyv::Archive,
762 rkyv::Deserialize,
763 rkyv::Serialize,
764)]
765#[rkyv(serialize_bounds(
766 __S: rkyv::ser::Writer + rkyv::ser::Allocator,
767 __S::Error: rkyv::rancor::Source,
768))]
769#[rkyv(deserialize_bounds(__D::Error: rkyv::rancor::Source))]
770#[rkyv(bytecheck(
771 bounds(
772 __C: rkyv::validation::ArchiveContext,
773 __C::Error: rkyv::rancor::Source,
774 )
775))]
776pub struct Fact {
777 pub name: Identifier,
779 #[rkyv(omit_bounds)]
781 pub keys: FactKeyList,
782 #[rkyv(omit_bounds)]
784 pub values: FactValueList,
785}
786
787impl Fact {
788 pub fn new(name: Identifier) -> Self {
790 Self {
791 name,
792 keys: vec![],
793 values: vec![],
794 }
795 }
796
797 pub fn set_key<V>(&mut self, name: Identifier, value: V)
799 where
800 V: Into<HashableValue>,
801 {
802 match self.keys.iter_mut().find(|e| e.identifier == name) {
803 None => self.keys.push(FactKey::new(name, value.into())),
804 Some(e) => e.value = value.into(),
805 }
806 }
807
808 pub fn set_value<V>(&mut self, name: Identifier, value: V)
810 where
811 V: Into<Value>,
812 {
813 match self.values.iter_mut().find(|e| e.identifier == name) {
814 None => self.values.push(FactValue {
815 identifier: name,
816 value: value.into(),
817 }),
818 Some(e) => e.value = value.into(),
819 }
820 }
821}
822
823impl Display for Fact {
824 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
825 write!(f, "{}[", self.name)?;
826 let mut i = false;
827 for FactKey {
828 identifier: k,
829 value: v,
830 } in &self.keys
831 {
832 if i {
833 write!(f, ", ")?;
834 }
835 i = true;
836 write!(f, "{}: {}", k, v)?;
837 }
838 write!(f, "]=>{{")?;
839 i = false;
840 for FactValue {
841 identifier: k,
842 value: v,
843 } in &self.values
844 {
845 if i {
846 write!(f, ", ")?;
847 }
848 i = true;
849 write!(f, "{}: {}", k, v)?;
850 }
851 write!(f, " }}")
852 }
853}
854
855#[derive(
857 Debug,
858 Clone,
859 PartialEq,
860 Eq,
861 Serialize,
862 Deserialize,
863 rkyv::Archive,
864 rkyv::Deserialize,
865 rkyv::Serialize,
866)]
867#[rkyv(serialize_bounds(
868 __S: rkyv::ser::Writer + rkyv::ser::Allocator,
869 __S::Error: rkyv::rancor::Source,
870))]
871#[rkyv(deserialize_bounds(__D::Error: rkyv::rancor::Source))]
872#[rkyv(bytecheck(
873 bounds(
874 __C: rkyv::validation::ArchiveContext,
875 __C::Error: rkyv::rancor::Source,
876 )
877))]
878pub struct Struct {
879 pub name: Identifier,
881 #[rkyv(omit_bounds)]
883 pub fields: BTreeMap<Identifier, Value>,
884}
885
886impl Struct {
887 pub fn new(
889 name: Identifier,
890 fields: impl IntoIterator<Item = impl Into<(Identifier, Value)>>,
891 ) -> Self {
892 Self {
893 name,
894 fields: fields.into_iter().map(Into::into).collect(),
895 }
896 }
897}
898
899impl Display for Struct {
900 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
901 write!(f, "{}{{", self.name)?;
902 let mut i = false;
903 for (k, v) in &self.fields {
904 if i {
905 write!(f, ", ")?;
906 }
907 i = true;
908 write!(f, "{}: {}", k, v)?;
909 }
910 write!(f, "}}")
911 }
912}
913
914#[cfg(test)]
915mod test {
916 use crate::{TryFromValue as _, Value};
917
918 #[test]
919 fn test_option_error() {
920 let err = <Option<i64>>::try_from_value(Value::Bool(true)).unwrap_err();
921 assert_eq!(
922 err.to_string(),
923 "expected type Option, but got Bool: Value -> core::option::Option<i64>"
924 );
925 }
926}