bc_envelope/extension/
types.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
use anyhow::{bail, Result};
use bc_components::DigestProvider;

use crate::{Envelope, EnvelopeEncodable, EnvelopeError};
use crate::extension::{known_values, KnownValue};

impl Envelope {
    /// Returns the result of adding the given `'IsA'` type assertion to the envelope.
    pub fn add_type(&self, object: impl EnvelopeEncodable) -> Self {
        self.add_assertion(known_values::IS_A, object)
    }

    /// Returns all of the envelope's `'IsA'` type assertions.
    pub fn types(&self) -> Vec<Self> {
        self.objects_for_predicate(known_values::IS_A)
    }

    /// Gets a single `'IsA'` type assertion from the envelope.
    ///
    /// If there is more than one `'IsA'` type assertion, returns an error.
    pub fn get_type(&self) -> Result<Self> {
        let t = self.types();
        if t.len() == 1 {
            Ok(t[0].clone())
        } else {
            bail!(EnvelopeError::AmbiguousType)
        }
    }

    /// Returns `true` if the envelope has an `'IsA'` type assertion with the given envelope `t`'s digest.
    pub fn has_type_envelope(&self, t: impl EnvelopeEncodable) -> bool {
        let e = t.into_envelope();
        self.types().iter().any(|x| x.digest() == e.digest())
    }

    /// Returns `true` if the envelope has an `'IsA'` type assertion with the given known value `t`.
    pub fn has_type(&self, t: &KnownValue) -> bool {
        let type_envelope: Envelope = t.clone().to_envelope();
        self.types().iter().any(|x| x.digest() == type_envelope.digest())
    }

    /// Succeeds if the envelope has an `'IsA'` type assertion with the given known value `t`.
    ///
    /// Fails with `EnvelopeError::InvalidType` otherwise.
    pub fn check_type(&self, t: &KnownValue) -> Result<()> {
        if self.has_type(t) {
            Ok(())
        } else {
            bail!(EnvelopeError::InvalidType)
        }
    }

    /// Succeeds if the envelope has an `'IsA'` type assertion with the given envelope `t`'s digest.
    ///
    /// Fails with `EnvelopeError::InvalidType` otherwise.
    pub fn check_type_envelope(&self, t: impl EnvelopeEncodable) -> Result<()> {
        if self.has_type_envelope(t) {
            Ok(())
        } else {
            bail!(EnvelopeError::InvalidType)
        }
    }
}