playdate_device/device/
mod.rs1use std::hash::Hash;
2pub use nusb::DeviceInfo;
3use crate::usb::mode::DeviceMode;
4use crate::usb::mode::Mode;
5
6pub mod serial;
7pub mod query;
8pub mod command;
9
10mod methods;
11pub use methods::*;
12
13
14pub struct Device {
16 pub(crate) info: DeviceInfo,
18 pub(crate) mode: Mode,
19
20 pub(crate) inner: Option<nusb::Device>,
22
23 pub(crate) interface: Option<crate::interface::Interface>,
29}
30
31impl Eq for Device {}
32impl PartialEq for Device {
33 fn eq(&self, other: &Self) -> bool {
34 self.info.serial_number().is_some() && self.info.serial_number() == other.info.serial_number()
35 }
36}
37
38impl Hash for Device {
39 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
40 let info = &self.info;
41 info.serial_number().hash(state);
42 info.bus_number().hash(state);
43 info.device_address().hash(state);
44 info.vendor_id().hash(state);
45 info.product_id().hash(state);
46 info.class().hash(state);
47 info.subclass().hash(state);
48 info.protocol().hash(state);
49 info.manufacturer_string().hash(state);
50 info.product_string().hash(state);
51 self.inner.is_some().hash(state);
52 self.interface.is_some().hash(state);
53 }
54}
55
56
57impl AsRef<DeviceInfo> for Device {
58 fn as_ref(&self) -> &DeviceInfo { &self.info }
59}
60
61impl std::fmt::Display for Device {
62 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63 write!(
64 f,
65 "{}({})",
66 self.info.serial_number().unwrap_or("unknown"),
67 self.info.mode()
68 )
69 }
70}
71
72impl std::fmt::Debug for Device {
73 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
74 f.debug_struct("Device")
75 .field("sn", &self.info.serial_number())
76 .field("mode", &self.mode)
77 .field("open", &self.is_open())
78 .field("interface", &self.interface)
79 .finish()
80 }
81}
82
83
84impl Device {
85 pub fn new(info: DeviceInfo) -> Self {
86 Self { mode: info.mode(),
87 info,
88 inner: None,
89 interface: None }
90 }
91
92 pub fn info(&self) -> &DeviceInfo { &self.info }
93 pub fn into_info(self) -> DeviceInfo { self.info }
94
95
96 pub fn mode_cached(&self) -> Mode { self.mode }
100 pub fn is_open(&self) -> bool { self.inner.is_some() || self.is_ready() }
101 pub fn is_ready(&self) -> bool {
102 match self.interface.as_ref() {
103 Some(crate::interface::Interface::Usb(_)) => true,
104 Some(crate::interface::Interface::Serial(inner)) => inner.is_open(),
105 None => false,
106 }
107 }
108}