Skip to content

Commit

Permalink
Remove regex crate and do manual parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
oblique committed Oct 11, 2021
1 parent 7a72ad4 commit 467c778
Show file tree
Hide file tree
Showing 2 changed files with 47 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
68 changes: 47 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,46 @@ 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 s = if s.starts_with("0x") { &s[2..] } else { s };
let mut offset = 0;

for s in s.split(&[':', '.', '-'][..]) {
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 +326,9 @@ impl fmt::Display for ParseError {
found,
&eui[..found]
),
ParseError::InvalidCharacter(found) => {
write!(f, "Invalid character; found `{}`", found)
}
}
}
}
Expand Down Expand Up @@ -600,16 +630,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 +674,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 467c778

Please sign in to comment.