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}