summaryrefslogtreecommitdiffstats
path: root/src/search/entry/config.rs
blob: d325b5856bde51b2073741a5835be8ca386b938d (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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
use ignore::WalkBuilder;
use serde::{Deserialize, Deserializer, Serialize};
use std::{convert::Infallible, path::PathBuf, str::FromStr};

use super::Entry;

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

impl From<Config> for Entry {
    fn from(config: Config) -> Self {
        let iter = WalkBuilder::new(&config.path_buf)
            .standard_filters(true)
            .max_depth(config.max_depth)
            .hidden(!config.hidden)
            .build();
        Self { iter, config }
    }
}

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

impl Config {
    pub fn new(path_buf: PathBuf) -> Self {
        Self {
            path_buf,
            ..Default::default()
        }
    }
}

impl FromStr for Config {
    type Err = Infallible;

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

// Custom deserialize impl to accept either string or struct
impl<'de> Deserialize<'de> for Config {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        #[derive(Deserialize)]
        #[serde(untagged)]
        enum Variants {
            String(String),
            Struct {
                path_buf: PathBuf,
                hidden: bool,
                max_depth: Option<usize>,
                git: bool,
                pattern: Option<String>,
            },
        }

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