|
1 | 1 | //! Access to I/O ports |
2 | 2 |
|
| 3 | +use core::fmt; |
3 | 4 | use core::marker::PhantomData; |
4 | 5 |
|
5 | 6 | pub use crate::structures::port::{PortRead, PortWrite}; |
@@ -95,21 +96,18 @@ impl PortWrite for u32 { |
95 | 96 | } |
96 | 97 |
|
97 | 98 | /// A read only I/O port. |
98 | | -#[derive(Debug, Clone, PartialEq, Eq)] |
99 | 99 | pub struct PortReadOnly<T> { |
100 | 100 | port: u16, |
101 | 101 | phantom: PhantomData<T>, |
102 | 102 | } |
103 | 103 |
|
104 | 104 | /// A write only I/O port. |
105 | | -#[derive(Debug, Clone, PartialEq, Eq)] |
106 | 105 | pub struct PortWriteOnly<T> { |
107 | 106 | port: u16, |
108 | 107 | phantom: PhantomData<T>, |
109 | 108 | } |
110 | 109 |
|
111 | 110 | /// An I/O port. |
112 | | -#[derive(Debug, Clone, PartialEq, Eq)] |
113 | 111 | pub struct Port<T> { |
114 | 112 | port: u16, |
115 | 113 | phantom: PhantomData<T>, |
@@ -199,3 +197,36 @@ impl<T: PortWrite> Port<T> { |
199 | 197 | T::write_to_port(self.port, value) |
200 | 198 | } |
201 | 199 | } |
| 200 | + |
| 201 | +macro_rules! impl_port_util_traits { |
| 202 | + ($struct_name:ident) => { |
| 203 | + impl<T> fmt::Debug for $struct_name<T> { |
| 204 | + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 205 | + f.debug_struct(stringify!($struct_name)) |
| 206 | + .field("port", &self.port) |
| 207 | + .finish() |
| 208 | + } |
| 209 | + } |
| 210 | + |
| 211 | + impl<T> Clone for $struct_name<T> { |
| 212 | + fn clone(&self) -> Self { |
| 213 | + Self { |
| 214 | + port: self.port, |
| 215 | + phantom: PhantomData, |
| 216 | + } |
| 217 | + } |
| 218 | + } |
| 219 | + |
| 220 | + impl<T> PartialEq for $struct_name<T> { |
| 221 | + fn eq(&self, other: &Self) -> bool { |
| 222 | + self.port == other.port |
| 223 | + } |
| 224 | + } |
| 225 | + |
| 226 | + impl<T> Eq for $struct_name<T> {} |
| 227 | + }; |
| 228 | +} |
| 229 | + |
| 230 | +impl_port_util_traits!(Port); |
| 231 | +impl_port_util_traits!(PortReadOnly); |
| 232 | +impl_port_util_traits!(PortWriteOnly); |
0 commit comments