bc_envelope/base/
wrap.rs

1use anyhow::{Result, bail};
2
3use super::envelope::EnvelopeCase;
4use crate::{Envelope, Error};
5
6/// Support for wrapping and unwrapping envelopes.
7impl Envelope {
8    /// Returns a new envelope which wraps the current envelope.
9    ///
10    /// Wrapping an envelope allows you to treat an envelope (including its
11    /// assertions) as a single unit, making it possible to add assertions
12    /// about the envelope as a whole.
13    ///
14    /// # Examples
15    ///
16    /// ```
17    /// # use bc_envelope::prelude::*;
18    /// # use indoc::indoc;
19    /// // Create an envelope with an assertion
20    /// let envelope = Envelope::new("Hello.").add_assertion("language", "English");
21    ///
22    /// // Wrap it to add an assertion about the envelope as a whole
23    /// let wrapped = envelope.wrap().add_assertion("authenticated", true);
24    ///
25    /// assert_eq!(
26    ///     wrapped.format(),
27    ///     indoc! {r#"
28    /// {
29    ///     "Hello." [
30    ///         "language": "English"
31    ///     ]
32    /// } [
33    ///     "authenticated": true
34    /// ]
35    /// "#}
36    ///     .trim()
37    /// );
38    /// ```
39    pub fn wrap(&self) -> Self { Self::new_wrapped(self.clone()) }
40
41    /// Unwraps and returns the inner envelope.
42    ///
43    /// This extracts the envelope contained within a wrapped envelope.
44    ///
45    /// # Errors
46    ///
47    /// Returns `EnvelopeError::NotWrapped` if this is not a wrapped envelope.
48    ///
49    /// # Examples
50    ///
51    /// ```
52    /// # use bc_envelope::prelude::*;
53    /// // Create an envelope and wrap it
54    /// let envelope = Envelope::new("Hello.");
55    /// let wrapped = envelope.wrap();
56    ///
57    /// // Unwrap to get the original envelope
58    /// let unwrapped = wrapped.try_unwrap().unwrap();
59    /// assert_eq!(unwrapped.format_flat(), r#""Hello.""#);
60    /// ```
61    pub fn try_unwrap(&self) -> Result<Self> {
62        match self.subject().case() {
63            EnvelopeCase::Wrapped { envelope, .. } => Ok(envelope.clone()),
64            _ => bail!(Error::NotWrapped),
65        }
66    }
67}