unity_asset_core/
error.rs

1//! Error types for Unity asset parsing
2
3use std::error::Error as StdError;
4use std::io;
5use thiserror::Error;
6
7/// Result type alias for Unity asset operations
8pub type Result<T> = std::result::Result<T, UnityAssetError>;
9
10/// Main error type for Unity asset parsing operations
11#[derive(Error, Debug)]
12pub enum UnityAssetError {
13    /// IO errors when reading/writing files
14    #[error("IO error: {0}")]
15    Io(#[from] io::Error),
16
17    /// Format parsing errors (YAML, binary, etc.)
18    #[error("Format parsing error: {0}")]
19    Format(String),
20
21    /// Unity-specific format errors
22    #[error("Unity format error: {message}")]
23    UnityFormat { message: String },
24
25    /// Class-related errors
26    #[error("Class error: {message}")]
27    Class { message: String },
28
29    /// Unknown class ID encountered
30    #[error("Unknown class ID: {class_id}")]
31    UnknownClassId { class_id: String },
32
33    /// Property access errors
34    #[error("Property '{property}' not found in class '{class_name}'")]
35    PropertyNotFound {
36        property: String,
37        class_name: String,
38    },
39
40    /// Type conversion errors
41    #[error("Type conversion error: cannot convert {from} to {to}")]
42    TypeConversion { from: String, to: String },
43
44    /// Anchor-related errors
45    #[error("Anchor error: {message}")]
46    Anchor { message: String },
47
48    /// Version compatibility errors
49    #[error("Version error: {message}")]
50    Version { message: String },
51
52    /// Generic parsing errors
53    #[error("Parse error: {message}")]
54    Parse { message: String },
55
56    /// Wrap an underlying error while preserving its type as a `source()`.
57    ///
58    /// This is used by higher-level crates (e.g. environment) to add context without losing
59    /// the original error kind (I/O, binary parser errors, etc).
60    #[error("{message}: {source}")]
61    WithSource {
62        message: String,
63        #[source]
64        source: Box<dyn StdError + Send + Sync + 'static>,
65    },
66}
67
68impl UnityAssetError {
69    /// Create a format error
70    pub fn format<S: Into<String>>(message: S) -> Self {
71        Self::Format(message.into())
72    }
73
74    /// Create a Unity format error
75    pub fn unity_format<S: Into<String>>(message: S) -> Self {
76        Self::UnityFormat {
77            message: message.into(),
78        }
79    }
80
81    /// Create a class error
82    pub fn class<S: Into<String>>(message: S) -> Self {
83        Self::Class {
84            message: message.into(),
85        }
86    }
87
88    /// Create a property not found error
89    pub fn property_not_found<S: Into<String>>(property: S, class_name: S) -> Self {
90        Self::PropertyNotFound {
91            property: property.into(),
92            class_name: class_name.into(),
93        }
94    }
95
96    /// Create a type conversion error
97    pub fn type_conversion<S: Into<String>>(from: S, to: S) -> Self {
98        Self::TypeConversion {
99            from: from.into(),
100            to: to.into(),
101        }
102    }
103
104    /// Create an anchor error
105    pub fn anchor<S: Into<String>>(message: S) -> Self {
106        Self::Anchor {
107            message: message.into(),
108        }
109    }
110
111    /// Create a version error
112    pub fn version<S: Into<String>>(message: S) -> Self {
113        Self::Version {
114            message: message.into(),
115        }
116    }
117
118    /// Create a parse error
119    pub fn parse<S: Into<String>>(message: S) -> Self {
120        Self::Parse {
121            message: message.into(),
122        }
123    }
124
125    /// Create a contextual error while preserving the underlying `source` error.
126    pub fn with_source<M, E>(message: M, source: E) -> Self
127    where
128        M: Into<String>,
129        E: StdError + Send + Sync + 'static,
130    {
131        Self::WithSource {
132            message: message.into(),
133            source: Box::new(source),
134        }
135    }
136}
137
138#[cfg(test)]
139mod tests {
140    use super::*;
141
142    #[test]
143    fn test_error_creation() {
144        let err = UnityAssetError::format("test message");
145        assert!(matches!(err, UnityAssetError::Format(_)));
146    }
147
148    #[test]
149    fn test_error_display() {
150        let err = UnityAssetError::property_not_found("m_Name", "GameObject");
151        let msg = format!("{}", err);
152        assert!(msg.contains("m_Name"));
153        assert!(msg.contains("GameObject"));
154    }
155}