simple_doip/
logical_address.rs1use core::fmt::{Debug, Display, LowerHex, UpperHex};
5#[cfg(feature = "std")]
6use tracing::info;
7
8#[derive(Clone, Copy, Eq)]
9pub struct LogicalAddress(
15 pub u16,
17);
18
19impl LogicalAddress {
20 pub const MIN_CLIENT_ADDRESS: LogicalAddress = LogicalAddress(0x0E00);
24 pub const MAX_CLIENT_ADDRESS: LogicalAddress = LogicalAddress(0x0FFF);
27
28 pub const OBD_ADDRESS_RANGE: (LogicalAddress, LogicalAddress) =
35 (LogicalAddress(0x0F00), LogicalAddress(0x0F7F));
36
37 #[must_use]
40 pub fn is_valid_client_address(&self) -> bool {
41 if *self >= Self::MIN_CLIENT_ADDRESS && *self <= Self::MAX_CLIENT_ADDRESS {
42 if *self >= Self::OBD_ADDRESS_RANGE.0 && *self <= Self::OBD_ADDRESS_RANGE.1 {
47 #[cfg(feature = "std")]
48 info!(
49 "Logical addresses in the 0x0F00-0x0F7F range are intended for internal \
50 data collection/on-board diagnostics only. Ensure that this is the intended use case."
51 );
52 }
53 true
54 } else {
55 false
56 }
57 }
58}
59
60impl Display for LogicalAddress {
61 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
62 write!(f, "{:#06X}", self.0)
63 }
64}
65impl Debug for LogicalAddress {
66 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
67 write!(f, "{:#06X}", self.0)
68 }
69}
70impl UpperHex for LogicalAddress {
71 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
72 UpperHex::fmt(&self.0, f)
73 }
74}
75impl LowerHex for LogicalAddress {
76 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
77 LowerHex::fmt(&self.0, f)
78 }
79}
80impl From<u16> for LogicalAddress {
81 fn from(addr: u16) -> Self {
82 LogicalAddress(addr)
83 }
84}
85impl From<LogicalAddress> for u16 {
86 fn from(addr: LogicalAddress) -> Self {
87 addr.0
88 }
89}
90impl PartialOrd<u16> for LogicalAddress {
91 fn partial_cmp(&self, other: &u16) -> Option<core::cmp::Ordering> {
92 self.0.partial_cmp(other)
93 }
94}
95impl PartialOrd<LogicalAddress> for LogicalAddress {
96 fn partial_cmp(&self, other: &LogicalAddress) -> Option<core::cmp::Ordering> {
97 self.0.partial_cmp(&other.0)
98 }
99}
100impl PartialEq<u16> for LogicalAddress {
101 fn eq(&self, other: &u16) -> bool {
102 self.0 == *other
103 }
104}
105impl PartialEq<LogicalAddress> for LogicalAddress {
106 fn eq(&self, other: &LogicalAddress) -> bool {
107 self.0 == other.0
108 }
109}
110
111#[cfg(test)]
112mod tests {
113 use super::*;
114
115 #[test]
116 fn test_logical_address() {
117 let addr = LogicalAddress(0x0E00);
118 assert!(addr.is_valid_client_address());
119 assert_eq!(addr.0, 0x0E00);
120 assert_eq!(addr, LogicalAddress(0x0E00));
121 assert_eq!(addr, 0x0E00);
122 }
123}