use crate::ptp::{EventCode, EventContainer, ObjectHandle, StorageId};
#[derive(Debug, Clone)]
pub enum DeviceEvent {
ObjectAdded {
handle: ObjectHandle,
},
ObjectRemoved {
handle: ObjectHandle,
},
StoreAdded {
storage_id: StorageId,
},
StoreRemoved {
storage_id: StorageId,
},
StorageInfoChanged {
storage_id: StorageId,
},
ObjectInfoChanged {
handle: ObjectHandle,
},
DeviceInfoChanged,
DeviceReset,
Unknown {
code: u16,
params: [u32; 3],
},
}
impl DeviceEvent {
#[must_use]
pub fn from_container(container: &EventContainer) -> Self {
match container.code {
EventCode::ObjectAdded => DeviceEvent::ObjectAdded {
handle: ObjectHandle(container.params[0]),
},
EventCode::ObjectRemoved => DeviceEvent::ObjectRemoved {
handle: ObjectHandle(container.params[0]),
},
EventCode::StoreAdded => DeviceEvent::StoreAdded {
storage_id: StorageId(container.params[0]),
},
EventCode::StoreRemoved => DeviceEvent::StoreRemoved {
storage_id: StorageId(container.params[0]),
},
EventCode::StorageInfoChanged => DeviceEvent::StorageInfoChanged {
storage_id: StorageId(container.params[0]),
},
EventCode::ObjectInfoChanged => DeviceEvent::ObjectInfoChanged {
handle: ObjectHandle(container.params[0]),
},
EventCode::DeviceInfoChanged => DeviceEvent::DeviceInfoChanged,
other => DeviceEvent::Unknown {
code: other.into(),
params: container.params,
},
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn event_parsing() {
for (code, expected_handle) in [
(EventCode::ObjectAdded, 42),
(EventCode::ObjectRemoved, 123),
(EventCode::ObjectInfoChanged, 99),
] {
let container = EventContainer {
code,
transaction_id: 0,
params: [expected_handle, 0, 0],
};
let event = DeviceEvent::from_container(&container);
let handle = match event {
DeviceEvent::ObjectAdded { handle } => handle,
DeviceEvent::ObjectRemoved { handle } => handle,
DeviceEvent::ObjectInfoChanged { handle } => handle,
_ => panic!("Unexpected event type"),
};
assert_eq!(handle, ObjectHandle(expected_handle));
}
for (code, expected_id) in [
(EventCode::StoreAdded, 0x00010001),
(EventCode::StoreRemoved, 0x00010002),
(EventCode::StorageInfoChanged, 0x00010001),
] {
let container = EventContainer {
code,
transaction_id: 0,
params: [expected_id, 0, 0],
};
let event = DeviceEvent::from_container(&container);
let storage_id = match event {
DeviceEvent::StoreAdded { storage_id } => storage_id,
DeviceEvent::StoreRemoved { storage_id } => storage_id,
DeviceEvent::StorageInfoChanged { storage_id } => storage_id,
_ => panic!("Unexpected event type"),
};
assert_eq!(storage_id, StorageId(expected_id));
}
let container = EventContainer {
code: EventCode::DeviceInfoChanged,
transaction_id: 0,
params: [0, 0, 0],
};
assert!(matches!(
DeviceEvent::from_container(&container),
DeviceEvent::DeviceInfoChanged
));
}
#[test]
fn unknown_events() {
let container = EventContainer {
code: EventCode::Unknown(0x9999),
transaction_id: 0,
params: [1, 2, 3],
};
match DeviceEvent::from_container(&container) {
DeviceEvent::Unknown { code, params } => {
assert_eq!(code, 0x9999);
assert_eq!(params, [1, 2, 3]);
}
_ => panic!("Expected Unknown event"),
}
let container = EventContainer {
code: EventCode::DevicePropChanged,
transaction_id: 0,
params: [100, 0, 0],
};
match DeviceEvent::from_container(&container) {
DeviceEvent::Unknown { code, params } => {
assert_eq!(code, 0x4006);
assert_eq!(params[0], 100);
}
_ => panic!("Expected Unknown event"),
}
}
}