determinator/
errors.rs

1// Copyright (c) The cargo-guppy Contributors
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4//! Error types returned by the determinator.
5
6use crate::rules::RuleIndex;
7use std::{error, fmt};
8
9/// An error that occurred while resolving a set of determinator rules.
10#[derive(Debug)]
11pub struct RulesError {
12    rule_index: RuleIndex,
13    kind: RulesErrorKind,
14}
15
16impl RulesError {
17    /// Returns the index of the determinator rule that failed to parse.
18    pub fn rule_index(&self) -> RuleIndex {
19        self.rule_index
20    }
21
22    /// Returns the kind of error that occurred.
23    pub fn kind(&self) -> &RulesErrorKind {
24        &self.kind
25    }
26
27    // ---
28    // Internal constructors
29    // ---
30
31    pub(crate) fn resolve_ref(rule_index: RuleIndex, err: guppy::Error) -> Self {
32        Self {
33            rule_index,
34            kind: RulesErrorKind::ResolveRef(err),
35        }
36    }
37
38    pub(crate) fn glob_parse(rule_index: RuleIndex, err: globset::Error) -> Self {
39        let kind = RulesErrorKind::GlobParse {
40            glob: err.glob().map(|s| s.to_owned()),
41            err: Box::new(err),
42        };
43        Self { rule_index, kind }
44    }
45}
46
47impl fmt::Display for RulesError {
48    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
49        write!(
50            f,
51            "error while resolving determinator rules: {}: {}",
52            self.rule_index, self.kind
53        )
54    }
55}
56
57impl error::Error for RulesError {
58    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
59        match &self.kind {
60            RulesErrorKind::ResolveRef(err) => Some(err),
61            RulesErrorKind::GlobParse { err, .. } => Some(&**err),
62        }
63    }
64}
65
66/// The kind of error that occurred while parsing a set of determinator rules.
67#[derive(Debug)]
68#[non_exhaustive]
69pub enum RulesErrorKind {
70    /// An error occurred while resolving a reference in guppy.
71    ResolveRef(guppy::Error),
72
73    /// An error occurred while parsing a glob.
74    GlobParse {
75        /// The glob that failed to parse, if one was present.
76        glob: Option<String>,
77        /// The error that occurred while parsing the glob.
78        err: Box<dyn error::Error + Send + Sync>,
79    },
80}
81
82impl fmt::Display for RulesErrorKind {
83    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
84        match self {
85            RulesErrorKind::ResolveRef(err) => write!(f, "{}", err),
86            RulesErrorKind::GlobParse {
87                glob: Some(glob),
88                err,
89            } => write!(f, "while parsing glob '{}': {}", glob, err),
90            RulesErrorKind::GlobParse { glob: None, err } => {
91                write!(f, "while parsing a glob: {}", err)
92            }
93        }
94    }
95}