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::{DeviceId, EncryptionKeyId};
8use aranya_policy_ast::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(String),
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!(String => String);
68impl_typed!(&str => String);
69
70impl_typed!(Vec<u8> => Bytes);
71impl_typed!(&[u8] => Bytes);
72
73impl_typed!(isize => Int);
74impl_typed!(i64 => Int);
75impl_typed!(i32 => Int);
76impl_typed!(i16 => Int);
77impl_typed!(i8 => Int);
78
79impl_typed!(usize => Int);
80impl_typed!(u64 => Int);
81impl_typed!(u32 => Int);
82impl_typed!(u16 => Int);
83impl_typed!(u8 => Int);
84
85impl_typed!(bool => Bool);
86
87impl_typed!(Id => Id);
88impl_typed!(EncryptionKeyId => Id);
89impl_typed!(DeviceId => Id);
90
91impl<T: Typed> Typed for Option<T> {
92 const TYPE: Type<'static> = Type::Optional(&T::TYPE);
93}
94
95#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
97pub enum Value {
98 Int(i64),
100 Bool(bool),
102 String(String),
104 Bytes(Vec<u8>),
106 Struct(Struct),
108 Fact(Fact),
110 Id(Id),
112 Enum(String, i64),
114 None,
116}
117
118pub trait TryFromValue: Sized {
123 fn try_from_value(value: Value) -> Result<Self, ValueConversionError>;
125}
126
127impl<T: TryFromValue> TryFromValue for Option<T> {
128 fn try_from_value(value: Value) -> Result<Self, ValueConversionError> {
129 if matches!(value, Value::None) {
130 Ok(None)
131 } else {
132 T::try_from_value(value).map(Some)
133 }
134 }
135}
136
137impl<T: TryFrom<Value, Error = ValueConversionError>> TryFromValue for T {
138 fn try_from_value(value: Value) -> Result<Self, ValueConversionError> {
139 Self::try_from(value)
140 }
141}
142
143pub trait TryAsMut<T: ?Sized> {
145 type Error;
147
148 fn try_as_mut(&mut self) -> Result<&mut T, Self::Error>;
151}
152
153impl Value {
154 pub fn vtype(&self) -> Option<VType> {
156 match self {
157 Value::Int(_) => Some(VType::Int),
158 Value::Bool(_) => Some(VType::Bool),
159 Value::String(_) => Some(VType::String),
160 Value::Bytes(_) => Some(VType::Bytes),
161 Value::Id(_) => Some(VType::Id),
162 Value::Enum(name, _) => Some(VType::Enum(name.to_owned())),
163 Value::Struct(s) => Some(VType::Struct(s.name.clone())),
164 _ => None,
165 }
166 }
167
168 pub fn type_name(&self) -> String {
170 match self {
171 Value::Int(_) => String::from("Int"),
172 Value::Bool(_) => String::from("Bool"),
173 Value::String(_) => String::from("String"),
174 Value::Bytes(_) => String::from("Bytes"),
175 Value::Struct(s) => format!("Struct {}", s.name),
176 Value::Fact(f) => format!("Fact {}", f.name),
177 Value::Id(_) => String::from("Id"),
178 Value::Enum(name, _) => format!("Enum {}", name),
179 Value::None => String::from("None"),
180 }
181 }
182
183 pub fn fits_type(&self, expected_type: &VType) -> bool {
193 match (self.vtype(), expected_type) {
194 (None, VType::Optional(_)) => true,
195 (None, _) => false,
196 (Some(VType::Optional(_)), _) => unreachable!(),
197 (Some(left), VType::Optional(inner)) => left == **inner,
198 (Some(left), right) => left == *right,
199 }
200 }
201}
202
203impl<T: Into<Value>> From<Option<T>> for Value {
204 fn from(value: Option<T>) -> Self {
205 value.map_or(Value::None, Into::into)
206 }
207}
208
209impl From<i64> for Value {
210 fn from(value: i64) -> Self {
211 Value::Int(value)
212 }
213}
214
215impl From<bool> for Value {
216 fn from(value: bool) -> Self {
217 Value::Bool(value)
218 }
219}
220
221impl From<&str> for Value {
222 fn from(value: &str) -> Self {
223 Value::String(value.to_owned())
224 }
225}
226
227impl From<String> for Value {
228 fn from(value: String) -> Self {
229 Value::String(value)
230 }
231}
232
233impl From<&[u8]> for Value {
234 fn from(value: &[u8]) -> Self {
235 Value::Bytes(value.to_owned())
236 }
237}
238
239impl From<Vec<u8>> for Value {
240 fn from(value: Vec<u8>) -> Self {
241 Value::Bytes(value)
242 }
243}
244
245impl From<Struct> for Value {
246 fn from(value: Struct) -> Self {
247 Value::Struct(value)
248 }
249}
250
251impl From<Fact> for Value {
252 fn from(value: Fact) -> Self {
253 Value::Fact(value)
254 }
255}
256
257impl From<Id> for Value {
258 fn from(id: Id) -> Self {
259 Value::Id(id)
260 }
261}
262
263impl From<DeviceId> for Value {
264 fn from(id: DeviceId) -> Self {
265 Value::Id(id.into())
266 }
267}
268
269impl From<EncryptionKeyId> for Value {
270 fn from(id: EncryptionKeyId) -> Self {
271 Value::Id(id.into())
272 }
273}
274
275impl TryFrom<Value> for i64 {
276 type Error = ValueConversionError;
277
278 fn try_from(value: Value) -> Result<Self, Self::Error> {
279 if let Value::Int(i) = value {
280 return Ok(i);
281 }
282 Err(ValueConversionError::invalid_type(
283 "Int",
284 value.type_name(),
285 "Value -> i64",
286 ))
287 }
288}
289
290impl TryFrom<Value> for bool {
291 type Error = ValueConversionError;
292
293 fn try_from(value: Value) -> Result<Self, Self::Error> {
294 if let Value::Bool(b) = value {
295 return Ok(b);
296 }
297 Err(ValueConversionError::invalid_type(
298 "Bool",
299 value.type_name(),
300 "Value -> bool",
301 ))
302 }
303}
304
305impl TryFrom<Value> for String {
306 type Error = ValueConversionError;
307
308 fn try_from(value: Value) -> Result<Self, Self::Error> {
309 if let Value::String(s) = value {
310 return Ok(s);
311 }
312 Err(ValueConversionError::invalid_type(
313 "String",
314 value.type_name(),
315 "Value -> String",
316 ))
317 }
318}
319
320impl TryFrom<Value> for Vec<u8> {
321 type Error = ValueConversionError;
322
323 fn try_from(value: Value) -> Result<Self, Self::Error> {
324 if let Value::Bytes(v) = value {
325 return Ok(v);
326 }
327 Err(ValueConversionError::invalid_type(
328 "Bytes",
329 value.type_name(),
330 "Value -> Vec<u8>",
331 ))
332 }
333}
334
335impl TryFrom<Value> for Struct {
336 type Error = ValueConversionError;
337
338 fn try_from(value: Value) -> Result<Self, Self::Error> {
339 if let Value::Struct(s) = value {
340 return Ok(s);
341 }
342 Err(ValueConversionError::invalid_type(
343 "Struct",
344 value.type_name(),
345 "Value -> Struct",
346 ))
347 }
348}
349
350impl TryFrom<Value> for Fact {
351 type Error = ValueConversionError;
352
353 fn try_from(value: Value) -> Result<Self, Self::Error> {
354 if let Value::Fact(f) = value {
355 return Ok(f);
356 }
357 Err(ValueConversionError::invalid_type(
358 "Fact",
359 value.type_name(),
360 "Value -> Fact",
361 ))
362 }
363}
364
365impl TryFrom<Value> for Id {
366 type Error = ValueConversionError;
367
368 fn try_from(value: Value) -> Result<Self, Self::Error> {
369 if let Value::Id(id) = value {
370 Ok(id)
371 } else {
372 Err(ValueConversionError::invalid_type(
373 "Id",
374 value.type_name(),
375 "Value -> Id",
376 ))
377 }
378 }
379}
380
381impl TryFrom<Value> for DeviceId {
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.into())
387 } else {
388 Err(ValueConversionError::invalid_type(
389 "Id",
390 value.type_name(),
391 "Value -> DeviceId",
392 ))
393 }
394 }
395}
396
397impl TryFrom<Value> for EncryptionKeyId {
398 type Error = ValueConversionError;
399
400 fn try_from(value: Value) -> Result<Self, Self::Error> {
401 if let Value::Id(id) = value {
402 Ok(id.into())
403 } else {
404 Err(ValueConversionError::invalid_type(
405 "Id",
406 value.type_name(),
407 "Value -> EncryptionKeyId",
408 ))
409 }
410 }
411}
412
413impl TryAsMut<i64> for Value {
414 type Error = ValueConversionError;
415 fn try_as_mut(&mut self) -> Result<&mut i64, Self::Error> {
416 if let Self::Int(s) = self {
417 return Ok(s);
418 }
419 Err(ValueConversionError::invalid_type(
420 "i64",
421 self.type_name(),
422 "Value -> i64",
423 ))
424 }
425}
426
427impl TryAsMut<bool> for Value {
428 type Error = ValueConversionError;
429 fn try_as_mut(&mut self) -> Result<&mut bool, Self::Error> {
430 if let Self::Bool(b) = self {
431 return Ok(b);
432 }
433 Err(ValueConversionError::invalid_type(
434 "bool",
435 self.type_name(),
436 "Value -> bool",
437 ))
438 }
439}
440
441impl TryAsMut<str> for Value {
442 type Error = ValueConversionError;
443 fn try_as_mut(&mut self) -> Result<&mut str, Self::Error> {
444 if let Self::String(s) = self {
445 return Ok(s);
446 }
447 Err(ValueConversionError::invalid_type(
448 "String",
449 self.type_name(),
450 "Value -> String",
451 ))
452 }
453}
454
455impl TryAsMut<[u8]> for Value {
456 type Error = ValueConversionError;
457 fn try_as_mut(&mut self) -> Result<&mut [u8], Self::Error> {
458 if let Self::Bytes(v) = self {
459 return Ok(v);
460 }
461 Err(ValueConversionError::invalid_type(
462 "Vec<u8>",
463 self.type_name(),
464 "Value -> [u8]",
465 ))
466 }
467}
468
469impl TryAsMut<Struct> for Value {
470 type Error = ValueConversionError;
471 fn try_as_mut(&mut self) -> Result<&mut Struct, Self::Error> {
472 if let Self::Struct(s) = self {
473 return Ok(s);
474 }
475 Err(ValueConversionError::invalid_type(
476 "Struct",
477 self.type_name(),
478 "Value -> Struct",
479 ))
480 }
481}
482
483impl TryAsMut<Fact> for Value {
484 type Error = ValueConversionError;
485 fn try_as_mut(&mut self) -> Result<&mut Fact, Self::Error> {
486 if let Self::Fact(f) = self {
487 return Ok(f);
488 }
489 Err(ValueConversionError::invalid_type(
490 "Fact",
491 self.type_name(),
492 "Value -> Fact",
493 ))
494 }
495}
496
497impl Display for Value {
498 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
499 match self {
500 Value::Int(i) => write!(f, "{}", i),
501 Value::Bool(b) => write!(f, "{}", b),
502 Value::String(s) => write!(f, "\"{}\"", s),
503 Value::Bytes(v) => {
504 write!(f, "b:")?;
505 for b in v {
506 write!(f, "{:02X}", b)?;
507 }
508 Ok(())
509 }
510 Value::Struct(s) => s.fmt(f),
511 Value::Fact(fa) => fa.fmt(f),
512 Value::Id(id) => id.fmt(f),
513 Value::Enum(name, value) => write!(f, "{name}::{value}"),
514 Value::None => write!(f, "None"),
515 }
516 }
517}
518
519#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
522#[cfg_attr(feature = "proptest", derive(proptest_derive::Arbitrary))]
523pub enum HashableValue {
524 Int(i64),
526 Bool(bool),
528 String(String),
530 Id(Id),
532 Enum(String, i64),
534}
535
536impl HashableValue {
537 pub fn vtype(&self) -> VType {
540 match self {
541 HashableValue::Int(_) => VType::Int,
542 HashableValue::Bool(_) => VType::Bool,
543 HashableValue::String(_) => VType::String,
544 HashableValue::Id(_) => VType::Id,
545 HashableValue::Enum(id, _) => VType::Enum(id.clone()),
546 }
547 }
548}
549
550impl TryFrom<Value> for HashableValue {
551 type Error = ValueConversionError;
552
553 fn try_from(value: Value) -> Result<Self, Self::Error> {
554 match value {
555 Value::Int(v) => Ok(HashableValue::Int(v)),
556 Value::Bool(v) => Ok(HashableValue::Bool(v)),
557 Value::String(v) => Ok(HashableValue::String(v)),
558 Value::Id(v) => Ok(HashableValue::Id(v)),
559 Value::Enum(id, value) => Ok(HashableValue::Enum(id, value)),
560 _ => Err(ValueConversionError::invalid_type(
561 "Int | Bool | String | Id | Enum",
562 value.type_name(),
563 "Value -> HashableValue",
564 )),
565 }
566 }
567}
568
569impl From<HashableValue> for Value {
570 fn from(value: HashableValue) -> Self {
571 match value {
572 HashableValue::Int(v) => Value::Int(v),
573 HashableValue::Bool(v) => Value::Bool(v),
574 HashableValue::String(v) => Value::String(v),
575 HashableValue::Id(v) => Value::Id(v),
576 HashableValue::Enum(id, value) => Value::Enum(id, value),
577 }
578 }
579}
580
581impl Display for HashableValue {
582 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
583 let real_value: Value = self.to_owned().into();
584 write!(f, "{}", real_value)
585 }
586}
587
588#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
591#[cfg_attr(feature = "proptest", derive(proptest_derive::Arbitrary))]
592pub struct FactKey {
593 pub identifier: String,
595 pub value: HashableValue,
597}
598
599impl FactKey {
600 pub fn new(name: &str, value: HashableValue) -> Self {
602 Self {
603 identifier: String::from(name),
604 value,
605 }
606 }
607}
608
609impl Display for FactKey {
610 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
611 write!(f, "{}: {}", self.identifier, self.value)
612 }
613}
614
615#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
617pub struct FactValue {
618 pub identifier: String,
620 pub value: Value,
622}
623
624impl FactValue {
625 pub fn new(name: &str, value: Value) -> Self {
627 Self {
628 identifier: String::from(name),
629 value,
630 }
631 }
632}
633
634impl Display for FactValue {
635 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
636 write!(f, "{}: {}", self.identifier, self.value)
637 }
638}
639
640pub type FactKeyList = Vec<FactKey>;
642
643pub type FactValueList = Vec<FactValue>;
645
646#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
650pub struct KVPair(String, Value);
651
652impl KVPair {
653 pub fn new(key: &str, value: Value) -> KVPair {
655 KVPair(key.to_owned(), value)
656 }
657
658 pub fn new_int(key: &str, value: i64) -> KVPair {
660 KVPair(key.to_owned(), Value::Int(value))
661 }
662
663 pub fn key(&self) -> &str {
665 &self.0
666 }
667
668 pub fn value(&self) -> &Value {
670 &self.1
671 }
672}
673
674impl Display for KVPair {
675 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
676 write!(f, "{}: {}", self.0, self.1)
677 }
678}
679
680impl From<KVPair> for (String, Value) {
681 fn from(kv: KVPair) -> Self {
682 (kv.0, kv.1)
683 }
684}
685
686impl From<&KVPair> for (String, Value) {
687 fn from(value: &KVPair) -> Self {
688 (value.0.clone(), value.1.clone())
689 }
690}
691
692impl From<FactKey> for KVPair {
693 fn from(value: FactKey) -> Self {
694 KVPair(value.identifier, value.value.into())
695 }
696}
697
698impl From<FactValue> for KVPair {
699 fn from(value: FactValue) -> Self {
700 KVPair(value.identifier, value.value)
701 }
702}
703
704#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
706pub struct Fact {
707 pub name: String,
709 pub keys: FactKeyList,
711 pub values: FactValueList,
713}
714
715impl Fact {
716 pub fn new(name: String) -> Fact {
718 Fact {
719 name,
720 keys: vec![],
721 values: vec![],
722 }
723 }
724
725 pub fn set_key<V>(&mut self, name: String, value: V)
727 where
728 V: Into<HashableValue>,
729 {
730 match self.keys.iter_mut().find(|e| e.identifier == name) {
731 None => self.keys.push(FactKey::new(&name, value.into())),
732 Some(e) => e.value = value.into(),
733 }
734 }
735
736 pub fn set_value<V>(&mut self, name: String, value: V)
738 where
739 V: Into<Value>,
740 {
741 match self.values.iter_mut().find(|e| e.identifier == name) {
742 None => self.values.push(FactValue {
743 identifier: name,
744 value: value.into(),
745 }),
746 Some(e) => e.value = value.into(),
747 }
748 }
749}
750
751impl Display for Fact {
752 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
753 write!(f, "{}[", self.name)?;
754 let mut i = false;
755 for FactKey {
756 identifier: k,
757 value: v,
758 } in &self.keys
759 {
760 if i {
761 write!(f, ", ")?;
762 }
763 i = true;
764 write!(f, "{}: {}", k, v)?;
765 }
766 write!(f, "]=>{{")?;
767 i = false;
768 for FactValue {
769 identifier: k,
770 value: v,
771 } in &self.values
772 {
773 if i {
774 write!(f, ", ")?;
775 }
776 i = true;
777 write!(f, "{}: {}", k, v)?;
778 }
779 write!(f, " }}")
780 }
781}
782
783#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
785pub struct Struct {
786 pub name: String,
788 pub fields: BTreeMap<String, Value>,
790}
791
792impl Struct {
793 pub fn new(name: &str, fields: impl IntoIterator<Item = impl Into<(String, Value)>>) -> Struct {
795 Struct {
796 name: name.to_owned(),
797 fields: fields.into_iter().map(|p| p.into()).collect(),
798 }
799 }
800}
801
802impl From<Struct> for (String, Vec<KVPair>) {
803 fn from(value: Struct) -> Self {
804 (
805 value.name,
806 value
807 .fields
808 .into_iter()
809 .map(|(k, v)| KVPair(k, v))
810 .collect(),
811 )
812 }
813}
814
815impl Display for Struct {
816 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
817 write!(f, "{}{{", self.name)?;
818 let mut i = false;
819 for (k, v) in &self.fields {
820 if i {
821 write!(f, ", ")?;
822 }
823 i = true;
824 write!(f, "{}: {}", k, v)?;
825 }
826 write!(f, "}}")
827 }
828}