foundry_config/
fmt.rs

1//! Configuration specific to the `forge fmt` command and the `forge_fmt` package
2
3use serde::{Deserialize, Serialize};
4
5/// Contains the config and rule set
6#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
7pub struct FormatterConfig {
8    /// Maximum line length where formatter will try to wrap the line
9    pub line_length: usize,
10    /// Number of spaces per indentation level
11    pub tab_width: usize,
12    /// Print spaces between brackets
13    pub bracket_spacing: bool,
14    /// Style of uint/int256 types
15    pub int_types: IntTypes,
16    /// Style of multiline function header in case it doesn't fit
17    pub multiline_func_header: MultilineFuncHeaderStyle,
18    /// Style of quotation marks
19    pub quote_style: QuoteStyle,
20    /// Style of underscores in number literals
21    pub number_underscore: NumberUnderscore,
22    /// Style of underscores in hex literals
23    pub hex_underscore: HexUnderscore,
24    /// Style of single line blocks in statements
25    pub single_line_statement_blocks: SingleLineBlockStyle,
26    /// Print space in state variable, function and modifier `override` attribute
27    pub override_spacing: bool,
28    /// Wrap comments on `line_length` reached
29    pub wrap_comments: bool,
30    /// Globs to ignore
31    pub ignore: Vec<String>,
32    /// Add new line at start and end of contract declarations
33    pub contract_new_lines: bool,
34    /// Sort import statements alphabetically in groups (a group is separated by a newline).
35    pub sort_imports: bool,
36}
37
38/// Style of uint/int256 types
39#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
40#[serde(rename_all = "snake_case")]
41pub enum IntTypes {
42    /// Print the explicit uint256 or int256
43    Long,
44    /// Print the implicit uint or int
45    Short,
46    /// Use the type defined in the source code
47    Preserve,
48}
49
50/// Style of underscores in number literals
51#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
52#[serde(rename_all = "snake_case")]
53pub enum NumberUnderscore {
54    /// Use the underscores defined in the source code
55    Preserve,
56    /// Remove all underscores
57    #[default]
58    Remove,
59    /// Add an underscore every thousand, if greater than 9999
60    /// e.g. 1000 -> 1000 and 10000 -> 10_000
61    Thousands,
62}
63
64impl NumberUnderscore {
65    /// Returns true if the option is `Preserve`
66    #[inline]
67    pub fn is_preserve(self) -> bool {
68        matches!(self, Self::Preserve)
69    }
70
71    /// Returns true if the option is `Remove`
72    #[inline]
73    pub fn is_remove(self) -> bool {
74        matches!(self, Self::Remove)
75    }
76
77    /// Returns true if the option is `Remove`
78    #[inline]
79    pub fn is_thousands(self) -> bool {
80        matches!(self, Self::Thousands)
81    }
82}
83
84/// Style of underscores in hex literals
85#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
86#[serde(rename_all = "snake_case")]
87pub enum HexUnderscore {
88    /// Use the underscores defined in the source code
89    Preserve,
90    /// Remove all underscores
91    #[default]
92    Remove,
93    /// Add underscore as separator between byte boundaries
94    Bytes,
95}
96
97impl HexUnderscore {
98    /// Returns true if the option is `Preserve`
99    #[inline]
100    pub fn is_preserve(self) -> bool {
101        matches!(self, Self::Preserve)
102    }
103
104    /// Returns true if the option is `Remove`
105    #[inline]
106    pub fn is_remove(self) -> bool {
107        matches!(self, Self::Remove)
108    }
109
110    /// Returns true if the option is `Remove`
111    #[inline]
112    pub fn is_bytes(self) -> bool {
113        matches!(self, Self::Bytes)
114    }
115}
116
117/// Style of string quotes
118#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
119#[serde(rename_all = "snake_case")]
120pub enum QuoteStyle {
121    /// Use double quotes where possible
122    Double,
123    /// Use single quotes where possible
124    Single,
125    /// Use quotation mark defined in the source code
126    Preserve,
127}
128
129impl QuoteStyle {
130    /// Get associated quotation mark with option
131    pub fn quote(self) -> Option<char> {
132        match self {
133            Self::Double => Some('"'),
134            Self::Single => Some('\''),
135            Self::Preserve => None,
136        }
137    }
138}
139
140/// Style of single line blocks in statements
141#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
142#[serde(rename_all = "snake_case")]
143pub enum SingleLineBlockStyle {
144    /// Prefer single line block when possible
145    Single,
146    /// Always use multiline block
147    Multi,
148    /// Preserve the original style
149    Preserve,
150}
151
152/// Style of function header in case it doesn't fit
153#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
154#[serde(rename_all = "snake_case")]
155pub enum MultilineFuncHeaderStyle {
156    /// Write function parameters multiline first.
157    ParamsFirst,
158    /// Write function parameters multiline first when there is more than one param.
159    ParamsFirstMulti,
160    /// Write function attributes multiline first.
161    AttributesFirst,
162    /// If function params or attrs are multiline.
163    /// split the rest
164    All,
165    /// Same as `All` but writes function params multiline even when there is a single param.
166    AllParams,
167}
168
169impl Default for FormatterConfig {
170    fn default() -> Self {
171        Self {
172            line_length: 120,
173            tab_width: 4,
174            bracket_spacing: false,
175            int_types: IntTypes::Long,
176            multiline_func_header: MultilineFuncHeaderStyle::AttributesFirst,
177            quote_style: QuoteStyle::Double,
178            number_underscore: NumberUnderscore::Preserve,
179            hex_underscore: HexUnderscore::Remove,
180            single_line_statement_blocks: SingleLineBlockStyle::Preserve,
181            override_spacing: false,
182            wrap_comments: false,
183            ignore: vec![],
184            contract_new_lines: false,
185            sort_imports: false,
186        }
187    }
188}