1use crate::ptp::{EventCode, EventContainer, ObjectHandle, StorageId};
4
5#[derive(Debug, Clone)]
7pub enum DeviceEvent {
8 ObjectAdded {
10 handle: ObjectHandle,
12 },
13
14 ObjectRemoved {
16 handle: ObjectHandle,
18 },
19
20 StoreAdded {
22 storage_id: StorageId,
24 },
25
26 StoreRemoved {
28 storage_id: StorageId,
30 },
31
32 StorageInfoChanged {
34 storage_id: StorageId,
36 },
37
38 ObjectInfoChanged {
40 handle: ObjectHandle,
42 },
43
44 DeviceInfoChanged,
46
47 DeviceReset,
49
50 Unknown {
52 code: u16,
54 params: [u32; 3],
56 },
57}
58
59impl DeviceEvent {
60 #[must_use]
62 pub fn from_container(container: &EventContainer) -> Self {
63 match container.code {
64 EventCode::ObjectAdded => DeviceEvent::ObjectAdded {
65 handle: ObjectHandle(container.params[0]),
66 },
67 EventCode::ObjectRemoved => DeviceEvent::ObjectRemoved {
68 handle: ObjectHandle(container.params[0]),
69 },
70 EventCode::StoreAdded => DeviceEvent::StoreAdded {
71 storage_id: StorageId(container.params[0]),
72 },
73 EventCode::StoreRemoved => DeviceEvent::StoreRemoved {
74 storage_id: StorageId(container.params[0]),
75 },
76 EventCode::StorageInfoChanged => DeviceEvent::StorageInfoChanged {
77 storage_id: StorageId(container.params[0]),
78 },
79 EventCode::ObjectInfoChanged => DeviceEvent::ObjectInfoChanged {
80 handle: ObjectHandle(container.params[0]),
81 },
82 EventCode::DeviceInfoChanged => DeviceEvent::DeviceInfoChanged,
83 other => DeviceEvent::Unknown {
85 code: other.into(),
86 params: container.params,
87 },
88 }
89 }
90}
91
92#[cfg(test)]
93mod tests {
94 use super::*;
95
96 #[test]
97 fn event_parsing() {
98 for (code, expected_handle) in [
100 (EventCode::ObjectAdded, 42),
101 (EventCode::ObjectRemoved, 123),
102 (EventCode::ObjectInfoChanged, 99),
103 ] {
104 let container = EventContainer {
105 code,
106 transaction_id: 0,
107 params: [expected_handle, 0, 0],
108 };
109 let event = DeviceEvent::from_container(&container);
110 let handle = match event {
111 DeviceEvent::ObjectAdded { handle } => handle,
112 DeviceEvent::ObjectRemoved { handle } => handle,
113 DeviceEvent::ObjectInfoChanged { handle } => handle,
114 _ => panic!("Unexpected event type"),
115 };
116 assert_eq!(handle, ObjectHandle(expected_handle));
117 }
118
119 for (code, expected_id) in [
121 (EventCode::StoreAdded, 0x00010001),
122 (EventCode::StoreRemoved, 0x00010002),
123 (EventCode::StorageInfoChanged, 0x00010001),
124 ] {
125 let container = EventContainer {
126 code,
127 transaction_id: 0,
128 params: [expected_id, 0, 0],
129 };
130 let event = DeviceEvent::from_container(&container);
131 let storage_id = match event {
132 DeviceEvent::StoreAdded { storage_id } => storage_id,
133 DeviceEvent::StoreRemoved { storage_id } => storage_id,
134 DeviceEvent::StorageInfoChanged { storage_id } => storage_id,
135 _ => panic!("Unexpected event type"),
136 };
137 assert_eq!(storage_id, StorageId(expected_id));
138 }
139
140 let container = EventContainer {
142 code: EventCode::DeviceInfoChanged,
143 transaction_id: 0,
144 params: [0, 0, 0],
145 };
146 assert!(matches!(
147 DeviceEvent::from_container(&container),
148 DeviceEvent::DeviceInfoChanged
149 ));
150 }
151
152 #[test]
153 fn unknown_events() {
154 let container = EventContainer {
156 code: EventCode::Unknown(0x9999),
157 transaction_id: 0,
158 params: [1, 2, 3],
159 };
160 match DeviceEvent::from_container(&container) {
161 DeviceEvent::Unknown { code, params } => {
162 assert_eq!(code, 0x9999);
163 assert_eq!(params, [1, 2, 3]);
164 }
165 _ => panic!("Expected Unknown event"),
166 }
167
168 let container = EventContainer {
170 code: EventCode::DevicePropChanged,
171 transaction_id: 0,
172 params: [100, 0, 0],
173 };
174 match DeviceEvent::from_container(&container) {
175 DeviceEvent::Unknown { code, params } => {
176 assert_eq!(code, 0x4006);
177 assert_eq!(params[0], 100);
178 }
179 _ => panic!("Expected Unknown event"),
180 }
181 }
182}