1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
13 use lists::{SeparatorTactic, ListTactic};
15 macro_rules! configuration_option_enum{
16 ($e:ident: $( $x:ident ),+ $(,)*) => {
17 #[derive(Copy, Clone, Eq, PartialEq, Debug)]
22 impl_enum_decodable!($e, $( $x ),+);
26 configuration_option_enum! { NewlineStyle:
31 configuration_option_enum! { BraceStyle:
34 // Prefer same line except where there is a where clause, in which case force
35 // the brace to the next line.
39 // How to indent a function's return type.
40 configuration_option_enum! { ReturnIndent:
41 // Aligned with the arguments
43 // Aligned with the where clause
47 // How to stle a struct literal.
48 configuration_option_enum! { StructLitStyle:
49 // First line on the same line as the opening brace, all lines aligned with
52 // First line is on a new line and all lines align with block indent.
54 // FIXME Maybe we should also have an option to align types.
57 configuration_option_enum! { BlockIndentStyle:
58 // Same level as parent.
60 // One level deeper than parent.
62 // Aligned with block open.
66 configuration_option_enum! { Density:
67 // Fit as much on one line as possible.
71 // Try to compress if the body is empty.
76 pub fn to_list_tactic(self) -> ListTactic {
78 Density::Compressed => ListTactic::Mixed,
79 Density::Tall | Density::CompressedIfEmpty => ListTactic::HorizontalVertical,
84 configuration_option_enum! { LicensePolicy:
85 // Do not place license text at top of files
87 // Use the text in "license" field as the license
89 // Use a text file as the license text
93 configuration_option_enum! { MultilineStyle:
94 // Use horizontal layout if it fits in one line, fall back to vertical
96 // Use vertical layout
100 impl MultilineStyle {
101 pub fn to_list_tactic(self) -> ListTactic {
103 MultilineStyle::PreferSingle => ListTactic::HorizontalVertical,
104 MultilineStyle::ForceMulti => ListTactic::Vertical,
109 configuration_option_enum! { ReportTactic:
115 // This trait and the following impl blocks are there so that we an use
116 // UCFS inside the get_docs() function on types for configs.
117 pub trait ConfigType {
118 fn get_variant_names() -> String;
121 impl ConfigType for bool {
122 fn get_variant_names() -> String {
123 String::from("<boolean>")
127 impl ConfigType for usize {
128 fn get_variant_names() -> String {
129 String::from("<unsigned integer>")
133 impl ConfigType for String {
134 fn get_variant_names() -> String {
135 String::from("<string>")
139 pub struct ConfigHelpItem {
140 option_name: &'static str,
141 doc_string: &'static str,
142 variant_names: String,
143 default: &'static str,
146 impl ConfigHelpItem {
147 pub fn option_name(&self) -> &'static str {
151 pub fn doc_string(&self) -> &'static str {
155 pub fn variant_names(&self) -> &String {
159 pub fn default(&self) -> &'static str {
164 macro_rules! create_config {
165 ($($i:ident: $ty:ty, $def:expr, $( $dstring:expr ),+ );+ $(;)*) => (
166 #[derive(RustcDecodable, Clone)]
171 // Just like the Config struct but with each property wrapped
172 // as Option<T>. This is used to parse a rustfmt.toml that doesn't
173 // specity all properties of `Config`.
174 // We first parse into `ParsedConfig`, then create a default `Config`
175 // and overwrite the properties with corresponding values from `ParsedConfig`
176 #[derive(RustcDecodable, Clone)]
177 pub struct ParsedConfig {
178 $(pub $i: Option<$ty>),+
183 fn fill_from_parsed_config(mut self, parsed: ParsedConfig) -> Config {
185 if let Some(val) = parsed.$i {
192 pub fn from_toml(toml: &str) -> Config {
193 let parsed = toml.parse().unwrap();
194 let parsed_config:ParsedConfig = match toml::decode(parsed) {
195 Some(decoded) => decoded,
197 println!("Decoding config file failed. Config:\n{}", toml);
198 let parsed: toml::Value = toml.parse().unwrap();
199 println!("\n\nParsed:\n{:?}", parsed);
203 Config::default().fill_from_parsed_config(parsed_config)
206 pub fn override_value(&mut self, key: &str, val: &str) {
210 self.$i = val.parse::<$ty>().unwrap();
213 _ => panic!("Bad config key!")
217 pub fn print_docs() {
220 $( let max = cmp::max(max, stringify!($i).len()+1); )+
221 let mut space_str = String::with_capacity(max);
225 println!("\nConfiguration Options:");
227 let name_raw = stringify!($i);
228 let mut name_out = String::with_capacity(max);
229 for _ in name_raw.len()..max-1 {
232 name_out.push_str(name_raw);
234 println!("{}{} Default: {:?}",
236 <$ty>::get_variant_names(),
239 println!("{}{}", space_str, $dstring);
246 // Template for the default configuration
247 impl Default for Config {
248 fn default() -> Config {
260 max_width: usize, 100, "Maximum width of each line";
261 ideal_width: usize, 80, "Ideal width of each line";
262 tab_spaces: usize, 4, "Number of spaces per tab";
263 fn_call_width: usize, 55,
264 "Maximum width of the args of a function call before faling back to vertical formatting";
265 struct_lit_width: usize, 16,
266 "Maximum width in the body of a struct lit before faling back to vertical formatting";
267 newline_style: NewlineStyle, NewlineStyle::Unix, "Unix or Windows line endings";
268 fn_brace_style: BraceStyle, BraceStyle::SameLineWhere, "Brace style for functions";
269 fn_return_indent: ReturnIndent, ReturnIndent::WithArgs,
270 "Location of return type in function declaration";
271 fn_args_paren_newline: bool, true, "If function argument parenthases goes on a newline";
272 fn_args_density: Density, Density::Tall, "Argument density in functions";
273 fn_args_layout: StructLitStyle, StructLitStyle::Visual, "Layout of function arguments";
274 fn_arg_indent: BlockIndentStyle, BlockIndentStyle::Visual, "Indent on function arguments";
275 // Should we at least try to put the where clause on the same line as the rest of the
277 where_density: Density, Density::CompressedIfEmpty, "Density of a where clause";
278 // Visual will be treated like Tabbed
279 where_indent: BlockIndentStyle, BlockIndentStyle::Tabbed, "Indentation of a where clause";
280 where_layout: ListTactic, ListTactic::Vertical, "Element layout inside a where clause";
281 where_pred_indent: BlockIndentStyle, BlockIndentStyle::Visual,
282 "Indentation style of a where predicate";
283 generics_indent: BlockIndentStyle, BlockIndentStyle::Visual, "Indentation of generics";
284 struct_trailing_comma: SeparatorTactic, SeparatorTactic::Vertical,
285 "If there is a trailing comma on structs";
286 struct_lit_trailing_comma: SeparatorTactic, SeparatorTactic::Vertical,
287 "If there is a trailing comma on literal structs";
288 struct_lit_style: StructLitStyle, StructLitStyle::Block, "Style of struct definition";
289 struct_lit_multiline_style: MultilineStyle, MultilineStyle::PreferSingle,
290 "Multilline style on literal structs";
291 enum_trailing_comma: bool, true, "Put a trailing comma on enum declarations";
292 report_todo: ReportTactic, ReportTactic::Always,
293 "Report all occurences of TODO in source file comments";
294 report_fixme: ReportTactic, ReportTactic::Never,
295 "Report all occurences of FIXME in source file comments";
296 // Alphabetically, case sensitive.
297 reorder_imports: bool, false, "Reorder import statements alphabetically";
298 single_line_if_else: bool, false, "Put else on same line as closing brace for if statements";
299 format_strings: bool, true, "Format string literals, or leave as is";
300 chains_overflow_last: bool, true, "Allow last call in method chain to break the line";
301 take_source_hints: bool, true, "Retain some formatting characteristics from the source code";
302 hard_tabs: bool, false, "Use tab characters for indentation, spaces for alignment";