Skip to content

Commit

Permalink
Remove regex crate and do manual parsing
Browse files Browse the repository at this point in the history
This reduces the binary size from 1.4mb to 264kb.

Fixes abaumhauer#31
  • Loading branch information
oblique committed Oct 11, 2021
1 parent 7a72ad4 commit 7ac583d
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 22 deletions.
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ exclude = [
]

[dependencies]
regex = { version = "1.3.9", optional = false }
rustc-serialize = { version = "0.3.24", optional = true }
serde = { version = "1.0.114", optional = true }
serde_json = { version = "1.0.56", optional = true }
Expand Down
70 changes: 49 additions & 21 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
html_root_url = "https://doc.rust-lang.org/eui48/"
)]

extern crate regex;
#[cfg(feature = "rustc-serialize")]
extern crate rustc_serialize;
#[cfg(feature = "serde")]
Expand All @@ -29,7 +28,6 @@ use std::error::Error;
use std::fmt;
use std::str::FromStr;

use regex::Regex;
#[cfg(feature = "rustc-serialize")]
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
#[cfg(feature = "serde")]
Expand Down Expand Up @@ -71,6 +69,8 @@ pub enum ParseError {
InvalidLength(usize),
/// The input string is invalid, usize bytes were found, and we put up to 6 bytes into Eui48
InvalidByteCount(usize, Eui48),
/// Character not [0-9a-fA-F]|'x'|'-'|':'|'.'
InvalidCharacter(char),
}

impl MacAddress {
Expand Down Expand Up @@ -203,7 +203,6 @@ impl MacAddress {

/// Parses a String representation from any format supported
pub fn parse_str(s: &str) -> Result<MacAddress, ParseError> {
let re = Regex::new("(0x)?([0-9a-fA-F]{1,2})[:.-]?").unwrap();
let mut eui: Eui48 = [0; EUI48LEN];

match s.len() {
Expand All @@ -213,18 +212,48 @@ impl MacAddress {
}
}

let mut i = 0;
for caps in re.captures_iter(s) {
// Fill the array and keep counting for InvalidByteCount
if i < EUI48LEN {
let matched_byte = caps.get(2).unwrap().as_str();
eui[i] = u8::from_str_radix(matched_byte, 16).unwrap();
let mut offset = 0;

for s in s
.split(&[':', '.', '-'][..])
.map(|s| if s.starts_with("0x") { &s[2..] } else { s })
{
let mut hex = 0;
let mut i = 0;

for c in s.chars() {
match c {
'0'..='9' | 'a'..='f' | 'A'..='F' => {
if i % 2 == 1 {
hex <<= 4;
}

hex |= c.to_digit(16).unwrap() as u8;
}
c => return Err(ParseError::InvalidCharacter(c)),
}

if i % 2 == 1 {
if offset < EUI48LEN {
eui[offset] = hex;
}
offset += 1;
hex = 0;
}

i += 1;
}

if i % 2 == 1 {
if offset < EUI48LEN {
eui[offset] = hex;
}
offset += 1;
}
i += 1;
}

if i != EUI48LEN {
return Err(ParseError::InvalidByteCount(i, eui));
if offset != EUI48LEN {
return Err(ParseError::InvalidByteCount(offset, eui));
}

Ok(MacAddress::new(eui))
Expand Down Expand Up @@ -299,6 +328,9 @@ impl fmt::Display for ParseError {
found,
&eui[..found]
),
ParseError::InvalidCharacter(found) => {
write!(f, "Invalid character; found `{}`", found)
}
}
}
}
Expand Down Expand Up @@ -600,16 +632,12 @@ mod tests {
.to_canonical()
);
assert_eq!(
"00-00-00-00-00-00",
MacAddress::parse_str("!0x00000000000")
.unwrap()
.to_canonical()
MacAddress::parse_str("!0x00000000000"),
Err(InvalidCharacter('!'))
);
assert_eq!(
"00-00-00-00-00-00",
MacAddress::parse_str("0x00000000000!")
.unwrap()
.to_canonical()
MacAddress::parse_str("0x00000000000!"),
Err(InvalidCharacter('!'))
);
// Test error parsing
assert_eq!(MacAddress::parse_str(""), Err(InvalidLength(0)));
Expand Down Expand Up @@ -648,7 +676,7 @@ mod tests {
);
assert_eq!(
MacAddress::parse_str("0x0x0x0x0x0x0x"),
Err(InvalidByteCount(4, [0, 0, 0, 0, 0, 0]))
Err(InvalidCharacter('x'))
);
}

Expand Down

0 comments on commit 7ac583d

Please sign in to comment.