Skip to main content

ifc_validate/
error.rs

1//! Why validation could not run.
2//!
3//! Distinct from a [`Finding`](crate::report::Finding): a finding says the
4//! *file* is wrong, this says the *validator* could not proceed. Conflating
5//! them would let "we could not check this" be read as "this is fine".
6
7use std::fmt;
8
9/// Validation could not be performed.
10#[derive(Debug, Clone, PartialEq, Eq)]
11#[non_exhaustive]
12pub enum ValidateError {
13    /// The `FILE_SCHEMA` token is not a schema version this crate recognises.
14    ///
15    /// Carries the token as written, so the caller can report it verbatim.
16    UnknownSchema(String),
17    /// A recognised schema version for which this build bundles no tables.
18    ///
19    /// Separate from [`Self::UnknownSchema`] because the remedy differs: an
20    /// unknown token usually means a malformed or non-IFC file, while an
21    /// unbundled schema is a known gap in this build. Reporting both as
22    /// "unknown" would hide which one a user is hitting.
23    UnbundledSchema(String),
24    /// The file declares no schema at all.
25    NoSchemaDeclared,
26}
27
28impl fmt::Display for ValidateError {
29    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30        match self {
31            Self::UnknownSchema(token) => {
32                write!(f, "unrecognised schema token {token:?}")
33            }
34            Self::UnbundledSchema(token) => {
35                write!(f, "no schema tables bundled for {token:?}")
36            }
37            Self::NoSchemaDeclared => f.write_str("the file declares no schema"),
38        }
39    }
40}
41
42impl std::error::Error for ValidateError {}
43
44#[cfg(test)]
45mod tests {
46    use super::*;
47
48    /// The two refusals must not read alike: one is a bad token, the other a
49    /// known schema this build cannot check.
50    #[test]
51    fn the_two_schema_refusals_are_distinguishable() {
52        let unknown = ValidateError::UnknownSchema("STEP".into()).to_string();
53        let unbundled = ValidateError::UnbundledSchema("IFC_FUTURE_PROFILE".into()).to_string();
54        assert_ne!(unknown, unbundled);
55        assert!(unbundled.contains("IFC_FUTURE_PROFILE"));
56        assert!(unknown.contains("STEP"));
57    }
58}