Skip to main content

oxigaf_flame/
error.rs

1//! Error types for the FLAME module.
2
3/// Errors that can occur when working with the FLAME model.
4#[derive(Debug, thiserror::Error)]
5pub enum FlameError {
6    /// I/O error reading model files.
7    #[error("I/O error: {0}")]
8    Io(#[from] std::io::Error),
9
10    /// Error loading `.npy` array data.
11    #[error("Failed to load array '{name}': {source}")]
12    NpyLoad {
13        name: String,
14        source: ndarray_npy::ReadNpyError,
15    },
16
17    /// Error loading `.npz` archive data.
18    #[cfg(feature = "npz")]
19    #[error("Failed to load NPZ array '{name}': {source}")]
20    NpzLoad {
21        name: String,
22        source: ndarray_npy::ReadNpzError,
23    },
24
25    /// Array shape does not match expected dimensions.
26    #[error("Shape mismatch for '{name}': expected {expected}, got {got}")]
27    ShapeMismatch {
28        name: String,
29        expected: String,
30        got: String,
31    },
32
33    /// Model directory does not exist or is missing required files.
34    #[error("Model directory error: {0}")]
35    ModelDir(String),
36
37    /// Invalid parameter dimensions.
38    #[error("Invalid parameters: {0}")]
39    InvalidParams(String),
40
41    /// Export failed (OBJ/PLY/glTF).
42    #[error("Export failed: {format} - {reason}")]
43    Export {
44        /// Export format (e.g., "OBJ", "PLY", "glTF").
45        format: String,
46        /// Detailed reason for failure.
47        reason: String,
48    },
49
50    /// Animation sequence error.
51    #[error("Animation error at frame {frame}: {reason}")]
52    Animation {
53        /// Frame index where error occurred.
54        frame: usize,
55        /// Detailed reason for failure.
56        reason: String,
57    },
58
59    /// Landmark detection or projection error.
60    #[error("Landmark error for index {index}: {reason}")]
61    Landmark {
62        /// Landmark index that caused the error.
63        index: usize,
64        /// Detailed reason for failure.
65        reason: String,
66    },
67
68    /// Expression transfer failure.
69    #[error("Expression transfer failed: {reason}")]
70    Transfer {
71        /// Detailed reason for failure.
72        reason: String,
73    },
74
75    /// Numerical computation error (e.g., matrix inversion failure).
76    #[error("Numerical error: {reason}")]
77    Numerical {
78        /// Detailed reason for failure.
79        reason: String,
80    },
81
82    /// Index out of bounds error.
83    #[error("Index out of bounds: {context} - index {index} >= {len}")]
84    IndexOutOfBounds {
85        /// Context where the error occurred.
86        context: String,
87        /// The invalid index.
88        index: usize,
89        /// The maximum valid length.
90        len: usize,
91    },
92
93    /// Error loading safetensors file.
94    #[error("Failed to load safetensors from '{path}': {message}")]
95    SafeTensorsLoad {
96        /// Path to the safetensors file.
97        path: std::path::PathBuf,
98        /// Error details.
99        message: String,
100    },
101
102    /// Error saving safetensors file.
103    #[error("Failed to save safetensors to '{path}': {message}")]
104    SafeTensorsSave {
105        /// Path to the safetensors file.
106        path: std::path::PathBuf,
107        /// Error details.
108        message: String,
109    },
110
111    /// Missing tensor in safetensors file.
112    #[error("Missing tensor '{name}' in safetensors file: {message}")]
113    SafeTensorsMissing {
114        /// Name of the missing tensor.
115        name: String,
116        /// Error details.
117        message: String,
118    },
119
120    /// Invalid dtype in safetensors tensor.
121    #[error("Invalid dtype for tensor '{name}': expected {expected}, got {got}")]
122    SafeTensorsInvalidDtype {
123        /// Name of the tensor.
124        name: String,
125        /// Expected dtype.
126        expected: String,
127        /// Actual dtype.
128        got: String,
129    },
130
131    /// I/O error with path context.
132    #[error("I/O error for '{path}': {source}")]
133    IoError {
134        /// The I/O error source.
135        source: std::io::Error,
136        /// Path where error occurred.
137        path: std::path::PathBuf,
138    },
139}
140
141impl FlameError {
142    /// Create an export error with format and reason.
143    #[must_use]
144    pub fn export(format: impl Into<String>, reason: impl Into<String>) -> Self {
145        Self::Export {
146            format: format.into(),
147            reason: reason.into(),
148        }
149    }
150
151    /// Create an animation error with frame and reason.
152    #[must_use]
153    pub fn animation(frame: usize, reason: impl Into<String>) -> Self {
154        Self::Animation {
155            frame,
156            reason: reason.into(),
157        }
158    }
159
160    /// Create a landmark error with index and reason.
161    #[must_use]
162    pub fn landmark(index: usize, reason: impl Into<String>) -> Self {
163        Self::Landmark {
164            index,
165            reason: reason.into(),
166        }
167    }
168
169    /// Create a transfer error with reason.
170    #[must_use]
171    pub fn transfer(reason: impl Into<String>) -> Self {
172        Self::Transfer {
173            reason: reason.into(),
174        }
175    }
176
177    /// Create a numerical error with reason.
178    #[must_use]
179    pub fn numerical(reason: impl Into<String>) -> Self {
180        Self::Numerical {
181            reason: reason.into(),
182        }
183    }
184
185    /// Create an index out of bounds error.
186    #[must_use]
187    pub fn index_out_of_bounds(context: impl Into<String>, index: usize, len: usize) -> Self {
188        Self::IndexOutOfBounds {
189            context: context.into(),
190            index,
191            len,
192        }
193    }
194}