use std::{env, fs};
use regex::Regex;
+use thiserror::Error;
use crate::config::config_type::ConfigType;
#[allow(unreachable_pub)]
// Imports
imports_indent: IndentStyle, IndentStyle::Block, false, "Indent of imports";
imports_layout: ListTactic, ListTactic::Mixed, false, "Item layout inside a import block";
- merge_imports: bool, false, false, "Merge imports";
+ imports_granularity: ImportGranularity, ImportGranularity::Preserve, false,
+ "Merge or split imports to the provided granularity";
+ group_imports: GroupImportsTactic, GroupImportsTactic::Preserve, false,
+ "Controls the strategy for how imports are grouped together";
+ merge_imports: bool, false, false, "(deprecated: use imports_granularity instead)";
// Ordering
reorder_imports: bool, true, true, "Reorder import and extern crate statements alphabetically";
"Align enum variants discrims, if their diffs fit within threshold";
match_arm_blocks: bool, true, false, "Wrap the body of arms in blocks when it does not fit on \
the same line with the pattern of arms";
+ match_arm_leading_pipes: MatchArmLeadingPipe, MatchArmLeadingPipe::Never, true,
+ "Determines whether leading pipes are emitted on match arms";
force_multiline_blocks: bool, false, false,
"Force multiline closure bodies and match arms to be wrapped in a block";
- fn_args_density: Density, Density::Tall, false, "Argument density in functions";
+ fn_args_layout: Density, Density::Tall, true,
+ "Control the layout of arguments in a function";
brace_style: BraceStyle, BraceStyle::SameLineWhere, false, "Brace style for items";
control_brace_style: ControlBraceStyle, ControlBraceStyle::AlwaysSameLine, false,
"Brace style for control flow constructs";
emit_mode: EmitMode, EmitMode::Files, false,
"What emit Mode to use when none is supplied";
make_backup: bool, false, false, "Backup changed files";
+ print_misformatted_file_names: bool, false, true,
+ "Prints the names of mismatched files that were formatted. Prints the names of \
+ files that would be formated when used with `--check` mode. ";
}
+#[derive(Error, Debug)]
+#[error("Could not output config: {0}")]
+pub struct ToTomlError(toml::ser::Error);
+
impl PartialConfig {
- pub fn to_toml(&self) -> Result<String, String> {
+ pub fn to_toml(&self) -> Result<String, ToTomlError> {
// Non-user-facing options can't be specified in TOML
let mut cloned = self.clone();
cloned.file_lines = None;
cloned.verbose = None;
cloned.width_heuristics = None;
+ cloned.print_misformatted_file_names = None;
+ cloned.merge_imports = None;
- ::toml::to_string(&cloned).map_err(|e| format!("Could not output config: {}", e))
+ ::toml::to_string(&cloned).map_err(ToTomlError)
}
}
via the --file-lines option";
width_heuristics: WidthHeuristics, WidthHeuristics::scaled(100), false,
"'small' heuristic values";
+ // merge_imports deprecation
+ imports_granularity: ImportGranularity, ImportGranularity::Preserve, false,
+ "Merge imports";
+ merge_imports: bool, false, false, "(deprecated: use imports_granularity instead)";
// Options that are used by the tests
stable_option: bool, false, true, "A stable option";
assert_eq!(s.contains("(unstable)"), true);
}
+ #[test]
+ fn test_empty_string_license_template_path() {
+ let toml = r#"license_template_path = """#;
+ let config = Config::from_toml(toml, Path::new("")).unwrap();
+ assert!(config.license_template.is_none());
+ }
+
+ #[test]
+ fn test_valid_license_template_path() {
+ if !crate::is_nightly_channel!() {
+ return;
+ }
+ let toml = r#"license_template_path = "tests/license-template/lt.txt""#;
+ let config = Config::from_toml(toml, Path::new("")).unwrap();
+ assert!(config.license_template.is_some());
+ }
+
+ #[test]
+ fn test_override_existing_license_with_no_license() {
+ if !crate::is_nightly_channel!() {
+ return;
+ }
+ let toml = r#"license_template_path = "tests/license-template/lt.txt""#;
+ let mut config = Config::from_toml(toml, Path::new("")).unwrap();
+ assert!(config.license_template.is_some());
+ config.override_value("license_template_path", "");
+ assert!(config.license_template.is_none());
+ }
+
#[test]
fn test_dump_default_config() {
- const DEFAULT_CONFIG: &str = r#"max_width = 100
+ let default_config = format!(
+ r#"max_width = 100
hard_tabs = false
tab_spaces = 4
newline_style = "Auto"
where_single_line = false
imports_indent = "Block"
imports_layout = "Mixed"
-merge_imports = false
+imports_granularity = "Preserve"
+group_imports = "Preserve"
reorder_imports = true
reorder_modules = true
reorder_impl_items = false
struct_field_align_threshold = 0
enum_discrim_align_threshold = 0
match_arm_blocks = true
+match_arm_leading_pipes = "Never"
force_multiline_blocks = false
-fn_args_density = "Tall"
+fn_args_layout = "Tall"
brace_style = "SameLineWhere"
control_brace_style = "AlwaysSameLine"
trailing_semicolon = true
force_explicit_abi = true
condense_wildcard_suffixes = false
color = "Auto"
-required_version = "1.2.2"
+required_version = "{}"
unstable_features = false
disable_all_formatting = false
skip_children = false
ignore = []
emit_mode = "Files"
make_backup = false
-"#;
+"#,
+ env!("CARGO_PKG_VERSION")
+ );
let toml = Config::default().all_options().to_toml().unwrap();
- assert_eq!(&toml, DEFAULT_CONFIG);
+ assert_eq!(&toml, &default_config);
}
// FIXME(#2183): these tests cannot be run in parallel because they use env vars.
// assert_eq!(config.unstable_features(), true);
// ::std::env::set_var("CFG_RELEASE_CHANNEL", v);
// }
+
+ #[cfg(test)]
+ mod deprecated_option_merge_imports {
+ use super::*;
+
+ #[test]
+ fn test_old_option_set() {
+ if !crate::is_nightly_channel!() {
+ return;
+ }
+ let toml = r#"
+ unstable_features = true
+ merge_imports = true
+ "#;
+ let config = Config::from_toml(toml, Path::new("")).unwrap();
+ assert_eq!(config.imports_granularity(), ImportGranularity::Crate);
+ }
+
+ #[test]
+ fn test_both_set() {
+ if !crate::is_nightly_channel!() {
+ return;
+ }
+ let toml = r#"
+ unstable_features = true
+ merge_imports = true
+ imports_granularity = "Preserve"
+ "#;
+ let config = Config::from_toml(toml, Path::new("")).unwrap();
+ assert_eq!(config.imports_granularity(), ImportGranularity::Preserve);
+ }
+
+ #[test]
+ fn test_new_overridden() {
+ if !crate::is_nightly_channel!() {
+ return;
+ }
+ let toml = r#"
+ unstable_features = true
+ merge_imports = true
+ "#;
+ let mut config = Config::from_toml(toml, Path::new("")).unwrap();
+ config.override_value("imports_granularity", "Preserve");
+ assert_eq!(config.imports_granularity(), ImportGranularity::Preserve);
+ }
+
+ #[test]
+ fn test_old_overridden() {
+ if !crate::is_nightly_channel!() {
+ return;
+ }
+ let toml = r#"
+ unstable_features = true
+ imports_granularity = "Module"
+ "#;
+ let mut config = Config::from_toml(toml, Path::new("")).unwrap();
+ config.override_value("merge_imports", "true");
+ // no effect: the new option always takes precedence
+ assert_eq!(config.imports_granularity(), ImportGranularity::Module);
+ }
+ }
}