1extern crate alloc;
2
3use alloc::{borrow::ToOwned, collections::BTreeMap, format, string::String, vec, vec::Vec};
4use core::fmt::{self, Display};
5
6pub use aranya_crypto::Id;
7use aranya_crypto::{
8 DeviceId, EncryptionKeyId, SigningKeyId,
9 policy::{CmdId, GroupId, LabelId, RoleId},
10};
11use aranya_policy_ast::{Ident, Identifier, Span, Text, TypeKind, VType};
12use serde::{Deserialize, Serialize};
13
14use super::ffi::Type;
15
16#[derive(Debug, thiserror::Error)]
17pub enum ValueConversionError {
19 #[error("expected type {want}, but got {got}: {msg}")]
21 InvalidType {
22 want: String,
24 got: String,
26 msg: String,
28 },
29 #[error("invalid struct member `{0}`")]
31 InvalidStructMember(Identifier),
32 #[error("value out of range")]
34 OutOfRange,
35 #[error("bad state")]
37 BadState,
38}
39
40impl ValueConversionError {
41 pub fn invalid_type(
43 want: impl Into<String>,
44 got: impl Into<String>,
45 msg: impl Into<String>,
46 ) -> Self {
47 Self::InvalidType {
48 want: want.into(),
49 got: got.into(),
50 msg: msg.into(),
51 }
52 }
53}
54
55pub trait Typed {
58 const TYPE: Type<'static>;
60}
61
62macro_rules! impl_typed {
63 ($name:ty => $type:ident) => {
64 impl Typed for $name {
65 const TYPE: Type<'static> = Type::$type;
66 }
67 };
68}
69
70impl_typed!(Text => String);
71
72impl_typed!(Vec<u8> => Bytes);
73impl_typed!(&[u8] => Bytes);
74
75impl_typed!(isize => Int);
76impl_typed!(i64 => Int);
77impl_typed!(i32 => Int);
78impl_typed!(i16 => Int);
79impl_typed!(i8 => Int);
80
81impl_typed!(usize => Int);
82impl_typed!(u64 => Int);
83impl_typed!(u32 => Int);
84impl_typed!(u16 => Int);
85impl_typed!(u8 => Int);
86
87impl_typed!(bool => Bool);
88
89impl_typed!(Id => Id);
90
91impl<T: Typed> Typed for Option<T> {
92 const TYPE: Type<'static> = Type::Optional(const { &T::TYPE });
93}
94
95#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
97pub enum Value {
98 Int(i64),
100 Bool(bool),
102 String(Text),
104 Bytes(Vec<u8>),
106 Struct(Struct),
108 Fact(Fact),
110 Id(Id),
112 Enum(Identifier, i64),
114 Identifier(Identifier),
116 None,
118}
119
120pub trait TryFromValue: Sized {
125 fn try_from_value(value: Value) -> Result<Self, ValueConversionError>;
127}
128
129impl<T: TryFromValue> TryFromValue for Option<T> {
130 fn try_from_value(value: Value) -> Result<Self, ValueConversionError> {
131 if matches!(value, Value::None) {
132 Ok(None)
133 } else {
134 T::try_from_value(value).map(Some)
135 }
136 }
137}
138
139impl<T: TryFrom<Value, Error = ValueConversionError>> TryFromValue for T {
140 fn try_from_value(value: Value) -> Result<Self, ValueConversionError> {
141 Self::try_from(value)
142 }
143}
144
145pub trait TryAsMut<T: ?Sized> {
147 type Error;
149
150 fn try_as_mut(&mut self) -> Result<&mut T, Self::Error>;
153}
154
155impl Value {
156 pub fn vtype(&self) -> Option<TypeKind> {
158 match self {
159 Value::Int(_) => Some(TypeKind::Int),
160 Value::Bool(_) => Some(TypeKind::Bool),
161 Value::String(_) => Some(TypeKind::String),
162 Value::Bytes(_) => Some(TypeKind::Bytes),
163 Value::Id(_) => Some(TypeKind::Id),
164 Value::Enum(name, _) => Some(TypeKind::Enum(Ident {
165 name: name.to_owned(),
166 span: Span::default(),
167 })),
168 Value::Struct(s) => Some(TypeKind::Struct(Ident {
169 name: s.name.clone(),
170 span: Span::default(),
171 })),
172 _ => None,
173 }
174 }
175
176 pub fn type_name(&self) -> String {
178 match self {
179 Value::Int(_) => String::from("Int"),
180 Value::Bool(_) => String::from("Bool"),
181 Value::String(_) => String::from("String"),
182 Value::Bytes(_) => String::from("Bytes"),
183 Value::Struct(s) => format!("Struct {}", s.name),
184 Value::Fact(f) => format!("Fact {}", f.name),
185 Value::Id(_) => String::from("Id"),
186 Value::Enum(name, _) => format!("Enum {}", name),
187 Value::Identifier(_) => String::from("Identifier"),
188 Value::None => String::from("None"),
189 }
190 }
191
192 pub fn fits_type(&self, expected_type: &VType) -> bool {
206 use aranya_policy_ast::TypeKind;
207 match (self.vtype(), &expected_type.kind) {
208 (None, TypeKind::Optional(_)) => true,
209 (None, _) => false,
210 (Some(vtype), TypeKind::Optional(inner)) => vtype.matches(&inner.kind),
211 (Some(vtype), kind) => vtype.matches(kind),
212 }
213 }
214}
215
216impl<T: Into<Value>> From<Option<T>> for Value {
217 fn from(value: Option<T>) -> Self {
218 value.map_or(Value::None, Into::into)
219 }
220}
221
222impl From<i64> for Value {
223 fn from(value: i64) -> Self {
224 Value::Int(value)
225 }
226}
227
228impl From<bool> for Value {
229 fn from(value: bool) -> Self {
230 Value::Bool(value)
231 }
232}
233
234impl From<Text> for Value {
235 fn from(value: Text) -> Self {
236 Value::String(value)
237 }
238}
239
240impl From<Identifier> for Value {
241 fn from(value: Identifier) -> Self {
242 Value::Identifier(value)
243 }
244}
245
246impl From<&[u8]> for Value {
247 fn from(value: &[u8]) -> Self {
248 Value::Bytes(value.to_owned())
249 }
250}
251
252impl From<Vec<u8>> for Value {
253 fn from(value: Vec<u8>) -> Self {
254 Value::Bytes(value)
255 }
256}
257
258impl From<Struct> for Value {
259 fn from(value: Struct) -> Self {
260 Value::Struct(value)
261 }
262}
263
264impl From<Fact> for Value {
265 fn from(value: Fact) -> Self {
266 Value::Fact(value)
267 }
268}
269
270impl From<Id> for Value {
271 fn from(id: Id) -> Self {
272 Value::Id(id)
273 }
274}
275
276impl TryFrom<Value> for i64 {
277 type Error = ValueConversionError;
278
279 fn try_from(value: Value) -> Result<Self, Self::Error> {
280 if let Value::Int(i) = value {
281 return Ok(i);
282 }
283 Err(ValueConversionError::invalid_type(
284 "Int",
285 value.type_name(),
286 "Value -> i64",
287 ))
288 }
289}
290
291impl TryFrom<Value> for bool {
292 type Error = ValueConversionError;
293
294 fn try_from(value: Value) -> Result<Self, Self::Error> {
295 if let Value::Bool(b) = value {
296 return Ok(b);
297 }
298 Err(ValueConversionError::invalid_type(
299 "Bool",
300 value.type_name(),
301 "Value -> bool",
302 ))
303 }
304}
305
306impl TryFrom<Value> for Text {
307 type Error = ValueConversionError;
308
309 fn try_from(value: Value) -> Result<Self, Self::Error> {
310 if let Value::String(s) = value {
311 return Ok(s);
312 }
313 Err(ValueConversionError::invalid_type(
314 "String",
315 value.type_name(),
316 "Value -> Text",
317 ))
318 }
319}
320
321impl TryFrom<Value> for Identifier {
322 type Error = ValueConversionError;
323
324 fn try_from(value: Value) -> Result<Self, Self::Error> {
325 let Value::Identifier(text) = value else {
326 return Err(ValueConversionError::invalid_type(
327 "Identifier",
328 value.type_name(),
329 "Value -> Identifier",
330 ));
331 };
332 Ok(text)
333 }
334}
335
336impl TryFrom<Value> for Vec<u8> {
337 type Error = ValueConversionError;
338
339 fn try_from(value: Value) -> Result<Self, Self::Error> {
340 if let Value::Bytes(v) = value {
341 return Ok(v);
342 }
343 Err(ValueConversionError::invalid_type(
344 "Bytes",
345 value.type_name(),
346 "Value -> Vec<u8>",
347 ))
348 }
349}
350
351impl TryFrom<Value> for Struct {
352 type Error = ValueConversionError;
353
354 fn try_from(value: Value) -> Result<Self, Self::Error> {
355 if let Value::Struct(s) = value {
356 return Ok(s);
357 }
358 Err(ValueConversionError::invalid_type(
359 "Struct",
360 value.type_name(),
361 "Value -> Struct",
362 ))
363 }
364}
365
366impl TryFrom<Value> for Fact {
367 type Error = ValueConversionError;
368
369 fn try_from(value: Value) -> Result<Self, Self::Error> {
370 if let Value::Fact(f) = value {
371 return Ok(f);
372 }
373 Err(ValueConversionError::invalid_type(
374 "Fact",
375 value.type_name(),
376 "Value -> Fact",
377 ))
378 }
379}
380
381impl TryFrom<Value> for Id {
382 type Error = ValueConversionError;
383
384 fn try_from(value: Value) -> Result<Self, Self::Error> {
385 if let Value::Id(id) = value {
386 Ok(id)
387 } else {
388 Err(ValueConversionError::invalid_type(
389 "Id",
390 value.type_name(),
391 "Value -> Id",
392 ))
393 }
394 }
395}
396
397impl TryAsMut<i64> for Value {
398 type Error = ValueConversionError;
399 fn try_as_mut(&mut self) -> Result<&mut i64, Self::Error> {
400 if let Self::Int(s) = self {
401 return Ok(s);
402 }
403 Err(ValueConversionError::invalid_type(
404 "i64",
405 self.type_name(),
406 "Value -> i64",
407 ))
408 }
409}
410
411impl TryAsMut<bool> for Value {
412 type Error = ValueConversionError;
413 fn try_as_mut(&mut self) -> Result<&mut bool, Self::Error> {
414 if let Self::Bool(b) = self {
415 return Ok(b);
416 }
417 Err(ValueConversionError::invalid_type(
418 "bool",
419 self.type_name(),
420 "Value -> bool",
421 ))
422 }
423}
424
425impl TryAsMut<[u8]> for Value {
426 type Error = ValueConversionError;
427 fn try_as_mut(&mut self) -> Result<&mut [u8], Self::Error> {
428 if let Self::Bytes(v) = self {
429 return Ok(v);
430 }
431 Err(ValueConversionError::invalid_type(
432 "Vec<u8>",
433 self.type_name(),
434 "Value -> [u8]",
435 ))
436 }
437}
438
439impl TryAsMut<Struct> for Value {
440 type Error = ValueConversionError;
441 fn try_as_mut(&mut self) -> Result<&mut Struct, Self::Error> {
442 if let Self::Struct(s) = self {
443 return Ok(s);
444 }
445 Err(ValueConversionError::invalid_type(
446 "Struct",
447 self.type_name(),
448 "Value -> Struct",
449 ))
450 }
451}
452
453impl TryAsMut<Fact> for Value {
454 type Error = ValueConversionError;
455 fn try_as_mut(&mut self) -> Result<&mut Fact, Self::Error> {
456 if let Self::Fact(f) = self {
457 return Ok(f);
458 }
459 Err(ValueConversionError::invalid_type(
460 "Fact",
461 self.type_name(),
462 "Value -> Fact",
463 ))
464 }
465}
466
467impl Display for Value {
468 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
469 match self {
470 Value::Int(i) => write!(f, "{}", i),
471 Value::Bool(b) => write!(f, "{}", b),
472 Value::String(s) => write!(f, "\"{}\"", s),
473 Value::Bytes(v) => {
474 write!(f, "b:")?;
475 for b in v {
476 write!(f, "{:02X}", b)?;
477 }
478 Ok(())
479 }
480 Value::Struct(s) => s.fmt(f),
481 Value::Fact(fa) => fa.fmt(f),
482 Value::Id(id) => id.fmt(f),
483 Value::Enum(name, value) => write!(f, "{name}::{value}"),
484 Value::Identifier(name) => write!(f, "{name}"),
485 Value::None => write!(f, "None"),
486 }
487 }
488}
489
490#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
493#[cfg_attr(feature = "proptest", derive(proptest_derive::Arbitrary))]
494pub enum HashableValue {
495 Int(i64),
497 Bool(bool),
499 String(Text),
501 Id(Id),
503 Enum(Identifier, i64),
505}
506
507impl HashableValue {
508 pub fn vtype(&self) -> TypeKind {
511 use aranya_policy_ast::TypeKind;
512 match self {
513 HashableValue::Int(_) => TypeKind::Int,
514 HashableValue::Bool(_) => TypeKind::Bool,
515 HashableValue::String(_) => TypeKind::String,
516 HashableValue::Id(_) => TypeKind::Id,
517 HashableValue::Enum(id, _) => TypeKind::Enum(Ident {
518 name: id.clone(),
519 span: Span::default(),
520 }),
521 }
522 }
523}
524
525impl TryFrom<Value> for HashableValue {
526 type Error = ValueConversionError;
527
528 fn try_from(value: Value) -> Result<Self, Self::Error> {
529 match value {
530 Value::Int(v) => Ok(HashableValue::Int(v)),
531 Value::Bool(v) => Ok(HashableValue::Bool(v)),
532 Value::String(v) => Ok(HashableValue::String(v)),
533 Value::Id(v) => Ok(HashableValue::Id(v)),
534 Value::Enum(id, value) => Ok(HashableValue::Enum(id, value)),
535 _ => Err(ValueConversionError::invalid_type(
536 "Int | Bool | String | Id | Enum",
537 value.type_name(),
538 "Value -> HashableValue",
539 )),
540 }
541 }
542}
543
544impl From<HashableValue> for Value {
545 fn from(value: HashableValue) -> Self {
546 match value {
547 HashableValue::Int(v) => Value::Int(v),
548 HashableValue::Bool(v) => Value::Bool(v),
549 HashableValue::String(v) => Value::String(v),
550 HashableValue::Id(v) => Value::Id(v),
551 HashableValue::Enum(id, value) => Value::Enum(id, value),
552 }
553 }
554}
555
556impl Display for HashableValue {
557 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
558 let real_value: Value = self.to_owned().into();
559 write!(f, "{}", real_value)
560 }
561}
562
563#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
566#[cfg_attr(feature = "proptest", derive(proptest_derive::Arbitrary))]
567pub struct FactKey {
568 pub identifier: Identifier,
570 pub value: HashableValue,
572}
573
574impl FactKey {
575 pub fn new(name: Identifier, value: HashableValue) -> Self {
577 Self {
578 identifier: name,
579 value,
580 }
581 }
582}
583
584impl Display for FactKey {
585 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
586 write!(f, "{}: {}", self.identifier, self.value)
587 }
588}
589
590#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
592pub struct FactValue {
593 pub identifier: Identifier,
595 pub value: Value,
597}
598
599impl FactValue {
600 pub fn new(name: Identifier, value: Value) -> Self {
602 Self {
603 identifier: name,
604 value,
605 }
606 }
607}
608
609impl Display for FactValue {
610 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
611 write!(f, "{}: {}", self.identifier, self.value)
612 }
613}
614
615pub type FactKeyList = Vec<FactKey>;
617
618pub type FactValueList = Vec<FactValue>;
620
621#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
625pub struct KVPair(Identifier, Value);
626
627impl KVPair {
628 pub fn new(key: Identifier, value: Value) -> KVPair {
630 KVPair(key, value)
631 }
632
633 pub fn new_int(key: Identifier, value: i64) -> KVPair {
635 KVPair(key, Value::Int(value))
636 }
637
638 pub fn key(&self) -> &Identifier {
640 &self.0
641 }
642
643 pub fn value(&self) -> &Value {
645 &self.1
646 }
647}
648
649impl Display for KVPair {
650 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
651 write!(f, "{}: {}", self.0, self.1)
652 }
653}
654
655impl From<KVPair> for (Identifier, Value) {
656 fn from(kv: KVPair) -> Self {
657 (kv.0, kv.1)
658 }
659}
660
661impl From<&KVPair> for (Identifier, Value) {
662 fn from(value: &KVPair) -> Self {
663 (value.0.clone(), value.1.clone())
664 }
665}
666
667impl From<FactKey> for KVPair {
668 fn from(value: FactKey) -> Self {
669 KVPair(value.identifier, value.value.into())
670 }
671}
672
673impl From<FactValue> for KVPair {
674 fn from(value: FactValue) -> Self {
675 KVPair(value.identifier, value.value)
676 }
677}
678
679#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
681pub struct Fact {
682 pub name: Identifier,
684 pub keys: FactKeyList,
686 pub values: FactValueList,
688}
689
690impl Fact {
691 pub fn new(name: Identifier) -> Fact {
693 Fact {
694 name,
695 keys: vec![],
696 values: vec![],
697 }
698 }
699
700 pub fn set_key<V>(&mut self, name: Identifier, value: V)
702 where
703 V: Into<HashableValue>,
704 {
705 match self.keys.iter_mut().find(|e| e.identifier == name) {
706 None => self.keys.push(FactKey::new(name, value.into())),
707 Some(e) => e.value = value.into(),
708 }
709 }
710
711 pub fn set_value<V>(&mut self, name: Identifier, value: V)
713 where
714 V: Into<Value>,
715 {
716 match self.values.iter_mut().find(|e| e.identifier == name) {
717 None => self.values.push(FactValue {
718 identifier: name,
719 value: value.into(),
720 }),
721 Some(e) => e.value = value.into(),
722 }
723 }
724}
725
726impl Display for Fact {
727 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
728 write!(f, "{}[", self.name)?;
729 let mut i = false;
730 for FactKey {
731 identifier: k,
732 value: v,
733 } in &self.keys
734 {
735 if i {
736 write!(f, ", ")?;
737 }
738 i = true;
739 write!(f, "{}: {}", k, v)?;
740 }
741 write!(f, "]=>{{")?;
742 i = false;
743 for FactValue {
744 identifier: k,
745 value: v,
746 } in &self.values
747 {
748 if i {
749 write!(f, ", ")?;
750 }
751 i = true;
752 write!(f, "{}: {}", k, v)?;
753 }
754 write!(f, " }}")
755 }
756}
757
758#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
760pub struct Struct {
761 pub name: Identifier,
763 pub fields: BTreeMap<Identifier, Value>,
765}
766
767impl Struct {
768 pub fn new(
770 name: Identifier,
771 fields: impl IntoIterator<Item = impl Into<(Identifier, Value)>>,
772 ) -> Struct {
773 Struct {
774 name,
775 fields: fields.into_iter().map(|p| p.into()).collect(),
776 }
777 }
778}
779
780impl Display for Struct {
781 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
782 write!(f, "{}{{", self.name)?;
783 let mut i = false;
784 for (k, v) in &self.fields {
785 if i {
786 write!(f, ", ")?;
787 }
788 i = true;
789 write!(f, "{}: {}", k, v)?;
790 }
791 write!(f, "}}")
792 }
793}
794
795macro_rules! id_impls {
796 ($ty:ident) => {
797 impl_typed!($ty => Id);
798
799 impl From<$ty> for Value {
800 fn from(id: $ty) -> Self {
801 Value::Id(id.into())
802 }
803 }
804
805 impl TryFrom<Value> for $ty {
806 type Error = ValueConversionError;
807
808 fn try_from(value: Value) -> Result<Self, Self::Error> {
809 if let Value::Id(id) = value {
810 Ok(id.into())
811 } else {
812 Err(ValueConversionError::invalid_type(
813 "Id",
814 value.type_name(),
815 concat!("Value -> ", stringify!($ty)),
816 ))
817 }
818 }
819 }
820 }
821}
822
823id_impls!(DeviceId);
824id_impls!(EncryptionKeyId);
825id_impls!(SigningKeyId);
826id_impls!(CmdId);
827id_impls!(LabelId);
828id_impls!(GroupId);
829id_impls!(RoleId);