Skip to main content

alpha2_engine/
error.rs

1use std::fmt;
2
3/// Failure produced by an engine runner.
4#[derive(Clone, Debug, PartialEq, Eq)]
5#[non_exhaustive]
6pub enum EngineError {
7    /// Timeline evaluation failed.
8    Evaluate(alpha2_eval::EvalError),
9    /// GPU rendering failed.
10    Render(alpha2_render::RenderError),
11    /// A quality profile contains an unusable value.
12    InvalidQualityProfile,
13    /// A frame index or scaled output size cannot be represented.
14    OutOfRange,
15    /// An exporter requires a non-empty timeline interval.
16    EmptyExportRange,
17    /// An export schedule exceeds the bounded frame budget.
18    ExportTooLarge {
19        /// Requested frame count.
20        frames: u64,
21        /// Largest supported frame count.
22        maximum: u64,
23    },
24    /// A caption or a text generator could not be rasterized or uploaded.
25    Text(crate::TextError),
26    /// An audio renderer received an unsupported layout, rate, or block size.
27    InvalidAudioConfiguration,
28    /// A loudness normalization gain is not finite, or its linear factor is
29    /// not a finite, positive 32-bit float.
30    InvalidNormalizationGain,
31    /// The project draws an effect the renderer has not registered, or
32    /// whose registration failed.
33    UnregisteredEffect {
34        /// The effect's id.
35        effect: String,
36        /// Its version.
37        version: u32,
38    },
39    /// An export step was given another snapshot than the one its exporter
40    /// was made for.
41    ExportProjectChanged,
42    /// A 4:2:0 export was asked for an output with an odd width or height.
43    ///
44    /// Its chroma planes are half size, and H.264 and HEVC crop in two-pixel
45    /// steps, so the bitstream cannot carry an odd size. The project canvas
46    /// may be odd; making the output even is the host's choice.
47    OddExportDimensions {
48        /// Output width.
49        width: u32,
50        /// Output height.
51        height: u32,
52        /// The nearest even size, each odd dimension one pixel smaller
53        /// (larger for a one-pixel dimension).
54        suggested: (u32, u32),
55    },
56}
57
58impl fmt::Display for EngineError {
59    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
60        match self {
61            Self::Evaluate(error) => write!(formatter, "timeline evaluation failed: {error}"),
62            Self::Render(error) => write!(formatter, "rendering failed: {error}"),
63            Self::InvalidQualityProfile => formatter.write_str("quality profile is invalid"),
64            Self::OutOfRange => formatter.write_str("timeline or output size is out of range"),
65            Self::EmptyExportRange => formatter.write_str("export range must not be empty"),
66            Self::ExportTooLarge { frames, maximum } => write!(
67                formatter,
68                "export requests {frames} frames; the maximum is {maximum}"
69            ),
70            Self::Text(error) => write!(formatter, "{error}"),
71            Self::InvalidAudioConfiguration => {
72                formatter.write_str("audio channel layout, sample rate, or block size is invalid")
73            }
74            Self::InvalidNormalizationGain => formatter.write_str(
75                "loudness normalization gain is not finite or past what a 32-bit float factor holds",
76            ),
77            Self::UnregisteredEffect { effect, version } => write!(
78                formatter,
79                "the project draws effect {effect}@{version}, which is not registered"
80            ),
81            Self::ExportProjectChanged => formatter.write_str(
82                "an export step was given another project than the export was started with",
83            ),
84            Self::OddExportDimensions {
85                width,
86                height,
87                suggested: (suggested_width, suggested_height),
88            } => write!(
89                formatter,
90                "4:2:0 video export must have even dimensions, but the output is \
91                 {width}x{height}; the nearest even size is {suggested_width}x{suggested_height}"
92            ),
93        }
94    }
95}
96
97impl std::error::Error for EngineError {
98    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
99        match self {
100            Self::Evaluate(error) => Some(error),
101            Self::Render(error) => Some(error),
102            _ => None,
103        }
104    }
105}
106
107impl From<alpha2_eval::EvalError> for EngineError {
108    fn from(error: alpha2_eval::EvalError) -> Self {
109        Self::Evaluate(error)
110    }
111}
112
113impl From<alpha2_render::RenderError> for EngineError {
114    fn from(error: alpha2_render::RenderError) -> Self {
115        Self::Render(error)
116    }
117}