diff --git a/src/addr.rs b/src/addr.rs index 58deebf..31563e6 100644 --- a/src/addr.rs +++ b/src/addr.rs @@ -1,8 +1,8 @@ #[cfg(feature = "std")] -use ::std::str::FromStr; +use std::{fmt, str::FromStr}; #[cfg(not(feature = "std"))] -use core::str::FromStr; +use core::{fmt, str::FromStr}; use crate::{parser, MacAddr6, MacAddr8, ParseError}; @@ -101,3 +101,12 @@ impl From<[u8; 8]> for MacAddr { MacAddr::V8(MacAddr8::from(bytes)) } } + +impl fmt::Display for MacAddr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + MacAddr::V6(v6) => fmt::Display::fmt(v6, f), + MacAddr::V8(v8) => fmt::Display::fmt(v8, f), + } + } +} diff --git a/src/addr6.rs b/src/addr6.rs index 2561162..fea1786 100644 --- a/src/addr6.rs +++ b/src/addr6.rs @@ -1,18 +1,15 @@ #[cfg(feature = "std")] -use ::std::str::FromStr; +use std::{fmt, str::FromStr}; #[cfg(not(feature = "std"))] -use core::str::FromStr; - -#[cfg(feature = "serde")] -use serde::{Deserialize, Serialize}; +use core::{fmt, str::FromStr}; use crate::parser; /// MAC address in *EUI-48* format. #[repr(C)] #[derive(Debug, Default, Hash, Eq, PartialEq, Ord, PartialOrd, Copy, Clone)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct MacAddr6([u8; 6]); impl MacAddr6 { @@ -200,24 +197,37 @@ impl AsMut<[u8]> for MacAddr6 { } } -#[cfg(feature = "std")] -mod std { - use std::fmt; - - use super::MacAddr6; - - impl fmt::Display for MacAddr6 { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +/// `MacAddr6` can be displayed in different formats. +/// +/// # Example +/// +/// ``` +/// # use macaddr::MacAddr6; +/// let addr = MacAddr6::new(0xab, 0x0d, 0xef, 0x12, 0x34, 0x56); +/// +/// assert_eq!(&format!("{}", addr), "AB:0D:EF:12:34:56"); +/// assert_eq!(&format!("{:-}", addr), "AB-0D-EF-12-34-56"); +/// assert_eq!(&format!("{:#}", addr), "AB0.DEF.123.456"); +/// ``` +impl fmt::Display for MacAddr6 { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if f.sign_minus() { + f.write_fmt(format_args!( + "{:02X}-{:02X}-{:02X}-{:02X}-{:02X}-{:02X}", + self.0[0], self.0[1], self.0[2], self.0[3], self.0[4], self.0[5], + )) + } else if f.alternate() { + let p1 = u16::from(self.0[0]) * 16 + u16::from(self.0[1] / 16); + let p2 = u16::from(self.0[1] % 16) * 256 + u16::from(self.0[2]); + let p3 = u16::from(self.0[3]) * 16 + u16::from(self.0[4] / 16); + let p4 = u16::from(self.0[4] % 16) * 256 + u16::from(self.0[5]); + + f.write_fmt(format_args!("{:03X}.{:03X}.{:03X}.{:03X}", p1, p2, p3, p4,)) + } else { f.write_fmt(format_args!( - // Canonical form - "{:02X}-{:02X}-{:02X}-{:02X}-{:02X}-{:02X}", - self.0[0], - self.0[1], - self.0[2], - self.0[3], - self.0[4], - self.0[5], - )) + "{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}", + self.0[0], self.0[1], self.0[2], self.0[3], self.0[4], self.0[5], + )) } } } diff --git a/src/addr8.rs b/src/addr8.rs index 29a0b01..ffcc60f 100644 --- a/src/addr8.rs +++ b/src/addr8.rs @@ -1,18 +1,15 @@ #[cfg(feature = "std")] -use ::std::str::FromStr; +use std::{fmt, str::FromStr}; #[cfg(not(feature = "std"))] -use core::str::FromStr; - -#[cfg(feature = "serde")] -use serde::{Deserialize, Serialize}; +use core::{fmt, str::FromStr}; use crate::parser; /// MAC address in *EUI-64* format. #[repr(C)] #[derive(Debug, Default, Hash, Eq, PartialEq, Ord, PartialOrd, Copy, Clone)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct MacAddr8([u8; 8]); impl MacAddr8 { @@ -200,26 +197,35 @@ impl AsMut<[u8]> for MacAddr8 { } } -#[cfg(feature = "std")] -mod std { - use std::fmt; - - use super::MacAddr8; - - impl fmt::Display for MacAddr8 { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +/// `MacAddr8` can be displayed in different formats. +/// +/// # Example +/// +/// ``` +/// # use macaddr::MacAddr8; +/// let addr = MacAddr8::new(0xab, 0x0d, 0xef, 0x12, 0x34, 0x56, 0x78, 0x9A); +/// +/// assert_eq!(&format!("{}", addr), "AB:0D:EF:12:34:56:78:9A"); +/// assert_eq!(&format!("{:-}", addr), "AB-0D-EF-12-34-56-78-9A"); +/// assert_eq!(&format!("{:#}", addr), "AB0D.EF12.3456.789A"); +/// ``` +impl fmt::Display for MacAddr8 { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if f.sign_minus() { + f.write_fmt(format_args!( + "{:02X}-{:02X}-{:02X}-{:02X}-{:02X}-{:02X}-{:02X}-{:02X}", + self.0[0], self.0[1], self.0[2], self.0[3], self.0[4], self.0[5], self.0[6], self.0[7], + )) + } else if f.alternate() { + f.write_fmt(format_args!( + "{:02X}{:02X}.{:02X}{:02X}.{:02X}{:02X}.{:02X}{:02X}", + self.0[0], self.0[1], self.0[2], self.0[3], self.0[4], self.0[5], self.0[6], self.0[7], + )) + } else { f.write_fmt(format_args!( - // Canonical form - "{:02X}-{:02X}-{:02X}-{:02X}-{:02X}-{:02X}-{:02X}-{:02X}", - self.0[0], - self.0[1], - self.0[2], - self.0[3], - self.0[4], - self.0[5], - self.0[6], - self.0[7], - )) + "{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}", + self.0[0], self.0[1], self.0[2], self.0[3], self.0[4], self.0[5], self.0[6], self.0[7], + )) } } } diff --git a/src/parser/mod.rs b/src/parser/mod.rs index e65521a..d7e81dc 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -1,7 +1,8 @@ #[cfg(feature = "std")] -use std::error::Error; -#[cfg(feature = "std")] -use std::fmt; +use std::{error::Error, fmt}; + +#[cfg(not(feature = "std"))] +use core::fmt; use crate::{MacAddr, MacAddr6, MacAddr8}; @@ -31,7 +32,6 @@ pub enum ParseError { InvalidCharacter(char, usize), } -#[cfg(feature = "std")] impl fmt::Display for ParseError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { diff --git a/src/parser/tests.rs b/src/parser/tests.rs index 4dbcc1b..dfea7a3 100644 --- a/src/parser/tests.rs +++ b/src/parser/tests.rs @@ -1,5 +1,9 @@ +#[cfg(feature = "std")] use std::str::FromStr; +#[cfg(not(feature = "std"))] +use core::str::FromStr; + use assert_matches::assert_matches; use crate::{MacAddr, MacAddr6, MacAddr8};