Skip to main content

pixelflow_core/
error.rs

1//! Structured error types for PixelFlow core and downstream crates.
2
3use std::error::Error;
4use std::fmt;
5
6/// Convenient result alias for PixelFlow operations.
7pub type Result<T> = std::result::Result<T, PixelFlowError>;
8
9/// Stable high-level category for routing errors across APIs and plugins.
10#[derive(Clone, Copy, Debug, Eq, PartialEq)]
11pub enum ErrorCategory {
12    /// Failure in core graph, render, scheduler, cache, frame, or metadata logic.
13    Core,
14    /// Failure while constructing or validating graph topology.
15    Graph,
16    /// Failure produced by script parsing, evaluation, or script-to-graph binding.
17    Script,
18    /// Failure produced by plugin loading, registration, or execution.
19    Plugin,
20    /// Failure produced by source indexing, fingerprinting, or decoding.
21    Source,
22    /// Failure caused by unsupported or inconsistent pixel format information.
23    Format,
24    /// Failure while reading from or writing to an external resource.
25    Io,
26    /// Internal invariant violation that should be reported as a bug.
27    Internal,
28}
29
30impl ErrorCategory {
31    /// Returns a stable lowercase category name for diagnostics and ABI mapping.
32    #[must_use]
33    pub const fn as_str(self) -> &'static str {
34        match self {
35            Self::Core => "core",
36            Self::Graph => "graph",
37            Self::Script => "script",
38            Self::Plugin => "plugin",
39            Self::Source => "source",
40            Self::Format => "format",
41            Self::Io => "io",
42            Self::Internal => "internal",
43        }
44    }
45}
46
47impl fmt::Display for ErrorCategory {
48    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
49        formatter.write_str(self.as_str())
50    }
51}
52
53/// Stable machine-readable error code within an [`ErrorCategory`].
54#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
55pub struct ErrorCode(&'static str);
56
57impl ErrorCode {
58    /// Creates an error code from a static dotted identifier.
59    #[must_use]
60    pub const fn new(code: &'static str) -> Self {
61        Self(code)
62    }
63
64    /// Returns the stable code string.
65    #[must_use]
66    pub const fn as_str(self) -> &'static str {
67        self.0
68    }
69}
70
71impl fmt::Display for ErrorCode {
72    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
73        formatter.write_str(self.0)
74    }
75}
76
77/// Structured error value used by public PixelFlow APIs.
78#[derive(Debug)]
79pub struct PixelFlowError {
80    category: ErrorCategory,
81    code: ErrorCode,
82    message: String,
83}
84
85impl PixelFlowError {
86    /// Creates a structured error with stable category/code and human message.
87    #[must_use]
88    pub fn new(category: ErrorCategory, code: ErrorCode, message: impl Into<String>) -> Self {
89        Self {
90            category,
91            code,
92            message: message.into(),
93        }
94    }
95
96    /// Returns high-level error category.
97    #[must_use]
98    pub const fn category(&self) -> ErrorCategory {
99        self.category
100    }
101
102    /// Returns machine-readable error code.
103    #[must_use]
104    pub const fn code(&self) -> ErrorCode {
105        self.code
106    }
107
108    /// Returns human-readable diagnostic message.
109    #[must_use]
110    pub fn message(&self) -> &str {
111        &self.message
112    }
113}
114
115impl fmt::Display for PixelFlowError {
116    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
117        write!(
118            formatter,
119            "{} error {}: {}",
120            self.category, self.code, self.message
121        )
122    }
123}
124
125impl Error for PixelFlowError {}