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 .map_err(|e| e.to_string())?;
91 Ok(envelope)
92 }
93 #[cfg(feature = "compress")]
94 tags::TAG_COMPRESSED => {
95 let compressed =
96 Compressed::from_untagged_cbor(item.clone())?;
97 let envelope = Self::new_with_compressed(compressed)
98 .map_err(|e| e.to_string())?;
99 Ok(envelope)
100 }
101 _ => {
102 Err(format!("unknown envelope tag: {}", tag.value()).into())
103 }
104 },
105 CBORCase::ByteString(bytes) => {
106 Ok(Self::new_elided(Digest::from_data_ref(bytes)?))
107 }
108 CBORCase::Array(elements) => {
109 if elements.len() < 2 {
110 return Err("node must have at least two elements".into());
111 }
112 let subject = Self::from_untagged_cbor(elements[0].clone())?;
113 let assertions: Vec<Envelope> = elements[1..]
114 .iter()
115 .cloned()
116 .map(Self::from_untagged_cbor)
117 .collect::<dcbor::Result<Vec<Self>>>()?;
118 Ok(Self::new_with_assertions(subject, assertions)
119 .map_err(|e| e.to_string())?)
120 }
121 CBORCase::Map(_) => {
122 let assertion =
123 Assertion::try_from(cbor).map_err(|e| e.to_string())?;
124 Ok(Self::new_with_assertion(assertion))
125 }
126 #[cfg(feature = "known_value")]
127 CBORCase::Unsigned(value) => {
128 let known_value = KnownValue::new(*value);
129 Ok(Self::new_with_known_value(known_value))
130 }
131 _ => Err("invalid envelope".into()),
132 }
133 }
134}