Skip to main content

goud_engine/assets/hot_reload/
events.rs

1//! Asset change event types for the hot reload system.
2
3use std::fmt;
4use std::path::{Path, PathBuf};
5
6// =============================================================================
7// AssetChangeEvent
8// =============================================================================
9
10/// Event representing a change to an asset file.
11///
12/// Emitted by the hot reload system when a file is modified, created, or deleted.
13#[derive(Debug, Clone, PartialEq, Eq)]
14pub enum AssetChangeEvent {
15    /// Asset file was modified.
16    Modified {
17        /// The path to the modified asset.
18        path: PathBuf,
19    },
20
21    /// Asset file was created.
22    Created {
23        /// The path to the newly created asset.
24        path: PathBuf,
25    },
26
27    /// Asset file was deleted.
28    Deleted {
29        /// The path to the deleted asset.
30        path: PathBuf,
31    },
32
33    /// Asset file was renamed.
34    Renamed {
35        /// The old path of the asset.
36        from: PathBuf,
37        /// The new path of the asset.
38        to: PathBuf,
39    },
40}
41
42impl AssetChangeEvent {
43    /// Returns the primary path affected by this event.
44    pub fn path(&self) -> &Path {
45        match self {
46            Self::Modified { path } | Self::Created { path } | Self::Deleted { path } => path,
47            Self::Renamed { to, .. } => to,
48        }
49    }
50
51    /// Returns the event kind as a string.
52    pub fn kind_str(&self) -> &'static str {
53        match self {
54            Self::Modified { .. } => "Modified",
55            Self::Created { .. } => "Created",
56            Self::Deleted { .. } => "Deleted",
57            Self::Renamed { .. } => "Renamed",
58        }
59    }
60
61    /// Returns true if this is a modification event.
62    pub fn is_modified(&self) -> bool {
63        matches!(self, Self::Modified { .. })
64    }
65
66    /// Returns true if this is a creation event.
67    pub fn is_created(&self) -> bool {
68        matches!(self, Self::Created { .. })
69    }
70
71    /// Returns true if this is a deletion event.
72    pub fn is_deleted(&self) -> bool {
73        matches!(self, Self::Deleted { .. })
74    }
75
76    /// Returns true if this is a rename event.
77    pub fn is_renamed(&self) -> bool {
78        matches!(self, Self::Renamed { .. })
79    }
80}
81
82impl fmt::Display for AssetChangeEvent {
83    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
84        match self {
85            Self::Modified { path } => write!(f, "Modified: {}", path.display()),
86            Self::Created { path } => write!(f, "Created: {}", path.display()),
87            Self::Deleted { path } => write!(f, "Deleted: {}", path.display()),
88            Self::Renamed { from, to } => {
89                write!(f, "Renamed: {} -> {}", from.display(), to.display())
90            }
91        }
92    }
93}
94
95// =============================================================================
96// Tests
97// =============================================================================
98
99#[cfg(test)]
100mod tests {
101    use super::*;
102
103    #[test]
104    fn test_modified() {
105        let event = AssetChangeEvent::Modified {
106            path: PathBuf::from("test.png"),
107        };
108
109        assert_eq!(event.path(), Path::new("test.png"));
110        assert_eq!(event.kind_str(), "Modified");
111        assert!(event.is_modified());
112        assert!(!event.is_created());
113        assert!(!event.is_deleted());
114        assert!(!event.is_renamed());
115    }
116
117    #[test]
118    fn test_created() {
119        let event = AssetChangeEvent::Created {
120            path: PathBuf::from("new.png"),
121        };
122
123        assert_eq!(event.path(), Path::new("new.png"));
124        assert_eq!(event.kind_str(), "Created");
125        assert!(!event.is_modified());
126        assert!(event.is_created());
127    }
128
129    #[test]
130    fn test_deleted() {
131        let event = AssetChangeEvent::Deleted {
132            path: PathBuf::from("old.png"),
133        };
134
135        assert_eq!(event.path(), Path::new("old.png"));
136        assert_eq!(event.kind_str(), "Deleted");
137        assert!(event.is_deleted());
138    }
139
140    #[test]
141    fn test_renamed() {
142        let event = AssetChangeEvent::Renamed {
143            from: PathBuf::from("old.png"),
144            to: PathBuf::from("new.png"),
145        };
146
147        assert_eq!(event.path(), Path::new("new.png")); // Returns "to" path
148        assert_eq!(event.kind_str(), "Renamed");
149        assert!(event.is_renamed());
150    }
151
152    #[test]
153    fn test_display() {
154        let event = AssetChangeEvent::Modified {
155            path: PathBuf::from("test.png"),
156        };
157        let display = format!("{}", event);
158        assert!(display.contains("Modified"));
159        assert!(display.contains("test.png"));
160    }
161
162    #[test]
163    fn test_clone() {
164        let event = AssetChangeEvent::Modified {
165            path: PathBuf::from("test.png"),
166        };
167        let cloned = event.clone();
168        assert_eq!(event, cloned);
169    }
170}