Skip to main content

copperlace/render/
error.rs

1use std::fmt;
2
3/// Error returned while compiling or rendering Copperlace rules.
4#[derive(Debug, PartialEq, Eq)]
5pub enum RenderError {
6    /// A template referenced a name that is neither bound nor defined as a rule.
7    UnknownRule(String),
8    /// A template pipeline referenced a processor that is not registered.
9    UnknownProcessor(String),
10    /// A registered processor rejected the rendered value.
11    ProcessorError { processor: String, message: String },
12    /// A `{...}` template expression could not be parsed.
13    InvalidExpression(String),
14    /// An array-backed choice rule had no alternatives.
15    EmptyChoice,
16    /// A strict unique choice call used every usable alternative.
17    ExhaustedUniqueChoice(String),
18    /// A strict unique choice call reached a rule that is not an array-backed choice.
19    UnsupportedUniqueChoice(String),
20    /// A weighted choice config entry is malformed.
21    InvalidWeightedChoice(String),
22    /// Rendering detected a recursive rule cycle.
23    CircularRuleReference(Vec<String>),
24    /// A config value type was parsed but is not renderable.
25    UnsupportedValue(String),
26    /// A loop source resolved successfully but is not iterable.
27    UnsupportedIterationSource {
28        /// Source expression from the `for` statement.
29        source: String,
30        /// Resolved value type.
31        value_type: String,
32    },
33    /// An overwrite binding targeted an immutable loop value.
34    ImmutableLoopBinding(String),
35    /// The root configuration value was not an object.
36    InvalidConfigRoot,
37    /// A structured render was requested for a non-object path.
38    UnsupportedStructuredTarget(String),
39    /// A structured value could not be serialized to JSON.
40    JsonSerialization(String),
41}
42
43impl fmt::Display for RenderError {
44    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
45        match self {
46            RenderError::UnknownRule(rule) => write!(formatter, "unknown rule: {rule}"),
47            RenderError::UnknownProcessor(processor) => {
48                write!(formatter, "unknown processor: {processor}")
49            }
50            RenderError::ProcessorError { processor, message } => {
51                write!(formatter, "processor {processor} failed: {message}")
52            }
53            RenderError::InvalidExpression(expression) => {
54                write!(formatter, "invalid template expression: {expression}")
55            }
56            RenderError::EmptyChoice => write!(formatter, "cannot render an empty choice"),
57            RenderError::ExhaustedUniqueChoice(rule) => {
58                write!(formatter, "exhausted unique choice: {rule}")
59            }
60            RenderError::UnsupportedUniqueChoice(rule) => {
61                write!(formatter, "unique choice target is not a choice: {rule}")
62            }
63            RenderError::InvalidWeightedChoice(message) => {
64                write!(formatter, "invalid weighted choice: {message}")
65            }
66            RenderError::CircularRuleReference(cycle) => {
67                write!(formatter, "circular rule reference: {}", cycle.join(" -> "))
68            }
69            RenderError::UnsupportedValue(value_type) => {
70                write!(formatter, "unsupported value type: {value_type}")
71            }
72            RenderError::UnsupportedIterationSource { source, value_type } => {
73                write!(
74                    formatter,
75                    "iteration source is not iterable: {source} ({value_type})"
76                )
77            }
78            RenderError::ImmutableLoopBinding(name) => {
79                write!(formatter, "cannot overwrite immutable loop binding: {name}")
80            }
81            RenderError::InvalidConfigRoot => write!(formatter, "config root must be an object"),
82            RenderError::UnsupportedStructuredTarget(rule) => {
83                write!(
84                    formatter,
85                    "structured render target must be an object: {rule}"
86                )
87            }
88            RenderError::JsonSerialization(message) => {
89                write!(
90                    formatter,
91                    "failed to serialize structured value as JSON: {message}"
92                )
93            }
94        }
95    }
96}
97
98impl std::error::Error for RenderError {}