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("")
+ };
+ ""
}