1use bc_components::{tags, Digest};
2#[cfg(feature = "encrypt")]
3use bc_components::EncryptedMessage;
4#[cfg(feature = "compress")]
5use bc_components::Compressed;
6use dcbor::prelude::*;
7use crate::{Assertion, Envelope};
8#[cfg(feature = "known_value")]
9use crate::extension::KnownValue;
10
11use super::envelope::EnvelopeCase;
12
13impl CBORTagged for Envelope {
27 fn cbor_tags() -> Vec<Tag> {
28 tags_for_values(&[tags::TAG_ENVELOPE])
29 }
30}
31
32impl From<Envelope> for CBOR {
33 fn from(value: Envelope) -> Self {
34 value.tagged_cbor()
35 }
36}
37
38impl TryFrom<CBOR> for Envelope {
39 type Error = dcbor::Error;
40
41 fn try_from(value: CBOR) -> dcbor::Result<Self> {
42 Self::from_tagged_cbor(value)
43 }
44}
45
46impl CBORTaggedEncodable for Envelope {
47 fn untagged_cbor(&self) -> CBOR {
48 match self.case() {
49 EnvelopeCase::Node { subject, assertions, digest: _ } => {
50 let mut result = vec![subject.untagged_cbor()];
51 for assertion in assertions {
52 result.push(assertion.untagged_cbor());
53 }
54 CBORCase::Array(result).into()
55 }
56 EnvelopeCase::Leaf { cbor, digest: _ } => CBOR::to_tagged_value(tags::TAG_LEAF, cbor.clone()),
57 EnvelopeCase::Wrapped { envelope, digest: _ } => envelope.tagged_cbor(),
58 EnvelopeCase::Assertion(assertion) => assertion.clone().into(),
59 EnvelopeCase::Elided(digest) => digest.untagged_cbor(),
60 #[cfg(feature = "known_value")]
61 EnvelopeCase::KnownValue { value, digest: _ } => value.untagged_cbor(),
62 #[cfg(feature = "encrypt")]
63 EnvelopeCase::Encrypted(encrypted_message) => encrypted_message.tagged_cbor(),
64 #[cfg(feature = "compress")]
65 EnvelopeCase::Compressed(compressed) => compressed.tagged_cbor(),
66 }
67 }
68}
69
70impl CBORTaggedDecodable for Envelope {
71 fn from_untagged_cbor(cbor: CBOR) -> dcbor::Result<Self> {
72 match cbor.as_case() {
73 CBORCase::Tagged(tag, item) => {
74 match tag.value() {
75 tags::TAG_LEAF | tags::TAG_ENCODED_CBOR => {
76 Ok(Self::new_leaf(item.clone()))
77 },
78 tags::TAG_ENVELOPE => {
79 let envelope = Envelope::try_from(cbor)?;
80 Ok(Self::new_wrapped(envelope))
81 },
82 #[cfg(feature = "encrypt")]
83 tags::TAG_ENCRYPTED => {
84 let encrypted = EncryptedMessage::from_untagged_cbor(item.clone())?;
85 let envelope = Self::new_with_encrypted(encrypted)?;
86 Ok(envelope)
87 },
88 #[cfg(feature = "compress")]
89 tags::TAG_COMPRESSED => {
90 let compressed = Compressed::from_untagged_cbor(item.clone())?;
91 let envelope = Self::new_with_compressed(compressed)?;
92 Ok(envelope)
93 },
94 _ => return Err(format!("unknown envelope tag: {}", tag.value()).into()),
95 }
96 }
97 CBORCase::ByteString(bytes) => {
98 Ok(Self::new_elided(Digest::from_data_ref(bytes)?))
99 }
100 CBORCase::Array(elements) => {
101 if elements.len() < 2 {
102 return Err("node must have at least two elements".into());
103 }
104 let subject = Self::from_untagged_cbor(elements[0].clone())?;
105 let assertions: Vec<Envelope> = elements[1..]
106 .iter()
107 .cloned()
108 .map(Self::from_untagged_cbor)
109 .collect::<dcbor::Result<Vec<Self>>>()?;
110 Ok(Self::new_with_assertions(subject, assertions)?)
111 }
112 CBORCase::Map(_) => {
113 let assertion = Assertion::try_from(cbor)?;
114 Ok(Self::new_with_assertion(assertion))
115 }
116 #[cfg(feature = "known_value")]
117 CBORCase::Unsigned(value) => {
118 let known_value = KnownValue::new(*value);
119 Ok(Self::new_with_known_value(known_value))
120 }
121 _ => return Err("invalid envelope".into()),
122 }
123 }
124}