Skip to main content

fancy_tree/tree/
builder.rs

1//! Provides tools for building a [`Tree`].
2use super::Tree;
3use super::charset::Charset;
4use crate::color::ColorChoice;
5use crate::config;
6use crate::git::Git;
7use std::path::Path;
8
9pub struct Builder<'git, 'charset, P: AsRef<Path>> {
10    /// The root path for the [`Tree`].
11    root: P,
12    /// The optional git state.
13    git: Option<&'git Git>,
14    color_choice: Option<ColorChoice>,
15    charset: Option<Charset<'charset>>,
16    max_level: Option<usize>,
17    /// Override the level limit that may be set by the configuration.
18    unset_level: bool,
19    config: Option<config::Main>,
20    icons: Option<config::Icons>,
21    colors: Option<config::Colors>,
22}
23
24impl<'git, 'charset, P> Builder<'git, 'charset, P>
25where
26    P: AsRef<Path>,
27{
28    /// Creates a new [`Builder`]
29    #[inline]
30    pub fn new(root: P) -> Self {
31        Self {
32            root,
33            git: None,
34            max_level: None,
35            unset_level: false,
36            charset: None,
37            color_choice: None,
38            config: None,
39            icons: None,
40            colors: None,
41        }
42    }
43
44    /// Adds a git state for the [`Tree`].
45    #[inline]
46    #[must_use]
47    pub fn git(self, git: &'git Git) -> Self {
48        Self {
49            git: Some(git),
50            ..self
51        }
52    }
53
54    /// Sets the maximum depth level for the [`Tree`].
55    #[inline]
56    #[must_use]
57    pub fn max_level(self, level: usize) -> Self {
58        Self {
59            max_level: Some(level),
60            ..self
61        }
62    }
63
64    /// Unsets the maximum depth level for the [`Tree`], returning to the default
65    /// behavior of searching infinitely deep.
66    ///
67    /// This helps override a maximum level that may have been set by the configuration.
68    #[inline]
69    #[must_use]
70    pub fn unset_level(self) -> Self {
71        Self {
72            unset_level: true,
73            ..self
74        }
75    }
76
77    /// Sets the [`Charset`] for the [`Tree`].
78    #[inline]
79    #[must_use]
80    pub fn charset(self, charset: Charset<'charset>) -> Self {
81        Self {
82            charset: Some(charset),
83            ..self
84        }
85    }
86
87    /// Sets [`ColorChoice`] override for the [`Tree`]. The color choice provided by the
88    /// main configuration is used if this isn't set.
89    #[inline]
90    #[must_use]
91    pub fn color_choice(self, color_choice: ColorChoice) -> Self {
92        Self {
93            color_choice: Some(color_choice),
94            ..self
95        }
96    }
97
98    /// Sets the configuration for the [`Tree`].
99    #[inline]
100    #[must_use]
101    pub fn config(self, config: config::Main) -> Self {
102        Self {
103            config: Some(config),
104            ..self
105        }
106    }
107
108    /// Sets the icon configuration for the [`Tree`].
109    #[inline]
110    #[must_use]
111    pub fn icons(self, icons: config::Icons) -> Self {
112        Self {
113            icons: Some(icons),
114            ..self
115        }
116    }
117
118    /// Sets the colors configuration for the [`Tree`].
119    #[inline]
120    #[must_use]
121    pub fn colors(self, colors: config::Colors) -> Self {
122        Self {
123            colors: Some(colors),
124            ..self
125        }
126    }
127
128    /// Creates the [`Tree`].
129    ///
130    /// # Panics
131    ///
132    /// - Panics if `max_level` and `unset_level` were both called.
133    pub fn build(self) -> Tree<'git, 'charset, P> {
134        assert!(
135            !(self.unset_level && self.max_level.is_some()),
136            "max_level cannot be set when unset_level is true"
137        );
138        let max_level = if self.unset_level {
139            None
140        } else {
141            self.max_level
142                .or(self.config.as_ref().and_then(|config| config.level()))
143        };
144        Tree {
145            root: self.root,
146            git: self.git,
147            max_level,
148            charset: self.charset.unwrap_or_default(),
149            color_choice: self.color_choice,
150            config: self.config.unwrap_or_default(),
151            icons: self.icons.unwrap_or_default(),
152            colors: self.colors.unwrap_or_default(),
153        }
154    }
155}
156
157#[cfg(test)]
158mod tests {
159    use super::*;
160
161    #[test]
162    #[should_panic]
163    fn test_cannot_build_unset_level_with_max_level() {
164        Builder::new(".").max_level(1).unset_level().build();
165    }
166}