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