src/extname.rs in faster_path-0.3.7 vs src/extname.rs in faster_path-0.3.8

- old
+ new

@@ -1,63 +1,25 @@ -use path_parsing::SEP; use std::str; +use path_parsing::{SEP, find_last_non_sep_pos}; -struct ExtnameCoords { - word: bool, - pred: bool, - dot: bool, - start: usize, - end: usize, -} - -impl ExtnameCoords { - pub fn dec(&mut self) { - self.start -= 1; - if !self.word { - self.end -= 1; - } - } -} - -pub fn extname(pth: &str) -> &str { - let path = pth.as_bytes(); - let mut extname = ExtnameCoords { - word: false, - pred: false, - dot: false, - start: path.len(), - end: path.len(), +pub fn extname(path: &str) -> &str { + let end = match find_last_non_sep_pos(path.as_bytes()) { + Some(pos) => pos + 1, + _ => return "", }; - - for &item in path.iter().rev() { - if (item == b'.' && !extname.dot) || item == SEP { - if item == SEP && extname.word { - return "" + let bytes = &path.as_bytes()[..end]; + for (pos, c) in bytes.iter().enumerate().rev() { + match *c { + b'.' => { + let prev = bytes.get(pos - 1); + if pos == end - 1 || prev == None || prev == Some(&SEP) { + return ""; + } else { + return &path[pos..end] + }; } - - if !extname.pred { - extname.dec(); - } - - if extname.word { - extname.dot = true; - } - } else { - if extname.dot { - extname.pred = true; - break; - } else { - extname.word = true; - } - - if !extname.pred { - extname.dec() - } + SEP => return "", + _ => {} } - } - - if !extname.pred { - return ""; - } - - str::from_utf8(&path[extname.start..extname.end]).unwrap_or("") + }; + "" }