Repository: starship/starship
File: src/context.rs (Rust)

Code before:
    folders: &'a [&'a str],
}

impl<'a> ScanAncestors<'a> {
    #[must_use]
    pub const fn set_files(mut self, files: &'a [&'a str]) -> Self {
        self.files = files;
        self
    }

    #[must_use]
    pub const fn set_folders(mut self, folders: &'a [&'a str]) -> Self {
        self.folders = folders;
        self
    }

    /// Scans upwards starting from the initial path until a directory containing one of the given
    /// files or folders is found.
    ///
    /// The scan does not cross device boundaries.
    pub fn scan(&self) -> Option<&'a Path> {
        let path = self.path;
        let initial_device_id = path.device_id();

        // We want to avoid reallocations during the search so we pre-allocate a buffer with enough
        // capacity to old the longest path + any marker (we could find the length of the longest
        // marker programmatically but that would actually cost more than preallocating 5 bytes too many).
        let mut buf = PathBuf::with_capacity(path.as_os_str().len() + 15);

        for dir in path.ancestors() {
            if initial_device_id != dir.device_id() {
                break;
            }
            // Then for each dir, we do `dir`, clearing in case `dir` is not an absolute path for
            // some reason
            buf.clear();
            buf.push(dir);

            for file in self.files {
                // Then for each file, we look for `dir/file`
                buf.push(file);

                if buf.is_file() {
                    return Some(dir);
                }

                // Removing the last pushed item means removing `file`, to replace it with either
                // the next `file` or the first `folder`, if any
                buf.pop();
            }


Review comment (suggestion):
```suggestion
        // capacity to hold the longest path + any marker (we could find the length of the longest
```

Code after:
    folders: &'a [&'a str],
}

impl<'a> ScanAncestors<'a> {
    #[must_use]
    pub const fn set_files(mut self, files: &'a [&'a str]) -> Self {
        self.files = files;
        self
    }

    #[must_use]
    pub const fn set_folders(mut self, folders: &'a [&'a str]) -> Self {
        self.folders = folders;
        self
    }

    /// Scans upwards starting from the initial path until a directory containing one of the given
    /// files or folders is found.
    ///
    /// The scan does not cross device boundaries.
    pub fn scan(&self) -> Option<PathBuf> {
        let path = self.path;
        let initial_device_id = path.device_id();

        // We want to avoid reallocations during the search so we pre-allocate a buffer with enough
        // capacity to hold the longest path + any marker (we could find the length of the longest
        // marker programmatically but that would actually cost more than preallocating a few bytes too many).
        let mut buf = PathBuf::with_capacity(path.as_os_str().len() + 15);
        path.clone_into(&mut buf);

        loop {
            if initial_device_id != buf.device_id() {
                break;
            }

            for file in self.files {
                // Then for each file, we look for `buf/file`
                buf.push(file);

                if buf.is_file() {
                    buf.pop();
                    return Some(buf);
                }

                // Removing the last pushed item means removing `file`, to replace it with either
                // the next `file` or the first `folder`, if any
                buf.pop();
            }

            for folder in self.folders {
                // Then for each folder, we look for `buf/folder`