bc_envelope/base/
leaf.rs

1//! Provides methods for working with envelope leaf nodes,
2//! which are dCBOR values of any kind.
3
4use dcbor::prelude::*;
5
6#[cfg(feature = "known_value")]
7use super::envelope::EnvelopeCase;
8#[cfg(feature = "known_value")]
9use crate::extension::KnownValue;
10#[cfg(feature = "known_value")]
11use crate::Error;
12
13use crate::Envelope;
14
15impl Envelope {
16    pub fn r#false() -> Self { Self::new_leaf(false) }
17
18    pub fn r#true() -> Self { Self::new_leaf(true) }
19
20    pub fn is_false(&self) -> bool {
21        self.extract_subject().ok() == Some(false)
22    }
23
24    pub fn is_true(&self) -> bool { self.extract_subject().ok() == Some(true) }
25
26    pub fn is_bool(&self) -> bool {
27        matches!(
28            self.extract_subject(),
29            Ok(dcbor::Simple::True | dcbor::Simple::False)
30        )
31    }
32}
33
34impl Envelope {
35    /// `true` if the envelope is a leaf node that contains a number, `false`
36    pub fn is_number(&self) -> bool {
37        self.as_leaf().map(|c| c.is_number()).unwrap_or(false)
38    }
39
40    /// `true` if the subject of the envelope is a number, `false`
41    /// otherwise.
42    pub fn is_subject_number(&self) -> bool { self.subject().is_number() }
43
44    /// `true` if the envelope is a leaf node that contains the NaN value,
45    /// `false` otherwise.
46    pub fn is_nan(&self) -> bool {
47        self.as_leaf().map(|c| c.is_nan()).unwrap_or(false)
48    }
49
50    /// `true` if the subject of the envelope is the NaN value, `false`
51    /// otherwise.
52    pub fn is_subject_nan(&self) -> bool { self.subject().is_nan() }
53}
54
55impl Envelope {
56    pub fn null() -> Self { Self::new_leaf(dcbor::Simple::Null) }
57
58    pub fn is_null(&self) -> bool {
59        self.extract_subject().ok() == Some(dcbor::Simple::Null)
60    }
61}
62
63impl Envelope {
64    /// The envelope's leaf CBOR object as a CBOR byte string, or an error if
65    /// the envelope is not a leaf, or the leaf is not a byte string.
66    pub fn try_byte_string(&self) -> anyhow::Result<Vec<u8>> {
67        Ok(self.try_leaf()?.try_into_byte_string()?)
68    }
69
70    pub fn as_byte_string(&self) -> Option<Vec<u8>> {
71        self.as_leaf().and_then(|c| c.into_byte_string())
72    }
73}
74
75impl Envelope {
76    pub fn as_array(&self) -> Option<Vec<CBOR>> {
77        self.as_leaf().and_then(|c| c.into_array())
78    }
79
80    pub fn as_map(&self) -> Option<dcbor::Map> {
81        self.as_leaf().and_then(|c| c.into_map())
82    }
83
84    pub fn as_text(&self) -> Option<String> {
85        self.as_leaf().and_then(|c| c.into_text())
86    }
87}
88
89#[cfg(feature = "known_value")]
90impl Envelope {
91    /// The envelope's `KnownValue`, or `None` if the envelope is not case
92    /// `::KnownValue`.
93    pub fn as_known_value(&self) -> Option<&KnownValue> {
94        match self.case() {
95            EnvelopeCase::KnownValue { value, .. } => Some(value),
96            _ => None,
97        }
98    }
99
100    /// The envelope's `KnownValue`, or an error if the envelope is not case
101    /// `::KnownValue`.
102    pub fn try_known_value(&self) -> anyhow::Result<&KnownValue> {
103        self.as_known_value().ok_or(Error::NotKnownValue.into())
104    }
105
106    /// `true` if the envelope is case `::KnownValue`, `false` otherwise.
107    pub fn is_known_value(&self) -> bool {
108        matches!(self.case(), EnvelopeCase::KnownValue { .. })
109    }
110
111    pub fn unit() -> Self { Self::new_leaf(known_values::UNIT) }
112
113    pub fn is_subject_unit(&self) -> bool {
114        self.extract_subject().ok() == Some(known_values::UNIT)
115    }
116}