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