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}