Skip to main content

nl3/
error.rs

1//! Error types.
2use std::fmt;
3
4use crate::triple::Triple;
5
6/// An error produced while parsing a phrase into a triple.
7///
8/// Marked `#[non_exhaustive]`: match with a wildcard arm so future variants do
9/// not break your build.
10#[derive(Debug, Clone, PartialEq, Eq)]
11#[non_exhaustive]
12pub enum ParseError {
13    /// The supplied text was empty or whitespace-only and could not be parsed.
14    /// Ports the `"could not be parsed into a triple"` throw in `parse.js`.
15    EmptyInput,
16    /// The parsed triple is not valid in either direction against the grammar.
17    /// Ports the `"Invalid triple"` throw in `rules-processor.js`. The triple is
18    /// boxed to keep `Result<Triple, ParseError>` small on the common `Ok` path.
19    InvalidTriple(Box<Triple>),
20    /// A phrase omitted an entity type, and the matched predicate maps to more
21    /// than one candidate type in the grammar, so the type cannot be inferred
22    /// unambiguously. Only returned under [`crate::Ambiguity::Error`].
23    AmbiguousType {
24        /// The predicate whose subject/object type was ambiguous.
25        predicate: String,
26        /// The candidate types, in grammar declaration order.
27        candidates: Vec<String>,
28    },
29}
30
31impl fmt::Display for ParseError {
32    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33        match self {
34            ParseError::EmptyInput => {
35                write!(f, "the supplied text could not be parsed into a triple")
36            }
37            ParseError::InvalidTriple(triple) => write!(f, "invalid triple: {triple:?}"),
38            ParseError::AmbiguousType {
39                predicate,
40                candidates,
41            } => write!(
42                f,
43                "ambiguous type for predicate {predicate:?}: candidates {candidates:?}"
44            ),
45        }
46    }
47}
48
49impl std::error::Error for ParseError {}