summaryrefslogtreecommitdiff
path: root/src/util/path_list.rs
blob: 88f43b903a148ab0ae95660455348c1f04dfa6a8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
//! Null-separated path-list parsing helpers.

use std::{ffi::OsStr, os::unix::ffi::OsStrExt, path::Path};

/// Parses a NUL-separated path list into borrowed paths.
///
/// Empty segments are ignored. Returned paths borrow from `bytes`.
pub fn paths_from_null_separated_bytes(bytes: &[u8]) -> Vec<&Path> {
    bytes
        .split(|byte| *byte == 0)
        .filter(|segment| !segment.is_empty())
        .map(|segment| Path::new(OsStr::from_bytes(segment)))
        .collect()
}

#[cfg(test)]
mod tests {
    use std::path::Path;

    use super::paths_from_null_separated_bytes;

    #[test]
    fn paths_from_null_separated_bytes_returns_empty_list_for_empty_input() {
        let paths = paths_from_null_separated_bytes(b"");

        assert!(paths.is_empty());
    }

    #[test]
    fn paths_from_null_separated_bytes_ignores_empty_segments() {
        let paths = paths_from_null_separated_bytes(b"\0a.rs\0\0b.rs\0");

        assert_eq!(paths, vec![Path::new("a.rs"), Path::new("b.rs")]);
    }

    #[test]
    fn paths_from_null_separated_bytes_accepts_final_path_without_trailing_nul() {
        let paths = paths_from_null_separated_bytes(b"a.rs\0b.rs");

        assert_eq!(paths, vec![Path::new("a.rs"), Path::new("b.rs")]);
    }

    #[test]
    fn paths_from_null_separated_bytes_preserves_order() {
        let paths = paths_from_null_separated_bytes(b"b.rs\0a.rs\0c.rs\0");

        assert_eq!(
            paths,
            vec![Path::new("b.rs"), Path::new("a.rs"), Path::new("c.rs")]
        );
    }
}