#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[non_exhaustive]
pub enum Speed {
_10M,
_100M,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[non_exhaustive]
pub enum Duplex {
Half,
Full,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct LinkState {
pub up: bool,
pub speed: Speed,
pub duplex: Duplex,
}
impl LinkState {
pub const fn down() -> Self {
Self {
up: false,
speed: Speed::_100M,
duplex: Duplex::Full,
}
}
pub const fn up(speed: Speed, duplex: Duplex) -> Self {
Self {
up: true,
speed,
duplex,
}
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct PhyCapabilities {
pub speed_100_fd: bool,
pub speed_100_hd: bool,
pub speed_10_fd: bool,
pub speed_10_hd: bool,
pub auto_negotiation: bool,
pub pause: bool,
}
#[cfg(test)]
mod tests {
extern crate alloc;
use super::*;
use alloc::format;
#[test]
fn link_state_up_constructor() {
let ls = LinkState::up(Speed::_100M, Duplex::Full);
assert!(ls.up);
assert_eq!(ls.speed, Speed::_100M);
assert_eq!(ls.duplex, Duplex::Full);
}
#[test]
fn link_state_down_constructor() {
let ls = LinkState::down();
assert!(!ls.up);
}
#[test]
fn link_state_equality() {
let a = LinkState::up(Speed::_10M, Duplex::Half);
let b = LinkState::up(Speed::_10M, Duplex::Half);
let c = LinkState::up(Speed::_100M, Duplex::Full);
assert_eq!(a, b);
assert_ne!(a, c);
assert_eq!(LinkState::down(), LinkState::down());
}
#[test]
fn link_state_all_up_combinations() {
let combos = [
LinkState::up(Speed::_10M, Duplex::Half),
LinkState::up(Speed::_10M, Duplex::Full),
LinkState::up(Speed::_100M, Duplex::Half),
LinkState::up(Speed::_100M, Duplex::Full),
];
for i in 0..combos.len() {
for j in (i + 1)..combos.len() {
assert_ne!(combos[i], combos[j], "combo {i} == combo {j}");
}
}
}
#[test]
fn phy_capabilities_default_all_false() {
let caps = PhyCapabilities::default();
assert!(!caps.speed_100_fd);
assert!(!caps.speed_100_hd);
assert!(!caps.speed_10_fd);
assert!(!caps.speed_10_hd);
assert!(!caps.auto_negotiation);
assert!(!caps.pause);
}
#[test]
fn phy_capabilities_equality() {
let a = PhyCapabilities {
speed_100_fd: true,
auto_negotiation: true,
..Default::default()
};
let b = PhyCapabilities {
speed_100_fd: true,
auto_negotiation: true,
..Default::default()
};
let c = PhyCapabilities::default();
assert_eq!(a, b);
assert_ne!(a, c);
}
#[test]
fn speed_clone_copy() {
let s = Speed::_100M;
let s2 = s;
let s3 = Clone::clone(&s);
assert_eq!(s, s2);
assert_eq!(s, s3);
}
#[test]
fn duplex_clone_copy() {
let d = Duplex::Full;
let d2 = d;
let d3 = Clone::clone(&d);
assert_eq!(d, d2);
assert_eq!(d, d3);
}
#[test]
fn link_state_debug() {
let ls = LinkState::up(Speed::_100M, Duplex::Full);
let dbg = format!("{:?}", ls);
assert!(dbg.contains("_100M"), "debug missing Speed: {dbg}");
assert!(dbg.contains("Full"), "debug missing Duplex: {dbg}");
assert!(dbg.contains("up: true"), "debug missing up flag: {dbg}");
}
}