Skip to main content

wdl_format/config/
indent.rs

1//! Indentation within formatting configuration.
2
3use thiserror::Error;
4
5use crate::SPACE;
6use crate::TAB;
7
8/// Error while creating indentation configuration.
9#[derive(Error, Debug)]
10pub enum IndentError {
11    /// Invalid options
12    #[error("indentation with tabs cannot have a number of spaces")]
13    InvalidConfiguration,
14    /// Too many spaces
15    #[error("`{0}` is more than the maximum allowed number of spaces: `{max}`", max = MAX_SPACE_INDENT)]
16    TooManySpaces(usize),
17}
18
19/// The default number of spaces to represent one indentation level.
20const DEFAULT_SPACE_INDENT: usize = 4;
21/// The default indentation.
22pub const DEFAULT_INDENT: Indent = Indent::Spaces(DEFAULT_SPACE_INDENT);
23/// The maximum number of spaces to represent one indentation level.
24pub const MAX_SPACE_INDENT: usize = 16;
25
26/// An indentation level.
27#[derive(Clone, Copy, Debug)]
28pub enum Indent {
29    /// Tabs.
30    Tabs,
31    /// Spaces.
32    Spaces(usize),
33}
34
35impl Default for Indent {
36    fn default() -> Self {
37        DEFAULT_INDENT
38    }
39}
40
41impl Indent {
42    /// Attempts to create a new indentation level configuration.
43    pub fn try_new(tab: bool, num_spaces: Option<usize>) -> Result<Self, IndentError> {
44        match (tab, num_spaces) {
45            (true, None) => Ok(Indent::Tabs),
46            (true, Some(_)) => Err(IndentError::InvalidConfiguration),
47            (false, Some(n)) => {
48                if n > MAX_SPACE_INDENT {
49                    Err(IndentError::TooManySpaces(n))
50                } else {
51                    Ok(Indent::Spaces(n))
52                }
53            }
54            (false, None) => Ok(Indent::default()),
55        }
56    }
57
58    /// Gets the number of characters to indent.
59    pub fn num(&self) -> usize {
60        match self {
61            Indent::Tabs => 1,
62            Indent::Spaces(n) => *n,
63        }
64    }
65
66    /// Gets the character used for indentation.
67    pub fn character(&self) -> &str {
68        match self {
69            Indent::Tabs => TAB,
70            Indent::Spaces(_) => SPACE,
71        }
72    }
73
74    /// Gets the string representation of the indentation.
75    pub fn string(&self) -> String {
76        match self {
77            Indent::Tabs => self.character().to_string(),
78            Indent::Spaces(n) => self.character().repeat(*n),
79        }
80    }
81}