aboutsummaryrefslogtreecommitdiffstats
path: root/src/projects/entry.rs
blob: 739ed8348cc391373bb19b3507b55d821d2a6ebe (plain)
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
use ignore::{DirEntry, Walk, WalkBuilder};
use serde::{Deserialize, Deserializer, Serialize};
use std::{convert::Infallible, path::PathBuf, str::FromStr};

#[derive(Debug, PartialEq, Eq, Clone, Default, Serialize)]
#[serde(default)]
pub struct SearchPath {
    pub path: PathBuf,
    pub hidden: bool,
    pub max_depth: Option<usize>,
}

impl SearchPath {
    pub fn filter(dir_entry: &DirEntry) -> bool {
        dir_entry.path().join(".git").exists()
    }
}

impl From<PathBuf> for SearchPath {
    fn from(path: PathBuf) -> Self {
        Self {
            path,
            ..Default::default()
        }
    }
}

impl From<SearchPath> for Walk {
    fn from(value: SearchPath) -> Self {
        WalkBuilder::new(value.path)
            .standard_filters(true)
            .max_depth(value.max_depth)
            .hidden(!value.hidden)
            .filter_entry(SearchPath::filter)
            .build()
    }
}

impl FromStr for SearchPath {
    type Err = Infallible;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        s.parse().map(PathBuf::into)
    }
}

impl<'de> Deserialize<'de> for SearchPath {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        #[derive(Deserialize)]
        #[serde(untagged)]
        enum Variants {
            String(String),
            Struct {
                path: PathBuf,
                hidden: bool,
                recurse: Option<usize>,
            },
        }

        match Variants::deserialize(deserializer)? {
            Variants::String(s) => s.parse().map_err(serde::de::Error::custom),
            Variants::Struct {
                path,
                hidden,
                recurse,
            } => Ok(Self {
                path,
                hidden,
                max_depth: recurse,
            }),
        }
    }
}