|
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