cddl_cat/
context.rs

1//! This module defines the LookupContext trait.
2//!
3//! A [`LookupContext`] is used to specify runtime behavior for validation.
4//! When a validation needs to resolve a rule reference, it will ask the
5//! `LookupContext` to perform the name resolution.
6//!
7
8use crate::ivt::{RuleDef, RulesByName};
9use crate::util::ValidateError;
10
11// The Node reference lives as long as the LookupContext does.
12type LookupResult<'a> = Result<&'a RuleDef, ValidateError>;
13
14/// A LookupContext contains any external information required for validation.
15///
16/// Right now, that only includes a function that understands how to resolve
17/// a name reference to an [`ivt::Rule`].
18///
19/// [`ivt::Rule`]: crate::ivt::Rule
20
21pub trait LookupContext {
22    /// Lookup a rule by name.
23    fn lookup_rule<'a>(&'a self, name: &str) -> LookupResult<'a>;
24}
25
26/// A simple context that owns a set of rules and can lookup rules by name.
27#[allow(missing_docs)]
28pub struct BasicContext {
29    pub rules: RulesByName,
30}
31
32impl BasicContext {
33    /// Create a new BasicContext from a rules map.
34    pub fn new(rules: RulesByName) -> BasicContext {
35        BasicContext { rules }
36    }
37}
38
39impl LookupContext for BasicContext {
40    fn lookup_rule<'a>(&'a self, name: &str) -> LookupResult<'a> {
41        match self.rules.get(name) {
42            Some(rule_def) => Ok(rule_def),
43            None => Err(ValidateError::MissingRule(name.into())),
44        }
45    }
46}
47
48#[doc(hidden)] // Only pub for integration tests
49#[allow(missing_docs)]
50pub mod tests {
51    use super::*;
52
53    /// A `LookupContext` that fails all rule lookups
54    pub struct DummyContext;
55
56    impl LookupContext for DummyContext {
57        fn lookup_rule<'a>(&'a self, name: &str) -> LookupResult<'a> {
58            Err(ValidateError::MissingRule(name.into()))
59        }
60    }
61}