Skip to main content

goud_engine/core/error/
conversions.rs

1//! Standard trait implementations and type conversions for [`GoudError`].
2//!
3//! Provides `Display`, `Error`, and `From` implementations to integrate
4//! `GoudError` with the standard Rust error ecosystem.
5
6use super::types::GoudError;
7
8// =============================================================================
9// Standard Trait Implementations
10// =============================================================================
11
12impl std::fmt::Display for GoudError {
13    /// Formats the error for user-friendly display.
14    ///
15    /// Format: `"[GOUD-{code}] {category}: {message}"`
16    ///
17    /// # Example
18    ///
19    /// ```
20    /// use goud_engine::core::error::GoudError;
21    ///
22    /// let error = GoudError::NotInitialized;
23    /// let display = format!("{}", error);
24    /// assert!(display.contains("[GOUD-1]"));
25    /// assert!(display.contains("Context"));
26    /// ```
27    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
28        write!(
29            f,
30            "[GOUD-{}] {}: {}",
31            self.error_code(),
32            self.category(),
33            self.message()
34        )
35    }
36}
37
38impl std::error::Error for GoudError {
39    /// Returns the source of this error, if any.
40    ///
41    /// Currently, `GoudError` does not wrap other errors, so this always returns `None`.
42    /// Future versions may add error chaining for wrapped errors.
43    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
44        None
45    }
46}
47
48// =============================================================================
49// Conversion Implementations
50// =============================================================================
51
52impl From<std::io::Error> for GoudError {
53    /// Converts an I/O error into a `GoudError`.
54    ///
55    /// The I/O error is mapped to an appropriate `GoudError` variant based on its kind:
56    /// - `NotFound` -> `ResourceNotFound`
57    /// - `PermissionDenied` -> `ResourceLoadFailed`
58    /// - Other -> `ResourceLoadFailed` with the error message
59    ///
60    /// # Example
61    ///
62    /// ```
63    /// use goud_engine::core::error::GoudError;
64    /// use std::io;
65    ///
66    /// let io_error = io::Error::new(io::ErrorKind::NotFound, "file not found");
67    /// let goud_error: GoudError = io_error.into();
68    /// assert!(matches!(goud_error, GoudError::ResourceNotFound(_)));
69    /// ```
70    fn from(error: std::io::Error) -> Self {
71        match error.kind() {
72            std::io::ErrorKind::NotFound => GoudError::ResourceNotFound(error.to_string()),
73            std::io::ErrorKind::PermissionDenied => {
74                GoudError::ResourceLoadFailed(format!("Permission denied: {}", error))
75            }
76            _ => GoudError::ResourceLoadFailed(error.to_string()),
77        }
78    }
79}
80
81impl From<String> for GoudError {
82    /// Converts a string into a `GoudError::InternalError`.
83    ///
84    /// This is a convenience conversion for creating internal errors from strings.
85    /// Use more specific error variants when the error category is known.
86    ///
87    /// # Example
88    ///
89    /// ```
90    /// use goud_engine::core::error::GoudError;
91    ///
92    /// let error: GoudError = "something went wrong".to_string().into();
93    /// assert!(matches!(error, GoudError::InternalError(_)));
94    /// ```
95    fn from(msg: String) -> Self {
96        GoudError::InternalError(msg)
97    }
98}
99
100impl From<&str> for GoudError {
101    /// Converts a string slice into a `GoudError::InternalError`.
102    ///
103    /// This is a convenience conversion for creating internal errors from string literals.
104    ///
105    /// # Example
106    ///
107    /// ```
108    /// use goud_engine::core::error::GoudError;
109    ///
110    /// let error: GoudError = "something went wrong".into();
111    /// assert!(matches!(error, GoudError::InternalError(_)));
112    /// ```
113    fn from(msg: &str) -> Self {
114        GoudError::InternalError(msg.to_string())
115    }
116}