dmx_rdm/
unique_identifier.rs1use crate::consts::BROADCAST_UID;
2use crate::rdm_types::DeserializationError;
3
4#[derive(Debug, Copy, Clone, Eq, PartialEq)]
10pub struct UniqueIdentifier {
11 manufacturer_uid: u16,
12 device_uid: u32,
13}
14
15impl core::fmt::Display for UniqueIdentifier {
16 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
17 write!(f, "{:04X}:{:08X}", self.manufacturer_uid, self.device_uid)
18 }
19}
20
21#[cfg(feature = "defmt")]
22impl defmt::Format for UniqueIdentifier {
23 fn format(&self, fmt: defmt::Formatter) {
24 defmt::write!(fmt, "{:04X}:{:08X}", self.manufacturer_uid, self.device_uid);
25 }
26}
27
28impl UniqueIdentifier {
29 pub const fn new(manufacturer_uid: u16, device_uid: u32) -> Result<Self, DeserializationError> {
30 if device_uid == u32::MAX || manufacturer_uid == u16::MAX {
31 return Err(DeserializationError);
32 }
33
34 Ok(UniqueIdentifier {
35 manufacturer_uid,
36 device_uid,
37 })
38 }
39
40 pub fn manufacturer_uid(&self) -> u16 {
41 self.manufacturer_uid
42 }
43
44 pub fn device_uid(&self) -> u32 {
45 self.device_uid
46 }
47
48 pub fn set_manufacturer_uid(
49 &mut self,
50 manufacturer_uid: u16,
51 ) -> Result<(), DeserializationError> {
52 if manufacturer_uid == u16::MAX {
53 return Err(DeserializationError);
54 }
55
56 self.manufacturer_uid = manufacturer_uid;
57 Ok(())
58 }
59
60 pub fn set_device_uid(&mut self, device_uid: u32) -> Result<(), DeserializationError> {
61 if device_uid == u32::MAX {
62 return Err(DeserializationError);
63 }
64
65 self.device_uid = device_uid;
66 Ok(())
67 }
68
69 pub fn to_bytes(&self) -> [u8; 6] {
70 let mut buffer = [0u8; 6];
71
72 buffer[..2].copy_from_slice(&self.manufacturer_uid.to_be_bytes());
73 buffer[2..].copy_from_slice(&self.device_uid.to_be_bytes());
74
75 buffer
76 }
77}
78
79impl TryFrom<u64> for UniqueIdentifier {
80 type Error = DeserializationError;
81
82 fn try_from(value: u64) -> Result<Self, Self::Error> {
83 let manufacturer_uid = (value >> u32::BITS) as u16;
84 let device_uid = (value & u32::MAX as u64) as u32;
85
86 if device_uid == u32::MAX {
87 return Err(DeserializationError);
88 }
89
90 Ok(Self {
91 manufacturer_uid,
92 device_uid,
93 })
94 }
95}
96
97impl From<UniqueIdentifier> for u64 {
98 fn from(value: UniqueIdentifier) -> Self {
99 ((value.manufacturer_uid as u64) << u32::BITS) | value.device_uid as u64
100 }
101}
102
103#[derive(Debug, Copy, Clone, Eq, PartialEq)]
104#[cfg_attr(feature = "defmt", derive(defmt::Format))]
105pub enum PackageAddress {
106 Broadcast,
108 ManufacturerBroadcast(u16),
111 Device(UniqueIdentifier),
113}
114
115impl PackageAddress {
116 pub fn from_bytes(buffer: &[u8; 6]) -> Self {
117 let manufacturer_uid = u16::from_be_bytes(buffer[0..2].try_into().unwrap());
118 let device_uid = u32::from_be_bytes(buffer[2..].try_into().unwrap());
119
120 if device_uid == u32::MAX {
121 if manufacturer_uid == u16::MAX {
122 Self::Broadcast
123 } else {
124 Self::ManufacturerBroadcast(manufacturer_uid)
125 }
126 } else {
127 Self::Device(UniqueIdentifier {
128 manufacturer_uid,
129 device_uid,
130 })
131 }
132 }
133
134 pub fn to_bytes(&self) -> [u8; 6] {
135 match self {
136 Self::Broadcast => [0xFFu8; 6],
137 Self::ManufacturerBroadcast(manufacturer_uid) => {
138 let mut buffer = [0xFFu8; 6];
139 buffer[..2].copy_from_slice(&manufacturer_uid.to_be_bytes());
140
141 buffer
142 },
143 Self::Device(uid) => uid.to_bytes(),
144 }
145 }
146
147 pub fn is_broadcast(&self) -> bool {
148 match self {
149 PackageAddress::Broadcast => true,
150 PackageAddress::ManufacturerBroadcast(_) => true,
151 PackageAddress::Device(_) => false,
152 }
153 }
154}
155
156impl TryFrom<u64> for PackageAddress {
157 type Error = DeserializationError;
158
159 fn try_from(value: u64) -> Result<Self, Self::Error> {
160 if value >> 6 > 0 {
161 return Err(DeserializationError);
162 }
163
164 let manufacturer_uid = (value >> u32::BITS) as u16;
165 let device_uid = (value & u32::MAX as u64) as u32;
166
167 if device_uid == u32::MAX {
168 if manufacturer_uid == u16::MAX {
169 return Ok(Self::Broadcast);
170 }
171
172 return Ok(Self::ManufacturerBroadcast(manufacturer_uid));
173 }
174
175 Ok(Self::Device(UniqueIdentifier {
176 manufacturer_uid: 0,
177 device_uid: 0,
178 }))
179 }
180}
181
182impl From<PackageAddress> for u64 {
183 fn from(value: PackageAddress) -> Self {
184 match value {
185 PackageAddress::Broadcast => BROADCAST_UID,
186 PackageAddress::ManufacturerBroadcast(manufacturer_uid) => {
187 ((manufacturer_uid as u64) << u32::BITS) | u32::MAX as u64
188 },
189 PackageAddress::Device(uid) => uid.into(),
190 }
191 }
192}