capturing_glob/
entry.rs

1use std::str::from_utf8;
2use std::path::{Path, PathBuf};
3use std::ffi::OsStr;
4
5/// Entry that contains file path as well as all capture groups if any
6#[derive(Debug)]
7pub struct Entry {
8    path: PathBuf,
9    groups: Vec<(usize, usize)>,
10}
11
12impl Entry {
13    pub(crate) fn new(path: PathBuf) -> Entry {
14        Entry {
15            path,
16            groups: Vec::new(),
17        }
18    }
19    pub(crate) fn with_captures<P>(path: P, capt: Vec<(usize, usize)>)
20        -> Entry
21        where P: Into<PathBuf>,
22    {
23        Entry {
24            path: path.into(),
25            groups: capt,
26        }
27    }
28    /// Get path represented by this entry
29    pub fn path(&self) -> &Path {
30        &self.path
31    }
32    /// Get capture group number `n`
33    ///
34    /// The `n` is 1-based as in regexes (group 0 is the whole path)
35    #[cfg(windows)]
36    pub fn group(&self, n: usize) -> Option<&OsStr> {
37        self.group_windows(n)
38    }
39    #[cfg_attr(not(windows), allow(dead_code))]
40    fn group_windows(&self, n: usize) -> Option<&OsStr> {
41        if n == 0 {
42            return Some(self.path.as_os_str());
43        }
44        if let Some(&(a, b)) = self.groups.get(n-1) {
45            let bytes = self.path.to_str().unwrap().as_bytes();
46            Some(Path::new(from_utf8(&bytes[a..b]).unwrap()).as_os_str())
47        } else {
48            None
49        }
50    }
51    /// Get capture group number `n`
52    ///
53    /// The `n` is 1-based as in regexes (group 0 is the whole path)
54    #[cfg(unix)]
55    pub fn group(&self, n: usize) -> Option<&OsStr> {
56        use std::os::unix::ffi::OsStrExt;
57        if n == 0 {
58            return Some(self.path.as_os_str());
59        }
60        if let Some(&(a, b)) = self.groups.get(n-1) {
61            let bytes = self.path.as_os_str().as_bytes();
62            Some(OsStr::from_bytes(&bytes[a..b]))
63        } else {
64            None
65        }
66    }
67}
68
69impl Into<PathBuf> for Entry {
70    fn into(self) -> PathBuf {
71        self.path
72    }
73}
74
75impl AsRef<Path> for Entry {
76    fn as_ref(&self) -> &Path {
77        self.path.as_ref()
78    }
79}