/rust/registry/src/index.crates.io-1949cf8c6b5b557f/dotenvy-0.15.7/src/find.rs
Line | Count | Source |
1 | | use std::fs::File; |
2 | | use std::path::{Path, PathBuf}; |
3 | | use std::{env, fs, io}; |
4 | | |
5 | | use crate::errors::*; |
6 | | use crate::iter::Iter; |
7 | | |
8 | | pub struct Finder<'a> { |
9 | | filename: &'a Path, |
10 | | } |
11 | | |
12 | | impl<'a> Finder<'a> { |
13 | 3 | pub fn new() -> Self { |
14 | 3 | Finder { |
15 | 3 | filename: Path::new(".env"), |
16 | 3 | } |
17 | 3 | } |
18 | | |
19 | 0 | pub fn filename(mut self, filename: &'a Path) -> Self { |
20 | 0 | self.filename = filename; |
21 | 0 | self |
22 | 0 | } |
23 | | |
24 | 3 | pub fn find(self) -> Result<(PathBuf, Iter<File>)> { |
25 | 3 | let path = find(&env::current_dir().map_err(Error::Io)?, self.filename)?; |
26 | 0 | let file = File::open(&path).map_err(Error::Io)?; |
27 | 0 | let iter = Iter::new(file); |
28 | 0 | Ok((path, iter)) |
29 | 3 | } |
30 | | } |
31 | | |
32 | | /// Searches for `filename` in `directory` and parent directories until found or root is reached. |
33 | 12 | pub fn find(directory: &Path, filename: &Path) -> Result<PathBuf> { |
34 | 12 | let candidate = directory.join(filename); |
35 | | |
36 | 12 | match fs::metadata(&candidate) { |
37 | 0 | Ok(metadata) => { |
38 | 0 | if metadata.is_file() { |
39 | 0 | return Ok(candidate); |
40 | 0 | } |
41 | | } |
42 | 12 | Err(error) => { |
43 | 12 | if error.kind() != io::ErrorKind::NotFound { |
44 | 0 | return Err(Error::Io(error)); |
45 | 12 | } |
46 | | } |
47 | | } |
48 | | |
49 | 12 | if let Some(parent) = directory.parent() { |
50 | 9 | find(parent, filename) |
51 | | } else { |
52 | 3 | Err(Error::Io(io::Error::new( |
53 | 3 | io::ErrorKind::NotFound, |
54 | 3 | "path not found", |
55 | 3 | ))) |
56 | | } |
57 | 12 | } |