Skip to main content

substrate_data/schema/reader/
expand.rs

1//! [`Expansion`]: what a reference read where a value may stand came to.
2
3use super::Reader;
4use crate::diagnostic::Problem;
5use crate::model::value::{Ref, Value};
6
7/// How many expanded values may be read inside one another: a value that
8/// expands to itself (through references that expand to references) stops
9/// here with a problem instead of never.
10pub const MAX_EXPANSION_DEPTH: usize = 32;
11
12/// What a reference read where a value may stand came to.
13#[derive(Debug, Clone, PartialEq)]
14pub enum Expansion {
15    /// The resolver keeps it a reference (or there is no resolver).
16    Kept,
17    /// The value in its place.
18    Value(Value),
19    /// The resolver refused it: the problem is reported.
20    Failed,
21}
22
23impl Reader<'_> {
24    /// `r`, at the current path, expanded by the resolver: what it came to
25    /// (a problem if the resolver refuses it).
26    pub fn expand_ref(&mut self, r: &Ref) -> Expansion {
27        let path = self.path();
28        let Some(resolver) = self.resolver.as_mut() else {
29            return Expansion::Kept;
30        };
31        match resolver.expand(r, &path) {
32            Ok(Some(value)) => Expansion::Value(value),
33            Ok(None) => Expansion::Kept,
34            Err(e) => {
35                self.problem_of(Problem::Unresolved, e.to_string());
36                Expansion::Failed
37            }
38        }
39    }
40
41    /// Runs `f`, which reads an expanded value, one expansion deeper; past
42    /// [`MAX_EXPANSION_DEPTH`] it is a problem and `f` isn't run.
43    pub fn expanded<T>(&mut self, f: impl FnOnce(&mut Self) -> Option<T>) -> Option<T> {
44        if self.expanding >= MAX_EXPANSION_DEPTH {
45            self.problem(format!(
46                "references expand into one another more than {MAX_EXPANSION_DEPTH} deep"
47            ));
48            return None;
49        }
50        self.expanding += 1;
51        let read = f(self);
52        self.expanding -= 1;
53        read
54    }
55}