Skip to content

Commit

Permalink
feat: allow flexible mac addr string
Browse files Browse the repository at this point in the history
  • Loading branch information
fengyc committed Dec 6, 2024
1 parent c3cc12a commit 6f3c52b
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 20 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# CHANGELOG

## v1.1.0

1. Allow flexible mac addr strings

## v1.0.1

From @konanzheng
Expand Down
8 changes: 6 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "wol-rs"
version = "1.0.1"
version = "1.1.0"
edition = "2021"
authors = ["fengyingcai <fengyc.work@gmail.com>"]
description = "Wake-on-LAN utility"
Expand Down Expand Up @@ -29,6 +29,10 @@ bin = ["dep:clap"]

[dependencies]
clap = { version = "4.5.20", features = ["derive"], optional = true }
eui48 = { version = "1.1.0", features = ["disp_hexstring"] }

[profile.release]
strip = true
strip = true

[dev-dependencies]
rstest = "0.23.0"
50 changes: 33 additions & 17 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ use std::io;
use std::net::{IpAddr, UdpSocket};
use std::str::FromStr;

use eui48::MacAddress;

/// Mac address size of bytes
const MAC_ADDR_SIZE: usize = 6;

Expand All @@ -14,7 +16,7 @@ const WOL_PORT: u16 = 9;

/// Mac address.
///
/// A 6 bytes mac address, e.g. "00:0a:0b:0c:0d:0e".
/// A 6 bytes mac address, e.g. "00:0a:0b:0c:0d:0e" or "0:a:b:c:d:e".
#[derive(Debug, Default, Eq, PartialEq, Copy, Clone)]
pub struct MacAddr(pub [u8; MAC_ADDR_SIZE]);

Expand All @@ -40,26 +42,18 @@ impl Debug for MacAddrError {
}
}

impl From<MacAddress> for MacAddr {
fn from(value: MacAddress) -> Self {
Self(value.to_array())
}
}

impl FromStr for MacAddr {
type Err = MacAddrError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
if s.len() != 17 {
return Err(MacAddrError {});
}
let separator = s.chars().nth(2).unwrap();
let v: Vec<&str> = s.split(separator).collect();
if v.len() != MAC_ADDR_SIZE {
return Err(MacAddrError {});
}
let mut mac_addr = MacAddr([0; MAC_ADDR_SIZE]);
for i in 0..MAC_ADDR_SIZE {
match u8::from_str_radix(v[i], 16) {
Ok(n) => mac_addr.0[i] = n,
Err(_) => return Err(MacAddrError {}),
}
}
Ok(mac_addr)
let m = MacAddress::from_str(s).map_err(|_| MacAddrError {})?;
Ok(m.into())
}
}

Expand Down Expand Up @@ -102,3 +96,25 @@ pub fn send_wol(

Ok(())
}

#[cfg(test)]
mod tests {
use std::str::FromStr;

use rstest::rstest;

use crate::MacAddr;

#[rstest]
#[case("00:01:11:34:88:99", true)]
#[case("G0:01:11:34:88:99", true)]
#[case("00-01:11:34:88:99", true)]
#[case("00:1:11:34:88:99", true)]
#[case("00-01-11-34-88-99", true)]
#[case("00-1-11-34-88-99", true)]
#[case("0102.030A.0b0f", true)] // This case is from eui48
#[case("0x1234567890ab", true)] // This case if from eui48
fn test_mac_addr(#[case] s: &str, #[case] ok: bool) {
assert!(MacAddr::from_str(s).is_ok() == ok)
}
}
4 changes: 3 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ fn main() {
let mac_addr: MacAddr = args.mac_addr.parse().unwrap();
let bcast_addr: IpAddr = args.bcast_addr.parse().unwrap();
let bind_addr: IpAddr = args.bind_addr.parse().unwrap();
if (bind_addr.is_ipv4() && bcast_addr.is_ipv6()) || (bind_addr.is_ipv6() && bcast_addr.is_ipv4()) {
if (bind_addr.is_ipv4() && bcast_addr.is_ipv6())
|| (bind_addr.is_ipv6() && bcast_addr.is_ipv4())
{
panic!("The IP versions of bind_addr and bcast_addr do not match");
}
send_wol(mac_addr, Some(bcast_addr), Some(bind_addr)).unwrap();
Expand Down

0 comments on commit 6f3c52b

Please sign in to comment.