Skip to main content

substrate_data/schema/reader/
resolve.rs

1//! [`Resolve`]: what a tool makes of the references it reads, and
2//! [`Unresolved`], why one is wrong.
3
4use std::fmt;
5
6use crate::model::value::{Path, Ref, RefKey, Value};
7
8/// What a tool makes of the references it reads: a build checks each one
9/// against what there is (and may rewrite its id), an editor shows them.
10pub trait Resolve {
11    /// A reference at `path`: the id to keep, or why it's wrong.
12    ///
13    /// # Errors
14    ///
15    /// [`Unresolved`] when the reference names nothing there is, or names
16    /// it in a way the tool refuses.
17    fn reference(&mut self, r: &Ref, path: &Path) -> Result<RefKey, Unresolved>;
18
19    /// A reference at `path` the tool replaces by a value — a word of a
20    /// dictionary, a localized text: `Some(value)` is read in its place,
21    /// `None` keeps it a reference. Asked only where a field says it takes
22    /// a value or a reference ([`with::Expand`](crate::with::Expand)); a
23    /// reference met anywhere else goes through [`Resolve::reference`].
24    ///
25    /// # Errors
26    ///
27    /// [`Unresolved`] when the reference names nothing there is, or names
28    /// it in a way the tool refuses.
29    fn expand(&mut self, _r: &Ref, _path: &Path) -> Result<Option<Value>, Unresolved> {
30        Ok(None)
31    }
32}
33
34/// Why a reference doesn't resolve.
35#[derive(Debug, Clone, PartialEq, Eq)]
36pub enum Unresolved {
37    /// There is nothing it names.
38    Missing(Ref),
39    /// It names something, but not in a way this tool takes (a reason for a person).
40    Refused {
41        /// The reference.
42        reference: Ref,
43        /// Why, for a person.
44        reason: String,
45    },
46}
47
48impl fmt::Display for Unresolved {
49    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50        match self {
51            Unresolved::Missing(r) => write!(f, "`{r}`: there is no such {}", r.kind),
52            Unresolved::Refused { reference, reason } => write!(f, "`{reference}`: {reason}"),
53        }
54    }
55}
56
57impl std::error::Error for Unresolved {}