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
use crate::file::{from_paths, resolve_includes};
use crate::parser::parse_from_path;
use crate::{parser, File};
use std::path::Path;

impl<'a> File<'a> {
    /// Constructs an empty `git-config` file.
    #[must_use]
    pub fn new() -> Self {
        Self::default()
    }

    /// Constructs a `git-config` file from the provided path.
    ///
    /// # Errors
    ///
    /// Returns an error if there was an IO error or if the file wasn't a valid
    /// git-config file.
    pub fn open<P: AsRef<Path>>(path: P) -> Result<Self, parser::ParserOrIoError<'static>> {
        parse_from_path(path).map(Self::from)
    }

    /// Constructs a `git-config` file from the provided paths in the order provided.
    /// This is neither zero-copy nor zero-alloc.
    ///
    /// # Errors
    ///
    /// Returns an error if there was an IO error or if a file wasn't a valid
    /// git-config file.
    ///
    /// [`git-config`'s documentation]: https://git-scm.com/docs/git-config#Documentation/git-config.txt-FILES
    pub fn from_paths(
        paths: impl IntoIterator<Item = impl AsRef<Path>>,
        options: from_paths::Options<'_>,
    ) -> Result<Self, from_paths::Error> {
        let mut target = Self::new();
        for path in paths {
            let path = path.as_ref();
            let mut config = Self::open(path)?;
            resolve_includes(&mut config, Some(path), options)?;
            target.append(config);
        }
        Ok(target)
    }
}