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