Refactoring configuration

This commit is contained in:
Scyptnex 2015-09-29 09:38:19 +10:00
parent 10eb21d020
commit 00b314618d
4 changed files with 164 additions and 166 deletions

View File

@ -85,13 +85,7 @@ fn print_usage<S: Into<String>>(reason: S) {
println!("{}\n\r usage: rustfmt [-h Help] [--write-mode=[replace|overwrite|display|diff]] \
<file_name>",
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<I>(args: I) -> Option<(Vec<String>, WriteMode)>

View File

@ -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 @@ impl Density {
}
}
#[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 @@ impl MultilineStyle {
}
}
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("<boolean>")
}
}
impl ConfigType for usize {
fn get_variant_names() -> String {
String::from("<unsigned integer>")
}
}
impl ConfigType for String {
fn get_variant_names() -> String {
String::from("<string>")
}
}
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 @@ macro_rules! create_config {
$(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("<boolean>")
}
}
impl ConfigType for usize {
fn get_variant_names() -> String {
String::from("<unsigned integer>")
}
}
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 @@ macro_rules! create_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 @@ macro_rules! create_config {
}
}
pub fn get_docs() -> Vec<ConfigHelpItem> {
let mut options: Vec<ConfigHelpItem> = 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";
}

View File

@ -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 @@ impl ReportTactic {
}
}
impl_enum_decodable!(ReportTactic, Always, Unnumbered, Never);
#[derive(Clone, Copy)]
enum Seeking {
Issue {

View File

@ -160,8 +160,7 @@ macro_rules! impl_enum_decodable {
$(
variants.push(stringify!($x));
)*
variants.join(", ")
format!("[{}]", variants.join("|"))
}
}
};