From 00b314618d1b2418c4c42041ae4ab11b067a9bef Mon Sep 17 00:00:00 2001 From: Scyptnex Date: Tue, 29 Sep 2015 09:38:19 +1000 Subject: [PATCH] Refactoring configuration --- src/bin/rustfmt.rs | 8 +- src/config.rs | 307 +++++++++++++++++++++++---------------------- src/issues.rs | 12 +- src/utils.rs | 3 +- 4 files changed, 164 insertions(+), 166 deletions(-) diff --git a/src/bin/rustfmt.rs b/src/bin/rustfmt.rs index af83cf13f85..01c292948df 100644 --- a/src/bin/rustfmt.rs +++ b/src/bin/rustfmt.rs @@ -85,13 +85,7 @@ fn print_usage>(reason: S) { println!("{}\n\r usage: rustfmt [-h Help] [--write-mode=[replace|overwrite|display|diff]] \ ", reason.into()); - - for option in Config::get_docs() { - println!("{}, {}, Possible values: {}", - option.option_name(), - option.doc_string(), - option.variant_names()); - } + Config::print_docs(); } fn determine_params(args: I) -> Option<(Vec, WriteMode)> diff --git a/src/config.rs b/src/config.rs index 7460f581205..3a73867f873 100644 --- a/src/config.rs +++ b/src/config.rs @@ -11,18 +11,24 @@ extern crate toml; use lists::{SeparatorTactic, ListTactic}; -pub use issues::ReportTactic; -#[derive(Copy, Clone, Eq, PartialEq, Debug)] -pub enum NewlineStyle { +macro_rules! configuration_option_enum{ + ($e:ident: $( $x:ident ),+ $(,)*) => { + #[derive(Copy, Clone, Eq, PartialEq, Debug)] + pub enum $e { + $( $x ),+ + } + + impl_enum_decodable!($e, $( $x ),+); + } +} + +configuration_option_enum! { NewlineStyle: Windows, // \r\n Unix, // \n } -impl_enum_decodable!(NewlineStyle, Windows, Unix); - -#[derive(Copy, Clone, Eq, PartialEq, Debug)] -pub enum BraceStyle { +configuration_option_enum! { BraceStyle: AlwaysNextLine, PreferSameLine, // Prefer same line except where there is a where clause, in which case force @@ -30,22 +36,16 @@ pub enum BraceStyle { SameLineWhere, } -impl_enum_decodable!(BraceStyle, AlwaysNextLine, PreferSameLine, SameLineWhere); - // How to indent a function's return type. -#[derive(Copy, Clone, Eq, PartialEq, Debug)] -pub enum ReturnIndent { +configuration_option_enum! { ReturnIndent: // Aligned with the arguments WithArgs, // Aligned with the where clause WithWhereClause, } -impl_enum_decodable!(ReturnIndent, WithArgs, WithWhereClause); - // How to stle a struct literal. -#[derive(Copy, Clone, Eq, PartialEq, Debug)] -pub enum StructLitStyle { +configuration_option_enum! { StructLitStyle: // First line on the same line as the opening brace, all lines aligned with // the first line. Visual, @@ -54,10 +54,7 @@ pub enum StructLitStyle { // FIXME Maybe we should also have an option to align types. } -impl_enum_decodable!(StructLitStyle, Visual, Block); - -#[derive(Copy, Clone, Eq, PartialEq, Debug)] -pub enum BlockIndentStyle { +configuration_option_enum! { BlockIndentStyle: // Same level as parent. Inherit, // One level deeper than parent. @@ -66,10 +63,7 @@ pub enum BlockIndentStyle { Visual, } -impl_enum_decodable!(BlockIndentStyle, Inherit, Tabbed, Visual); - -#[derive(Copy, Clone, Eq, PartialEq, Debug)] -pub enum Density { +configuration_option_enum! { Density: // Fit as much on one line as possible. Compressed, // Use more lines. @@ -78,8 +72,6 @@ pub enum Density { CompressedIfEmpty, } -impl_enum_decodable!(Density, Compressed, Tall); - impl Density { pub fn to_list_tactic(self) -> ListTactic { match self { @@ -89,17 +81,22 @@ pub fn to_list_tactic(self) -> ListTactic { } } -#[derive(Copy, Clone, Eq, PartialEq, Debug)] -pub enum MultilineStyle { +configuration_option_enum! { LicensePolicy: + // Do not place license text at top of files + NoLicense, + // Use the text in "license" field as the license + TextLicense, + // Use a text file as the license text + FileLicense, +} + +configuration_option_enum! { MultilineStyle: // Use horizontal layout if it fits in one line, fall back to vertical PreferSingle, // Use vertical layout ForceMulti, } - -impl_enum_decodable!(MultilineStyle, PreferSingle, ForceMulti); - impl MultilineStyle { pub fn to_list_tactic(self) -> ListTactic { match self { @@ -109,8 +106,63 @@ pub fn to_list_tactic(self) -> ListTactic { } } +configuration_option_enum! { ReportTactic: + Always, + Unnumbered, + Never, +} + +// This trait and the following impl blocks are there so that we an use +// UCFS inside the get_docs() function on types for configs. +pub trait ConfigType { + fn get_variant_names() -> String; +} + +impl ConfigType for bool { + fn get_variant_names() -> String { + String::from("") + } +} + +impl ConfigType for usize { + fn get_variant_names() -> String { + String::from("") + } +} + +impl ConfigType for String { + fn get_variant_names() -> String { + String::from("") + } +} + +pub struct ConfigHelpItem { + option_name: &'static str, + doc_string: &'static str, + variant_names: String, + default: &'static str, +} + +impl ConfigHelpItem { + pub fn option_name(&self) -> &'static str { + self.option_name + } + + pub fn doc_string(&self) -> &'static str { + self.doc_string + } + + pub fn variant_names(&self) -> &String { + &self.variant_names + } + + pub fn default(&self) -> &'static str { + self.default + } +} + macro_rules! create_config { - ($($i:ident: $ty:ty, $dstring: tt),+ $(,)*) => ( + ($($i:ident: $ty:ty, $def:expr, $( $dstring:expr ),+ );+ $(;)*) => ( #[derive(RustcDecodable, Clone)] pub struct Config { $(pub $i: $ty),+ @@ -126,47 +178,9 @@ pub struct ParsedConfig { $(pub $i: Option<$ty>),+ } - // This trait and the following impl blocks are there so that we an use - // UCFS inside the get_docs() function on types for configs. - pub trait ConfigType { - fn get_variant_names() -> String; - } - - impl ConfigType for bool { - fn get_variant_names() -> String { - String::from("") - } - } - - impl ConfigType for usize { - fn get_variant_names() -> String { - String::from("") - } - } - - pub struct ConfigHelpItem { - option_name: &'static str, - doc_string : &'static str, - variant_names: String, - } - - impl ConfigHelpItem { - pub fn option_name(&self) -> &'static str { - self.option_name - } - - pub fn doc_string(&self) -> &'static str { - self.doc_string - } - - pub fn variant_names(&self) -> &String { - &self.variant_names - } - } - impl Config { - fn fill_from_parsed_config(mut self, parsed: &ParsedConfig) -> Config { + fn fill_from_parsed_config(mut self, parsed: ParsedConfig) -> Config { $( if let Some(val) = parsed.$i { self.$i = val; @@ -186,7 +200,7 @@ pub fn from_toml(toml: &str) -> Config { panic!(); } }; - Config::default().fill_from_parsed_config(&parsed_config) + Config::default().fill_from_parsed_config(parsed_config) } pub fn override_value(&mut self, key: &str, val: &str) { @@ -200,93 +214,90 @@ pub fn override_value(&mut self, key: &str, val: &str) { } } - pub fn get_docs() -> Vec { - let mut options: Vec = Vec::new(); + pub fn print_docs() { + use std::cmp; + let max = 0; + $( let max = cmp::max(max, stringify!($i).len()+1); )+ + let mut space_str = String::with_capacity(max); + for _ in 0..max { + space_str.push(' '); + } + println!("\nConfiguration Options:"); $( - options.push(ConfigHelpItem { - option_name: stringify!($i), - doc_string: stringify!($dstring), - variant_names: <$ty>::get_variant_names(), - }); + let name_raw = stringify!($i); + let mut name_out = String::with_capacity(max); + for _ in name_raw.len()..max-1 { + name_out.push(' ') + } + name_out.push_str(name_raw); + name_out.push(' '); + println!("{}{} Default: {:?}", + name_out, + <$ty>::get_variant_names(), + $def); + $( + println!("{}{}", space_str, $dstring); + )+ + println!(""); )+ - options + } + } + + // Template for the default configuration + impl Default for Config { + fn default() -> Config { + Config { + $( + $i: $def, + )+ + } } } ) } create_config! { - max_width: usize, "Maximum width of each line", - ideal_width: usize, "Ideal width of each line (only used for comments)", - tab_spaces: usize, "Number of spaces per tab", - fn_call_width: usize, "Maximum width of the args of a function call\ - before faling back to vertical formatting", - struct_lit_width: usize, "Maximum width in the body of a struct lit\ - before faling back to vertical formatting", - newline_style: NewlineStyle, "Unix or Windows line endings", - fn_brace_style: BraceStyle, "Brace style for functions", - fn_return_indent: ReturnIndent, "Location of return type in function declaration", - fn_args_paren_newline: bool, "If function argument parenthases goes on a newline", - fn_args_density: Density, "Argument density in functions", - fn_args_layout: StructLitStyle, "Layout of function arguments", - fn_arg_indent: BlockIndentStyle, "Indent on function arguments", + max_width: usize, 100, "Maximum width of each line"; + ideal_width: usize, 80, "Ideal width of each line"; + tab_spaces: usize, 4, "Number of spaces per tab"; + fn_call_width: usize, 50, + "Maximum width of the args of a function call before faling back to vertical formatting"; + struct_lit_width: usize, 12, + "Maximum width in the body of a struct lit before faling back to vertical formatting"; + newline_style: NewlineStyle, NewlineStyle::Unix, "Unix or Windows line endings"; + fn_brace_style: BraceStyle, BraceStyle::SameLineWhere, "Brace style for functions"; + fn_return_indent: ReturnIndent, ReturnIndent::WithArgs, + "Location of return type in function declaration"; + fn_args_paren_newline: bool, true, "If function argument parenthases goes on a newline"; + fn_args_density: Density, Density::Tall, "Argument density in functions"; + fn_args_layout: StructLitStyle, StructLitStyle::Visual, "Layout of function arguments"; + fn_arg_indent: BlockIndentStyle, BlockIndentStyle::Visual, "Indent on function arguments"; // Should we at least try to put the where clause on the same line as the rest of the // function decl? - where_density: Density, "Density of a where clause", + where_density: Density, Density::CompressedIfEmpty, "Density of a where clause"; // Visual will be treated like Tabbed - where_indent: BlockIndentStyle, "Indentation of a where clause", - where_layout: ListTactic, "Element layout inside a where clause", - where_pred_indent: BlockIndentStyle, "Indentation style of a where predicate", - generics_indent: BlockIndentStyle, "Indentation of generics", - struct_trailing_comma: SeparatorTactic, "If there is a trailing comma on structs", - struct_lit_trailing_comma: SeparatorTactic, "If there is a trailing comma on literal structs", - struct_lit_style: StructLitStyle, "Style of struct definition", - struct_lit_multiline_style: MultilineStyle, "Multilline style on literal structs", - enum_trailing_comma: bool, "Put a trailing comma on enum declarations", - report_todo: ReportTactic, "Report all occurences of TODO in source file comments", - report_fixme: ReportTactic, "Report all occurences of FIXME in source file comments", + where_indent: BlockIndentStyle, BlockIndentStyle::Tabbed, "Indentation of a where clause"; + where_layout: ListTactic, ListTactic::Vertical, "Element layout inside a where clause"; + where_pred_indent: BlockIndentStyle, BlockIndentStyle::Visual, + "Indentation style of a where predicate"; + generics_indent: BlockIndentStyle, BlockIndentStyle::Visual, "Indentation of generics"; + struct_trailing_comma: SeparatorTactic, SeparatorTactic::Vertical, + "If there is a trailing comma on structs"; + struct_lit_trailing_comma: SeparatorTactic, SeparatorTactic::Vertical, + "If there is a trailing comma on literal structs"; + struct_lit_style: StructLitStyle, StructLitStyle::Block, "Style of struct definition"; + struct_lit_multiline_style: MultilineStyle, MultilineStyle::PreferSingle, + "Multilline style on literal structs"; + enum_trailing_comma: bool, true, "Put a trailing comma on enum declarations"; + report_todo: ReportTactic, ReportTactic::Always, + "Report all occurences of TODO in source file comments"; + report_fixme: ReportTactic, ReportTactic::Never, + "Report all occurences of FIXME in source file comments"; // Alphabetically, case sensitive. - reorder_imports: bool, "Reorder import statements alphabetically", - single_line_if_else: bool, "Put else on same line as closing brace for if statements", - format_strings: bool, "Format string literals, or leave as is", - chains_overflow_last: bool, "Allow last call in method chain to break the line", - take_source_hints: bool, "Retain some formatting characteristics from the source code", - hard_tabs: bool, "Use tab characters for indentation, spaces for alignment", -} - -impl Default for Config { - fn default() -> Config { - Config { - max_width: 100, - ideal_width: 80, - tab_spaces: 4, - fn_call_width: 50, - struct_lit_width: 12, - newline_style: NewlineStyle::Unix, - fn_brace_style: BraceStyle::SameLineWhere, - fn_return_indent: ReturnIndent::WithArgs, - fn_args_paren_newline: true, - fn_args_density: Density::Tall, - fn_args_layout: StructLitStyle::Visual, - fn_arg_indent: BlockIndentStyle::Visual, - where_density: Density::CompressedIfEmpty, - where_indent: BlockIndentStyle::Tabbed, - where_layout: ListTactic::Vertical, - where_pred_indent: BlockIndentStyle::Visual, - generics_indent: BlockIndentStyle::Visual, - struct_trailing_comma: SeparatorTactic::Vertical, - struct_lit_trailing_comma: SeparatorTactic::Vertical, - struct_lit_style: StructLitStyle::Block, - struct_lit_multiline_style: MultilineStyle::PreferSingle, - enum_trailing_comma: true, - report_todo: ReportTactic::Always, - report_fixme: ReportTactic::Never, - reorder_imports: false, - single_line_if_else: false, - format_strings: true, - chains_overflow_last: true, - take_source_hints: true, - hard_tabs: false, - } - } + reorder_imports: bool, false, "Reorder import statements alphabetically"; + single_line_if_else: bool, false, "Put else on same line as closing brace for if statements"; + format_strings: bool, true, "Format string literals, or leave as is"; + chains_overflow_last: bool, true, "Allow last call in method chain to break the line"; + take_source_hints: bool, true, "Retain some formatting characteristics from the source code"; + hard_tabs: bool, false, "Use tab characters for indentation, spaces for alignment"; } diff --git a/src/issues.rs b/src/issues.rs index 2a5eaae287a..6f64436bb52 100644 --- a/src/issues.rs +++ b/src/issues.rs @@ -13,17 +13,13 @@ // associated issue number. use std::fmt; +pub use config::ReportTactic; static TO_DO_CHARS: &'static [char] = &['T', 'O', 'D', 'O']; static FIX_ME_CHARS: &'static [char] = &['F', 'I', 'X', 'M', 'E']; -#[derive(Clone, Copy)] -pub enum ReportTactic { - Always, - Unnumbered, - Never, -} - +// Enabled implementation detail is here because it is +// irrelevant outside the issues module impl ReportTactic { fn is_enabled(&self) -> bool { match *self { @@ -34,8 +30,6 @@ fn is_enabled(&self) -> bool { } } -impl_enum_decodable!(ReportTactic, Always, Unnumbered, Never); - #[derive(Clone, Copy)] enum Seeking { Issue { diff --git a/src/utils.rs b/src/utils.rs index 171572ccfbf..b9da5b04c3b 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -160,8 +160,7 @@ fn get_variant_names() -> String { $( variants.push(stringify!($x)); )* - - variants.join(", ") + format!("[{}]", variants.join("|")) } } }; -- 2.44.0