trybuild_internals_api/
expand.rs

1use crate::error::{Error, Result};
2use crate::manifest::Name;
3use crate::Test;
4use std::collections::BTreeMap as Map;
5use std::path::PathBuf;
6
7#[derive(Debug)]
8pub struct ExpandedTest {
9    pub name: Name,
10    pub test: Test,
11    pub error: Option<Error>,
12    is_from_glob: bool,
13}
14
15pub fn expand_globs(tests: &[Test]) -> Vec<ExpandedTest> {
16    let mut set = ExpandedTestSet::new();
17
18    for test in tests {
19        match test.path.to_str() {
20            Some(utf8) if utf8.contains('*') => match glob(utf8) {
21                Ok(paths) => {
22                    let expected = test.expected;
23                    for path in paths {
24                        set.insert(Test { path, expected }, None, true);
25                    }
26                }
27                Err(error) => set.insert(test.clone(), Some(error), false),
28            },
29            _ => set.insert(test.clone(), None, false),
30        }
31    }
32
33    set.vec
34}
35
36struct ExpandedTestSet {
37    vec: Vec<ExpandedTest>,
38    path_to_index: Map<PathBuf, usize>,
39}
40
41impl ExpandedTestSet {
42    fn new() -> Self {
43        ExpandedTestSet {
44            vec: Vec::new(),
45            path_to_index: Map::new(),
46        }
47    }
48
49    fn insert(&mut self, test: Test, error: Option<Error>, is_from_glob: bool) {
50        if let Some(&i) = self.path_to_index.get(&test.path) {
51            let prev = &mut self.vec[i];
52            if prev.is_from_glob {
53                prev.test.expected = test.expected;
54                return;
55            }
56        }
57
58        let index = self.vec.len();
59        let name = Name(format!("trybuild{:03}", index));
60        self.path_to_index.insert(test.path.clone(), index);
61        self.vec.push(ExpandedTest {
62            name,
63            test,
64            error,
65            is_from_glob,
66        });
67    }
68}
69
70fn glob(pattern: &str) -> Result<Vec<PathBuf>> {
71    let mut paths = glob::glob(pattern)?
72        .map(|entry| entry.map_err(Error::from))
73        .collect::<Result<Vec<PathBuf>>>()?;
74    paths.sort();
75    Ok(paths)
76}