Skip to content

Commit

Permalink
use arrayvec for packets (#4)
Browse files Browse the repository at this point in the history
  • Loading branch information
LesnyRumcajs authored Jun 24, 2022
1 parent 0fc9f33 commit f3dc6b1
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 14 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "wakey"
version = "0.2.0"
version = "0.2.1"

authors = ["Hubert Bugaj<[email protected]>"]
edition = "2021"
Expand All @@ -14,4 +14,5 @@ categories = ["network-programming"]

[dependencies]
hex = "~0.3"
arrayvec = "0.7.2"
clap = { version = "3.1.18", features = ["derive"] }
74 changes: 61 additions & 13 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,20 @@
use std::iter;
use std::net::{SocketAddr, ToSocketAddrs, UdpSocket};

use arrayvec::ArrayVec;

const MAC_SIZE: usize = 6;
const MAC_PER_MAGIC: usize = 16;
static HEADER: [u8; 6] = [0xFF; 6];
const HEADER: [u8; 6] = [0xFF; 6];
const PACKET_LEN: usize = HEADER.len() + MAC_SIZE * MAC_PER_MAGIC;

type Packet = ArrayVec<u8, PACKET_LEN>;

/// Wake-on-LAN packet
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct WolPacket {
/// WOL packet bytes
packet: Vec<u8>,
packet: Packet,
}

impl WolPacket {
Expand Down Expand Up @@ -80,28 +86,39 @@ impl WolPacket {
/// Converts string representation of MAC address (e.x. 00:01:02:03:04:05) to raw bytes.
/// # Panic
/// Panics when input MAC is invalid (i.e. contains non-byte characters)
fn mac_to_byte(data: &str, sep: char) -> Vec<u8> {
data.split(sep)
fn mac_to_byte(data: &str, sep: char) -> ArrayVec<u8, MAC_SIZE> {
let bytes = data
.split(sep)
.flat_map(|x| hex::decode(x).expect("Invalid mac!"))
.collect()
.collect::<ArrayVec<u8, MAC_SIZE>>();

debug_assert_eq!(MAC_SIZE, bytes.len());

bytes
}

/// Extends the MAC address to fill the magic packet
fn extend_mac(mac: &[u8]) -> Vec<u8> {
iter::repeat(mac)
fn extend_mac(mac: &[u8]) -> ArrayVec<u8, { MAC_SIZE * MAC_PER_MAGIC }> {
let magic = iter::repeat(mac)
.take(MAC_PER_MAGIC)
.flatten()
.cloned()
.collect()
.copied()
.collect::<ArrayVec<u8, { MAC_SIZE * MAC_PER_MAGIC }>>();

debug_assert_eq!(MAC_SIZE * MAC_PER_MAGIC, magic.len());

magic
}

/// Creates bytes of the magic packet from MAC address
fn create_packet_bytes(mac: &[u8]) -> Vec<u8> {
let mut packet = Vec::with_capacity(HEADER.len() + MAC_SIZE * MAC_PER_MAGIC);
fn create_packet_bytes(mac: &[u8]) -> Packet {
let mut packet = Packet::new();

packet.extend(HEADER.iter());
packet.extend(HEADER);
packet.extend(WolPacket::extend_mac(mac));

debug_assert_eq!(PACKET_LEN, packet.len());

packet
}
}
Expand All @@ -121,12 +138,29 @@ mod tests {
);
}

#[test]
#[should_panic]
fn extend_mac_mac_too_long_test() {
let mac = vec![0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07];
super::WolPacket::extend_mac(&mac);
}

#[test]
#[should_panic]
fn extend_mac_mac_too_short_test() {
let mac = vec![0x01, 0x02, 0x03, 0x04, 0x05];
super::WolPacket::extend_mac(&mac);
}

#[test]
fn mac_to_byte_test() {
let mac = "01:02:03:04:05:06";
let result = super::WolPacket::mac_to_byte(mac, ':');

assert_eq!(result, vec![0x01, 0x02, 0x03, 0x04, 0x05, 0x06]);
assert_eq!(
result.into_inner().unwrap(),
[0x01, 0x02, 0x03, 0x04, 0x05, 0x06]
);
}

#[test]
Expand All @@ -143,6 +177,20 @@ mod tests {
super::WolPacket::mac_to_byte(mac, ':');
}

#[test]
#[should_panic]
fn mac_to_byte_mac_too_long_test() {
let mac = "01:02:03:04:05:06:07";
super::WolPacket::mac_to_byte(mac, ':');
}

#[test]
#[should_panic]
fn mac_to_byte_mac_too_short_test() {
let mac = "01:02:03:04:05";
super::WolPacket::mac_to_byte(mac, ':');
}

#[test]
fn create_packet_bytes_test() {
let bytes = super::WolPacket::create_packet_bytes(&[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]);
Expand Down

0 comments on commit f3dc6b1

Please sign in to comment.