Skip to main content

paramodel_elements/
error.rs

1// Copyright (c) Jonathan Shook
2// SPDX-License-Identifier: Apache-2.0
3
4//! Crate-local error type for `paramodel-elements`.
5//!
6//! Per SRD-0003 D3, each paramodel crate owns a single `Error` enum
7//! and a local `Result<T>` alias. `paramodel-elements` is now the
8//! central algebra crate (after absorbing the former `paramodel-core`),
9//! so everything below ships here: name validation, domain / parameter
10//! / attribute / element / trial construction, regex compilation, and
11//! derivation evaluation.
12
13use crate::attributes::AttributeError;
14use crate::domain::DomainError;
15use crate::expression::DerivationError;
16use crate::names::NameError;
17use crate::parameter::ParameterError;
18use crate::trial::TrialError;
19
20/// Errors produced by `paramodel-elements`.
21#[derive(Debug, thiserror::Error)]
22pub enum Error {
23    /// A validated name (parameter, element, port, …) failed its
24    /// construction check.
25    #[error(transparent)]
26    Name(#[from] NameError),
27
28    /// A domain constructor or operation was rejected.
29    #[error(transparent)]
30    Domain(#[from] DomainError),
31
32    /// An attribute layer constructor or validation was rejected.
33    #[error(transparent)]
34    Attribute(#[from] AttributeError),
35
36    /// A parameter constructor or builder setter was rejected.
37    #[error(transparent)]
38    Parameter(#[from] ParameterError),
39
40    /// A derived-parameter expression failed at bind time.
41    #[error(transparent)]
42    Derivation(#[from] DerivationError),
43
44    /// A regex pattern failed to compile.
45    #[error("invalid regex: {0}")]
46    Regex(#[from] regex::Error),
47
48    /// An element-level validation or construction was rejected.
49    #[error(transparent)]
50    Element(#[from] ElementError),
51
52    /// A trial constructor (assignments, sampling strategy, ...)
53    /// rejected its inputs.
54    #[error(transparent)]
55    Trial(#[from] TrialError),
56}
57
58/// Crate-local result alias.
59pub type Result<T, E = Error> = std::result::Result<T, E>;
60
61// ---------------------------------------------------------------------------
62// ElementError.
63// ---------------------------------------------------------------------------
64
65/// Errors from `Element` construction and validation.
66#[derive(Debug, thiserror::Error)]
67pub enum ElementError {
68    /// A name-validation error bubbled up (e.g. the `type` label value
69    /// wasn't a valid `TypeId`).
70    #[error(transparent)]
71    Name(#[from] NameError),
72
73    /// An attribute-layer namespace check failed.
74    #[error(transparent)]
75    Attribute(#[from] AttributeError),
76
77    /// The element's `labels` are missing the `type` entry required
78    /// by SRD-0007 D8.
79    #[error("element is missing the required `type` label")]
80    MissingTypeLabel,
81
82    /// The element's `type` label names a type that isn't registered.
83    #[error("unknown element type '{type_id}'")]
84    UnknownElementType {
85        /// The unregistered type id.
86        type_id: String,
87    },
88
89    /// Two `Parameter`s in `Element.parameters` share a name.
90    #[error("duplicate parameter name '{name}' in element parameters")]
91    DuplicateParameterName {
92        /// The duplicated name.
93        name: String,
94    },
95
96    /// Two `Parameter`s in `Element.result_parameters` share a name.
97    #[error("duplicate parameter name '{name}' in element result_parameters")]
98    DuplicateResultParameterName {
99        /// The duplicated name.
100        name: String,
101    },
102
103    /// A configuration key references a parameter the element doesn't
104    /// declare.
105    #[error("configuration entry references unknown parameter '{name}'")]
106    UnknownConfigurationParameter {
107        /// The offending parameter name.
108        name: String,
109    },
110
111    /// A parameter name collides with a label / tag / port on the
112    /// same element.
113    #[error("parameter name '{name}' collides with an attribute or port name")]
114    ParameterNameCollidesWithAttribute {
115        /// The offending parameter name.
116        name: String,
117    },
118
119    /// `max_concurrency` is set to zero.
120    #[error("max_concurrency must be >= 1")]
121    InvalidMaxConcurrency,
122
123    /// `max_group_concurrency` exceeds `max_concurrency`.
124    #[error("max_group_concurrency ({group}) exceeds max_concurrency ({global})")]
125    GroupConcurrencyExceedsGlobal {
126        /// The group-level cap.
127        group:  u32,
128        /// The global cap it must not exceed.
129        global: u32,
130    },
131
132    /// A required label (declared by the type descriptor) is absent.
133    #[error("element is missing required label '{key}' for its type")]
134    MissingRequiredLabel {
135        /// The label key.
136        key: String,
137    },
138
139    /// A forbidden label (declared by the type descriptor) is present.
140    #[error("forbidden label '{key}' is present on this element: {reason}")]
141    ForbiddenLabelPresent {
142        /// The offending label key.
143        key:    String,
144        /// Descriptor-supplied explanation.
145        reason: String,
146    },
147
148    /// A `TokenExpr` was constructed from an empty string.
149    #[error("token expression must not be empty")]
150    EmptyTokenExpr,
151}