Refactoring configuration
This commit is contained in:
parent
10eb21d020
commit
00b314618d
@ -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)>
|
||||
|
307
src/config.rs
307
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 @@ 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";
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -160,8 +160,7 @@ macro_rules! impl_enum_decodable {
|
||||
$(
|
||||
variants.push(stringify!($x));
|
||||
)*
|
||||
|
||||
variants.join(", ")
|
||||
format!("[{}]", variants.join("|"))
|
||||
}
|
||||
}
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user