]> git.lizzy.rs Git - rust.git/blobdiff - src/config.rs
Refactoring configuration
[rust.git] / src / config.rs
index 7460f5812055610d3562eabea60e7d59de51c78d..3a73867f873bbf785103bbdc15a1fd2076a52d3d 100644 (file)
 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("<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 @@ 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("<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 @@ 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<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";
 }