config file: 🔨 uniq file and serde yaml parsing

This commit is contained in:
zwPapEr 2020-10-31 18:20:59 +08:00 committed by Abin Simon
parent 0e8ae256b5
commit e4d8d85678
20 changed files with 374 additions and 578 deletions

75
Cargo.lock generated
View file

@ -206,6 +206,12 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
[[package]]
name = "dtoa"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b"
[[package]] [[package]]
name = "float-cmp" name = "float-cmp"
version = "0.8.0" version = "0.8.0"
@ -345,6 +351,8 @@ dependencies = [
"libc", "libc",
"lscolors", "lscolors",
"predicates", "predicates",
"serde",
"serde_yaml",
"tempfile", "tempfile",
"term_grid", "term_grid",
"terminal_size", "terminal_size",
@ -424,6 +432,24 @@ dependencies = [
"treeline", "treeline",
] ]
[[package]]
name = "proc-macro2"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
dependencies = [
"proc-macro2",
]
[[package]] [[package]]
name = "rand" name = "rand"
version = "0.7.3" version = "0.7.3"
@ -530,12 +556,55 @@ dependencies = [
"winapi-util", "winapi-util",
] ]
[[package]]
name = "serde"
version = "1.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_yaml"
version = "0.8.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae3e2dd40a7cdc18ca80db804b7f461a39bb721160a85c9a1fa30134bf3c02a5"
dependencies = [
"dtoa",
"linked-hash-map",
"serde",
"yaml-rust",
]
[[package]] [[package]]
name = "strsim" name = "strsim"
version = "0.8.0" version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "syn"
version = "1.0.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc371affeffc477f42a221a1e4297aedcea33d47d19b61455588bd9d8f6b19ac"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]] [[package]]
name = "tempfile" name = "tempfile"
version = "3.1.0" version = "3.1.0"
@ -621,6 +690,12 @@ version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
[[package]]
name = "unicode-xid"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]] [[package]]
name = "users" name = "users"
version = "0.11.0" version = "0.11.0"

View file

@ -35,6 +35,8 @@ wild = "2.0.*"
globset = "0.4.*" globset = "0.4.*"
xdg = "2.1.*" xdg = "2.1.*"
yaml-rust = "0.4.*" yaml-rust = "0.4.*"
serde = { version = "1.0", features = ["derive"] }
serde_yaml = "0.8"
[target.'cfg(unix)'.dependencies] [target.'cfg(unix)'.dependencies]
users = "0.11.*" users = "0.11.*"

View file

@ -1,181 +1,171 @@
use serde::Deserialize;
use serde_yaml::Sequence;
use std::error::Error;
///! This module provides methods to handle the program's config files and operations related to ///! This module provides methods to handle the program's config files and operations related to
///! this. ///! this.
use std::fs::File; use std::fs;
use std::io::prelude::*; use std::io::BufReader;
use std::path::PathBuf; use std::path::PathBuf;
use xdg::BaseDirectories;
use crate::print_error; use crate::print_error;
#[cfg(not(windows))]
use xdg::BaseDirectories;
use yaml_rust::{Yaml, YamlLoader};
const CONF_DIR: &str = "lsd"; const CONF_DIR: &str = "lsd";
const CONF_FILE_NAME: &str = "config"; const CONF_FILE_NAME: &str = "config";
const YAML_LONG_EXT: &str = "yaml"; const YAML_LONG_EXT: &str = "yaml";
const YAML_SHORT_EXT: &str = "yml";
/// A struct to hold an optional file path [String] and an optional [Yaml], and provides methods /// A struct to hold an optional file path [String] and an optional [Yaml], and provides methods
/// around error handling in a config file. /// around error handling in a config file.
#[derive(Clone, Debug)] #[derive(Debug, Deserialize)]
pub struct Config { pub struct Config {
pub file: Option<String>, pub classic: Option<bool>,
pub yaml: Option<Yaml>, pub blocks: Option<Sequence>,
pub color: Option<Color>,
pub date: Option<String>, // enum?
pub dereference: Option<bool>,
pub display: Option<String>, // enum?
pub icons: Option<Icons>,
pub ignore_globs: Option<Sequence>,
pub indicators: Option<bool>,
pub layout: Option<String>, // enum?
pub recursion: Option<Recursion>,
pub size: Option<String>, // enum?
pub sorting: Option<Sorting>,
pub no_symlink: Option<bool>,
pub total_size: Option<bool>,
pub styling: Option<Styling>,
}
#[derive(Debug, Deserialize)]
pub struct Color {
pub when: String, // enum?
}
#[derive(Debug, Deserialize)]
pub struct Icons {
pub when: String, // enum?
pub theme: String,
}
#[derive(Debug, Deserialize)]
pub struct Recursion {
pub enabled: bool,
pub depth: i32,
}
#[derive(Debug, Deserialize)]
pub struct Sorting {
pub column: String, // enum?
pub reverse: bool,
pub dir_grouping: String, // enum?
}
#[derive(Debug, Deserialize)]
pub struct Styling {
pub symlink_arrow: bool,
} }
impl Config { impl Config {
/// This constructs a Config struct without a file [String] and without a [Yaml]. /// This constructs a Config struct without a file [String] and without a [Yaml].
pub fn with_none() -> Self { pub fn with_none() -> Self {
Self { Self::default()
file: None,
yaml: None,
}
} }
/// This constructs a Config struct with a passed file [String] and without a [Yaml]. /// This constructs a Config struct with a passed file [String] and without a [Yaml].
pub fn with_file(file: String) -> Self { // TODO(zhangwei) Box<Error>
Self { pub fn with_file(file: String) -> Option<Self> {
file: Some(file), match fs::read(&file) {
yaml: None, Ok(f) => Self::with_yaml(&String::from_utf8_lossy(&f)),
Err(e) => {
match e.kind() {
std::io::ErrorKind::NotFound => {}
_ => print_error!("bad config file: {}, {}\n", &file, e),
};
None
}
} }
} }
/// This constructs a Config struct with a passed [Yaml] and without a file [String]. /// This constructs a Config struct with a passed [Yaml] and without a file [String].
#[cfg(test)] fn with_yaml(yaml: &str) -> Option<Self> {
pub fn with_yaml(yaml: Yaml) -> Self { match serde_yaml::from_str(yaml) {
Self { Ok(c) => Some(c),
file: None, Err(e) => {
yaml: Some(yaml), print_error!("configuration file format error, {}\n\n", e);
} None
}
/// This tries to read a configuration file like in the XDG_BASE_DIRS specification and returns
/// the contents of the YAML config file.
pub fn read_config(name: &str) -> Self {
let config_file_long_path;
let config_file_short_path;
match Self::config_file_paths(name) {
Some((long, short)) => {
config_file_long_path = long;
config_file_short_path = short;
}
_ => return Self::with_none(),
}
let mut out_config;
let mut config_file;
match File::open(&config_file_long_path) {
Ok(result) => {
config_file = result;
out_config = Self::with_file(config_file_long_path.as_path().display().to_string());
}
Err(_) => match File::open(&config_file_short_path) {
Ok(result) => {
config_file = result;
out_config =
Self::with_file(config_file_short_path.as_path().display().to_string());
}
Err(_) => return Self::with_none(),
},
}
let mut config_content = String::new();
if let Err(error) = config_file.read_to_string(&mut config_content) {
print_error!("Found a config file, but could not read it: {}", error);
return out_config;
}
match YamlLoader::load_from_str(&config_content) {
Ok(result) => {
if !result.is_empty() {
out_config.yaml = Some(result[0].clone());
}
out_config
}
Err(error) => {
print_error!("Error parsing config: {}\n", error);
out_config
} }
} }
} }
/// This provides two paths for a configuration file (the first with the long yaml extension, /// This provides the path for a configuration file, according to the XDG_BASE_DIRS specification.
/// the second with the short yml extension), according to the XDG_BASE_DIRS specification. /// not checking the error because this is static
#[cfg(not(windows))] #[cfg(not(windows))]
pub fn config_file_paths(name: &str) -> Option<(PathBuf, PathBuf)> { fn config_file_path() -> PathBuf {
let base_dirs; BaseDirectories::with_prefix(CONF_DIR)
match BaseDirectories::with_prefix(CONF_DIR) { .unwrap()
Ok(result) => base_dirs = result, .place_config_file([CONF_FILE_NAME, YAML_LONG_EXT].join("."))
_ => return None, .unwrap()
}
let config_file_long_path;
match base_dirs.place_config_file([name, YAML_LONG_EXT].join(".")) {
Ok(result) => config_file_long_path = result,
_ => return None,
}
let config_file_short_path;
match base_dirs.place_config_file([name, YAML_SHORT_EXT].join(".")) {
Ok(result) => config_file_short_path = result,
_ => return None,
}
Some((config_file_long_path, config_file_short_path))
} }
/// This provides two paths for a configuration file (the first with the long yaml extension, /// This provides the path for a configuration file, inside the %APPDATA% directory.
/// the second with the short yml extension) inside the %APPDATA% directory. /// not checking the error because this is static
#[cfg(windows)] #[cfg(windows)]
pub fn config_file_paths(name: &str) -> Option<(PathBuf, PathBuf)> { fn config_file_path() -> PathBuf {
let mut config_file_long_path; dirs::config_dir()
match dirs::config_dir() { .unwrap()
Some(path) => config_file_long_path = path, .join(CONF_DIR)
_ => return None, .join(CONF_FILE_NAME)
} .set_extension(YAML_LONG_EXT)
config_file_long_path.push(CONF_DIR);
let mut config_file_short_path = config_file_long_path.clone();
config_file_long_path.push([name, YAML_LONG_EXT].join("."));
config_file_short_path.push([name, YAML_SHORT_EXT].join("."));
Some((config_file_long_path, config_file_short_path))
}
/// Returns whether the Config has a [Yaml].
pub fn has_yaml(&self) -> bool {
self.yaml.is_some()
}
/// This prints the provided warning message to stderr, prepending the executable name and the
/// configuration file path that likely caused the warning.
pub fn print_warning(&self, message: &str) {
print_error!(
"lsd: {} - {}\n",
self.file.as_ref().unwrap_or(&String::from("")),
message
);
}
/// This prints a predetermined warning message to stderr, warning about an invalid value for a
/// configuration element.
pub fn print_invalid_value_warning(&self, name: &str, value: &str) {
self.print_warning(&format!("Not a valid {} value: {}", name, value));
}
/// This prints a predetermined warning message to stderr, warning about a wrong [Yaml] data
/// type for a configuration value.
pub fn print_wrong_type_warning(&self, name: &str, type_name: &str) {
self.print_warning(&format!(
"The {} config value has to be a {}.",
name, type_name
));
} }
} }
impl Default for Config { impl Default for Config {
fn default() -> Self { fn default() -> Self {
Self::read_config(CONF_FILE_NAME) if let Some(c) = Self::with_file(Self::config_file_path().to_string_lossy().to_string()) {
c
} else {
Config {
classic: Some(false),
blocks: None,
color: None,
date: None,
dereference: None,
display: None,
icons: None,
ignore_globs: None,
indicators: None,
layout: None,
recursion: None,
size: None,
sorting: None,
no_symlink: None,
total_size: None,
styling: None,
}
}
}
}
#[cfg(test)]
mod tests {
use super::Config;
#[test]
fn test_read_config_ok() {
let c = Config::with_yaml("classic: true").unwrap();
println!("{:?}", c);
assert!(c.classic.unwrap())
}
#[test]
fn test_read_config_bad_bool() {
let c = Config::with_yaml("classic: notbool");
println!("{:?}", c);
assert!(c.is_some())
}
#[test]
fn test_read_config_file_not_found() {
let c = Config::with_file("not-existed".to_string());
assert!(c.is_none())
} }
} }

View file

@ -6,7 +6,6 @@ use std::convert::TryFrom;
use crate::config_file::Config; use crate::config_file::Config;
use clap::{ArgMatches, Error, ErrorKind}; use clap::{ArgMatches, Error, ErrorKind};
use yaml_rust::Yaml;
/// A struct to hold a [Vec] of [Block]s and to provide methods to create it. /// A struct to hold a [Vec] of [Block]s and to provide methods to create it.
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
@ -41,7 +40,7 @@ impl Blocks {
}; };
if matches.is_present("long") { if matches.is_present("long") {
if config.has_yaml() { if !matches.is_present("ignore-config") {
if let Some(value) = Self::from_config(config) { if let Some(value) = Self::from_config(config) {
result = Ok(value); result = Ok(value);
} }
@ -101,15 +100,8 @@ impl Blocks {
/// of its [String](Yaml::String) values is returned in a `Blocks` in a [Some]. Otherwise it /// of its [String](Yaml::String) values is returned in a `Blocks` in a [Some]. Otherwise it
/// returns [None]. /// returns [None].
fn from_config(config: &Config) -> Option<Self> { fn from_config(config: &Config) -> Option<Self> {
if let Some(yaml) = &config.yaml { if let Some(c) = &config.blocks {
match &yaml["blocks"] { None
Yaml::BadValue => None,
Yaml::Array(values) => Self::from_yaml_array(values, config),
_ => {
config.print_wrong_type_warning("blocks", "array");
None
}
}
} else { } else {
None None
} }
@ -117,23 +109,23 @@ impl Blocks {
/// Get a [Blocks] from a [Yaml] array. The [Config] is used to log warnings about wrong values /// Get a [Blocks] from a [Yaml] array. The [Config] is used to log warnings about wrong values
/// in a Yaml. /// in a Yaml.
fn from_yaml_array(values: &[Yaml], config: &Config) -> Option<Self> { // fn from_yaml_array(values: &[Yaml], config: &Config) -> Option<Self> {
let mut blocks: Vec<Block> = vec![]; // let mut blocks: Vec<Block> = vec![];
for array_el in values.iter() { // for array_el in values.iter() {
match array_el { // match array_el {
Yaml::String(value) => match Block::try_from(value.as_str()) { // Yaml::String(value) => match Block::try_from(value.as_str()) {
Ok(block) => blocks.push(block), // Ok(block) => blocks.push(block),
Err(err) => config.print_warning(&err), // Err(err) => config.print_warning(&err),
}, // },
_ => config.print_warning("The blocks config values have to be strings."), // _ => config.print_warning("The blocks config values have to be strings."),
} // }
} // }
if blocks.is_empty() { // if blocks.is_empty() {
None // None
} else { // } else {
Some(Self(blocks)) // Some(Self(blocks))
} // }
} // }
/// This returns a Blocks struct for the long format. /// This returns a Blocks struct for the long format.
/// ///
@ -424,7 +416,7 @@ mod test_blocks {
fn test_from_config_empty() { fn test_from_config_empty() {
let yaml_string = "---"; let yaml_string = "---";
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(None, Blocks::from_config(&Config::with_yaml(yaml))); assert_eq!(None, Blocks::from_config(&Config::with_none()));
} }
#[test] #[test]
@ -432,7 +424,7 @@ mod test_blocks {
let yaml_string = "blocks:\n - permission"; let yaml_string = "blocks:\n - permission";
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
let blocks = Blocks(vec![Block::Permission]); let blocks = Blocks(vec![Block::Permission]);
assert_eq!(Some(blocks), Blocks::from_config(&Config::with_yaml(yaml))); assert_eq!(Some(blocks), Blocks::from_config(&Config::with_none()));
} }
#[test] #[test]
@ -454,7 +446,7 @@ mod test_blocks {
Block::User, Block::User,
Block::Permission, Block::Permission,
]); ]);
assert_eq!(Some(blocks), Blocks::from_config(&Config::with_yaml(yaml))); assert_eq!(Some(blocks), Blocks::from_config(&Config::with_none()));
} }
#[test] #[test]
@ -466,7 +458,7 @@ mod test_blocks {
"; ";
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
let blocks = Blocks(vec![Block::Permission, Block::Group, Block::Date]); let blocks = Blocks(vec![Block::Permission, Block::Group, Block::Date]);
assert_eq!(Some(blocks), Blocks::from_config(&Config::with_yaml(yaml))); assert_eq!(Some(blocks), Blocks::from_config(&Config::with_none()));
} }
#[test] #[test]
@ -478,7 +470,7 @@ mod test_blocks {
"; ";
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
let blocks = Blocks(vec![Block::Permission, Block::Date]); let blocks = Blocks(vec![Block::Permission, Block::Date]);
assert_eq!(Some(blocks), Blocks::from_config(&Config::with_yaml(yaml))); assert_eq!(Some(blocks), Blocks::from_config(&Config::with_none()));
} }
} }

View file

@ -4,9 +4,9 @@
use super::Configurable; use super::Configurable;
use crate::config_file::Config; use crate::config_file::Config;
use crate::print_error;
use clap::ArgMatches; use clap::ArgMatches;
use yaml_rust::Yaml;
/// A collection of flags on how to use colors. /// A collection of flags on how to use colors.
#[derive(Clone, Debug, Copy, PartialEq, Eq, Default)] #[derive(Clone, Debug, Copy, PartialEq, Eq, Default)]
@ -42,7 +42,7 @@ impl ColorOption {
"auto" => Some(Self::Auto), "auto" => Some(Self::Auto),
"never" => Some(Self::Never), "never" => Some(Self::Never),
_ => { _ => {
config.print_invalid_value_warning("color->when", &value); print_error!("color->when: {}", &value);
None None
} }
} }
@ -78,22 +78,11 @@ impl Configurable<Self> for ColorOption {
/// "when" and it is one of "always", "auto" or "never", this returns its corresponding variant /// "when" and it is one of "always", "auto" or "never", this returns its corresponding variant
/// in a [Some]. Otherwise this returns [None]. /// in a [Some]. Otherwise this returns [None].
fn from_config(config: &Config) -> Option<Self> { fn from_config(config: &Config) -> Option<Self> {
if let Some(yaml) = &config.yaml { if let Some(_c) = &config.color {
if let Yaml::Boolean(true) = &yaml["classic"] { // TODO(zhangwei)
Some(Self::Never) return None
} else {
match &yaml["color"]["when"] {
Yaml::BadValue => None,
Yaml::String(value) => Self::from_yaml_string(&value, &config),
_ => {
config.print_wrong_type_warning("color->when", "string");
None
}
}
}
} else {
None
} }
None
} }
} }
@ -170,7 +159,7 @@ mod test_color_option {
fn test_from_config_empty() { fn test_from_config_empty() {
let yaml_string = "---"; let yaml_string = "---";
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(None, ColorOption::from_config(&Config::with_yaml(yaml))); assert_eq!(None, ColorOption::from_config(&Config::with_none()));
} }
#[test] #[test]
@ -179,7 +168,7 @@ mod test_color_option {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(ColorOption::Always), Some(ColorOption::Always),
ColorOption::from_config(&Config::with_yaml(yaml)) ColorOption::from_config(&Config::with_none())
); );
} }
@ -189,7 +178,7 @@ mod test_color_option {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(ColorOption::Auto), Some(ColorOption::Auto),
ColorOption::from_config(&Config::with_yaml(yaml)) ColorOption::from_config(&Config::with_none())
); );
} }
@ -199,7 +188,7 @@ mod test_color_option {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(ColorOption::Never), Some(ColorOption::Never),
ColorOption::from_config(&Config::with_yaml(yaml)) ColorOption::from_config(&Config::with_none())
); );
} }
@ -209,7 +198,7 @@ mod test_color_option {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(ColorOption::Never), Some(ColorOption::Never),
ColorOption::from_config(&Config::with_yaml(yaml)) ColorOption::from_config(&Config::with_none())
); );
} }
} }

View file

@ -5,9 +5,9 @@ use super::Configurable;
use crate::app; use crate::app;
use crate::config_file::Config; use crate::config_file::Config;
use crate::print_error;
use clap::ArgMatches; use clap::ArgMatches;
use yaml_rust::Yaml;
/// The flag showing which kind of time stamps to display. /// The flag showing which kind of time stamps to display.
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
@ -24,7 +24,7 @@ impl DateFlag {
match app::validate_time_format(&value) { match app::validate_time_format(&value) {
Ok(()) => Some(Self::Formatted(value[1..].to_string())), Ok(()) => Some(Self::Formatted(value[1..].to_string())),
_ => { _ => {
config.print_warning(&format!("Not a valid date format: {}", value)); print_error!("Not a valid date format: {}", value);
None None
} }
} }
@ -38,7 +38,7 @@ impl DateFlag {
"relative" => Some(Self::Relative), "relative" => Some(Self::Relative),
_ if value.starts_with('+') => Self::from_format_string(&value, &config), _ if value.starts_with('+') => Self::from_format_string(&value, &config),
_ => { _ => {
config.print_warning(&format!("Not a valid date value: {}", value)); print_error!("Not a valid date value: {}", value);
None None
} }
} }
@ -76,22 +76,8 @@ impl Configurable<Self> for DateFlag {
/// is one of "date" or "relative", this returns its corresponding variant in a [Some]. /// is one of "date" or "relative", this returns its corresponding variant in a [Some].
/// Otherwise this returns [None]. /// Otherwise this returns [None].
fn from_config(config: &Config) -> Option<Self> { fn from_config(config: &Config) -> Option<Self> {
if let Some(yaml) = &config.yaml { // TODO(zhangwei)
if let Yaml::Boolean(true) = &yaml["classic"] { None
Some(Self::Date)
} else {
match &yaml["date"] {
Yaml::BadValue => None,
Yaml::String(value) => Self::from_yaml_string(&value, &config),
_ => {
config.print_wrong_type_warning("date", "string");
None
}
}
}
} else {
None
}
} }
} }
@ -170,7 +156,7 @@ mod test {
fn test_from_config_empty() { fn test_from_config_empty() {
let yaml_string = "---"; let yaml_string = "---";
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(None, DateFlag::from_config(&Config::with_yaml(yaml))); assert_eq!(None, DateFlag::from_config(&Config::with_none()));
} }
#[test] #[test]
@ -179,7 +165,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(DateFlag::Date), Some(DateFlag::Date),
DateFlag::from_config(&Config::with_yaml(yaml)) DateFlag::from_config(&Config::with_none())
); );
} }
@ -189,7 +175,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(DateFlag::Relative), Some(DateFlag::Relative),
DateFlag::from_config(&Config::with_yaml(yaml)) DateFlag::from_config(&Config::with_none())
); );
} }
@ -199,7 +185,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(DateFlag::Formatted("%F".to_string())), Some(DateFlag::Formatted("%F".to_string())),
DateFlag::from_config(&Config::with_yaml(yaml)) DateFlag::from_config(&Config::with_none())
); );
} }
@ -207,7 +193,7 @@ mod test {
fn test_from_config_format_invalid() { fn test_from_config_format_invalid() {
let yaml_string = "date: +%J"; let yaml_string = "date: +%J";
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(None, DateFlag::from_config(&Config::with_yaml(yaml))); assert_eq!(None, DateFlag::from_config(&Config::with_none()));
} }
#[test] #[test]
@ -216,7 +202,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(DateFlag::Date), Some(DateFlag::Date),
DateFlag::from_config(&Config::with_yaml(yaml)) DateFlag::from_config(&Config::with_none())
); );
} }
} }

View file

@ -6,7 +6,6 @@ use super::Configurable;
use crate::config_file::Config; use crate::config_file::Config;
use clap::ArgMatches; use clap::ArgMatches;
use yaml_rust::Yaml;
/// The flag showing whether to dereference symbolic links. /// The flag showing whether to dereference symbolic links.
#[derive(Clone, Debug, Copy, PartialEq, Eq, Default)] #[derive(Clone, Debug, Copy, PartialEq, Eq, Default)]
@ -31,18 +30,8 @@ impl Configurable<Self> for Dereference {
/// "dereference", this returns its value as the value of the `Dereference`, in a [Some]. /// "dereference", this returns its value as the value of the `Dereference`, in a [Some].
/// Otherwise this returns [None]. /// Otherwise this returns [None].
fn from_config(config: &Config) -> Option<Self> { fn from_config(config: &Config) -> Option<Self> {
if let Some(yaml) = &config.yaml { // TODO(zhangwei)
match &yaml["dereference"] { None
Yaml::BadValue => None,
Yaml::Boolean(value) => Some(Self(*value)),
_ => {
config.print_wrong_type_warning("dereference", "boolean");
None
}
}
} else {
None
}
} }
} }
@ -82,7 +71,7 @@ mod test {
fn test_from_config_empty() { fn test_from_config_empty() {
let yaml_string = "---"; let yaml_string = "---";
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(None, Dereference::from_config(&Config::with_yaml(yaml))); assert_eq!(None, Dereference::from_config(&Config::with_none()));
} }
#[test] #[test]
@ -91,7 +80,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(Dereference(true)), Some(Dereference(true)),
Dereference::from_config(&Config::with_yaml(yaml)) Dereference::from_config(&Config::with_none())
); );
} }
@ -101,7 +90,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(Dereference(false)), Some(Dereference(false)),
Dereference::from_config(&Config::with_yaml(yaml)) Dereference::from_config(&Config::with_none())
); );
} }
} }

View file

@ -4,9 +4,9 @@
use super::Configurable; use super::Configurable;
use crate::config_file::Config; use crate::config_file::Config;
use crate::print_error;
use clap::ArgMatches; use clap::ArgMatches;
use yaml_rust::Yaml;
/// The flag showing which file system nodes to display. /// The flag showing which file system nodes to display.
#[derive(Clone, Debug, Copy, PartialEq, Eq)] #[derive(Clone, Debug, Copy, PartialEq, Eq)]
@ -26,7 +26,7 @@ impl Display {
"almost-all" => Some(Self::AlmostAll), "almost-all" => Some(Self::AlmostAll),
"directory-only" => Some(Self::DirectoryItself), "directory-only" => Some(Self::DirectoryItself),
_ => { _ => {
config.print_invalid_value_warning("display", &value); print_error!("display: {}", &value);
None None
} }
} }
@ -57,18 +57,8 @@ impl Configurable<Self> for Display {
/// it is either "all", "almost-all" or "directory-only", this returns the corresponding /// it is either "all", "almost-all" or "directory-only", this returns the corresponding
/// `Display` variant in a [Some]. Otherwise this returns [None]. /// `Display` variant in a [Some]. Otherwise this returns [None].
fn from_config(config: &Config) -> Option<Self> { fn from_config(config: &Config) -> Option<Self> {
if let Some(yaml) = &config.yaml { // TODO(zhangwei)
match &yaml["display"] { None
Yaml::BadValue => None,
Yaml::String(value) => Self::from_yaml_string(&value, &config),
_ => {
config.print_wrong_type_warning("display", "string");
None
}
}
} else {
None
}
} }
} }
@ -132,7 +122,7 @@ mod test {
fn test_from_config_empty() { fn test_from_config_empty() {
let yaml_string = "---"; let yaml_string = "---";
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(None, Display::from_config(&Config::with_yaml(yaml))); assert_eq!(None, Display::from_config(&Config::with_none()));
} }
#[test] #[test]
@ -141,7 +131,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(Display::All), Some(Display::All),
Display::from_config(&Config::with_yaml(yaml)) Display::from_config(&Config::with_none())
); );
} }
@ -151,7 +141,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(Display::AlmostAll), Some(Display::AlmostAll),
Display::from_config(&Config::with_yaml(yaml)) Display::from_config(&Config::with_none())
); );
} }
@ -161,7 +151,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(Display::DirectoryItself), Some(Display::DirectoryItself),
Display::from_config(&Config::with_yaml(yaml)) Display::from_config(&Config::with_none())
); );
} }
} }

View file

@ -4,9 +4,9 @@
use super::Configurable; use super::Configurable;
use crate::config_file::Config; use crate::config_file::Config;
use crate::print_error;
use clap::ArgMatches; use clap::ArgMatches;
use yaml_rust::Yaml;
/// A collection of flags on how to use icons. /// A collection of flags on how to use icons.
#[derive(Clone, Debug, Copy, PartialEq, Eq, Default)] #[derive(Clone, Debug, Copy, PartialEq, Eq, Default)]
@ -46,7 +46,7 @@ impl IconOption {
"auto" => Some(Self::Auto), "auto" => Some(Self::Auto),
"never" => Some(Self::Never), "never" => Some(Self::Never),
_ => { _ => {
config.print_invalid_value_warning("icons->when", &value); print_error!("icons->when: {}", &value);
None None
} }
} }
@ -82,22 +82,8 @@ impl Configurable<Self> for IconOption {
/// "when" and it is one of "always", "auto" or "never", this returns its corresponding variant /// "when" and it is one of "always", "auto" or "never", this returns its corresponding variant
/// in a [Some]. Otherwise this returns [None]. /// in a [Some]. Otherwise this returns [None].
fn from_config(config: &Config) -> Option<Self> { fn from_config(config: &Config) -> Option<Self> {
if let Some(yaml) = &config.yaml { // TODO(zhangwei)
if let Yaml::Boolean(true) = &yaml["classic"] { None
Some(Self::Never)
} else {
match &yaml["icons"]["when"] {
Yaml::BadValue => None,
Yaml::String(value) => Self::from_yaml_string(&value, &config),
_ => {
config.print_wrong_type_warning("icons->when", "string");
None
}
}
}
} else {
None
}
} }
} }
@ -123,7 +109,7 @@ impl IconTheme {
"fancy" => Some(Self::Fancy), "fancy" => Some(Self::Fancy),
"unicode" => Some(Self::Unicode), "unicode" => Some(Self::Unicode),
_ => { _ => {
config.print_invalid_value_warning("icons->theme", &value); print_error!("icons->theme: {}", &value);
None None
} }
} }
@ -153,18 +139,8 @@ impl Configurable<Self> for IconTheme {
/// "theme" and it is one of "fancy" or "unicode", this returns its corresponding variant in a /// "theme" and it is one of "fancy" or "unicode", this returns its corresponding variant in a
/// [Some]. Otherwise this returns [None]. /// [Some]. Otherwise this returns [None].
fn from_config(config: &Config) -> Option<Self> { fn from_config(config: &Config) -> Option<Self> {
if let Some(yaml) = &config.yaml { // TODO(zhangwei):
match &yaml["icons"]["theme"] { None
Yaml::BadValue => None,
Yaml::String(value) => Self::from_yaml_string(&value, &config),
_ => {
config.print_wrong_type_warning("icons->theme", "string");
None
}
}
} else {
None
}
} }
} }
@ -241,7 +217,7 @@ mod test_icon_option {
fn test_from_config_empty() { fn test_from_config_empty() {
let yaml_string = "---"; let yaml_string = "---";
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(None, IconOption::from_config(&Config::with_yaml(yaml))); assert_eq!(None, IconOption::from_config(&Config::with_none()));
} }
#[test] #[test]
@ -250,7 +226,7 @@ mod test_icon_option {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(IconOption::Always), Some(IconOption::Always),
IconOption::from_config(&Config::with_yaml(yaml)) IconOption::from_config(&Config::with_none())
); );
} }
@ -260,7 +236,7 @@ mod test_icon_option {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(IconOption::Auto), Some(IconOption::Auto),
IconOption::from_config(&Config::with_yaml(yaml)) IconOption::from_config(&Config::with_none())
); );
} }
@ -270,7 +246,7 @@ mod test_icon_option {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(IconOption::Never), Some(IconOption::Never),
IconOption::from_config(&Config::with_yaml(yaml)) IconOption::from_config(&Config::with_none())
); );
} }
@ -280,7 +256,7 @@ mod test_icon_option {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(IconOption::Never), Some(IconOption::Never),
IconOption::from_config(&Config::with_yaml(yaml)) IconOption::from_config(&Config::with_none())
); );
} }
} }
@ -331,7 +307,7 @@ mod test_icon_theme {
fn test_from_config_empty() { fn test_from_config_empty() {
let yaml_string = "---"; let yaml_string = "---";
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(None, IconTheme::from_config(&Config::with_yaml(yaml))); assert_eq!(None, IconTheme::from_config(&Config::with_none()));
} }
#[test] #[test]
@ -340,7 +316,7 @@ mod test_icon_theme {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(IconTheme::Fancy), Some(IconTheme::Fancy),
IconTheme::from_config(&Config::with_yaml(yaml)) IconTheme::from_config(&Config::with_none())
); );
} }
@ -350,7 +326,7 @@ mod test_icon_theme {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(IconTheme::Unicode), Some(IconTheme::Unicode),
IconTheme::from_config(&Config::with_yaml(yaml)) IconTheme::from_config(&Config::with_none())
); );
} }
} }

View file

@ -5,7 +5,6 @@ use crate::config_file::Config;
use clap::{ArgMatches, Error, ErrorKind}; use clap::{ArgMatches, Error, ErrorKind};
use globset::{Glob, GlobSet, GlobSetBuilder}; use globset::{Glob, GlobSet, GlobSetBuilder};
use yaml_rust::Yaml;
/// The struct holding a [GlobSet] and methods to build it. /// The struct holding a [GlobSet] and methods to build it.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -29,7 +28,7 @@ impl IgnoreGlobs {
pub fn configure_from(matches: &ArgMatches, config: &Config) -> Result<Self, Error> { pub fn configure_from(matches: &ArgMatches, config: &Config) -> Result<Self, Error> {
let mut result: Result<Self, Error> = Ok(Default::default()); let mut result: Result<Self, Error> = Ok(Default::default());
if config.has_yaml() { if !matches.is_present("ignore-config") {
if let Some(value) = Self::from_config(config) { if let Some(value) = Self::from_config(config) {
match value { match value {
Ok(glob_set) => result = Ok(Self(glob_set)), Ok(glob_set) => result = Ok(Self(glob_set)),
@ -82,31 +81,8 @@ impl IgnoreGlobs {
/// encountered while building, an [Error] is returned in the Result instead. If the Yaml does /// encountered while building, an [Error] is returned in the Result instead. If the Yaml does
/// not contain such a key, this returns [None]. /// not contain such a key, this returns [None].
fn from_config(config: &Config) -> Option<Result<GlobSet, Error>> { fn from_config(config: &Config) -> Option<Result<GlobSet, Error>> {
if let Some(yaml) = &config.yaml { // TODO(zhangwei)
match &yaml["ignore-globs"] { None
Yaml::BadValue => None,
Yaml::Array(values) => {
let mut glob_set_builder = GlobSetBuilder::new();
for yaml_str in values.iter() {
if let Yaml::String(value) = yaml_str {
match Self::create_glob(value) {
Ok(glob) => {
glob_set_builder.add(glob);
}
Err(err) => return Some(Err(err)),
}
}
}
Some(Self::create_glob_set(&glob_set_builder))
}
_ => {
config.print_wrong_type_warning("ignore-globs", "string");
None
}
}
} else {
None
}
} }
/// Create a [Glob] from a provided pattern. /// Create a [Glob] from a provided pattern.
@ -180,7 +156,7 @@ mod test {
fn test_from_config_empty() { fn test_from_config_empty() {
let yaml_string = "---"; let yaml_string = "---";
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert!(match IgnoreGlobs::from_config(&Config::with_yaml(yaml)) { assert!(match IgnoreGlobs::from_config(&Config::with_none()) {
None => true, None => true,
_ => false, _ => false,
}); });

View file

@ -6,7 +6,6 @@ use super::Configurable;
use crate::config_file::Config; use crate::config_file::Config;
use clap::ArgMatches; use clap::ArgMatches;
use yaml_rust::Yaml;
/// The flag showing whether to print file type indicators. /// The flag showing whether to print file type indicators.
#[derive(Clone, Debug, Copy, PartialEq, Eq, Default)] #[derive(Clone, Debug, Copy, PartialEq, Eq, Default)]
@ -31,18 +30,8 @@ impl Configurable<Self> for Indicators {
/// "indicators", this returns its value as the value of the `Indicators`, in a [Some]. /// "indicators", this returns its value as the value of the `Indicators`, in a [Some].
/// Otherwise this returns [None]. /// Otherwise this returns [None].
fn from_config(config: &Config) -> Option<Self> { fn from_config(config: &Config) -> Option<Self> {
if let Some(yaml) = &config.yaml { // TODO(zhangwei)
match &yaml["indicators"] { None
Yaml::BadValue => None,
Yaml::Boolean(value) => Some(Self(*value)),
_ => {
config.print_wrong_type_warning("indicators", "boolean");
None
}
}
} else {
None
}
} }
} }
@ -82,7 +71,7 @@ mod test {
fn test_from_config_empty() { fn test_from_config_empty() {
let yaml_string = "---"; let yaml_string = "---";
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(None, Indicators::from_config(&Config::with_yaml(yaml))); assert_eq!(None, Indicators::from_config(&Config::with_none()));
} }
#[test] #[test]
@ -91,7 +80,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(Indicators(true)), Some(Indicators(true)),
Indicators::from_config(&Config::with_yaml(yaml)) Indicators::from_config(&Config::with_none())
); );
} }
@ -101,7 +90,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(Indicators(false)), Some(Indicators(false)),
Indicators::from_config(&Config::with_yaml(yaml)) Indicators::from_config(&Config::with_none())
); );
} }
} }

View file

@ -6,7 +6,6 @@ use super::Configurable;
use crate::config_file::Config; use crate::config_file::Config;
use clap::ArgMatches; use clap::ArgMatches;
use yaml_rust::Yaml;
/// The flag showing which output layout to print. /// The flag showing which output layout to print.
#[derive(Clone, Debug, Copy, PartialEq, Eq)] #[derive(Clone, Debug, Copy, PartialEq, Eq)]
@ -44,26 +43,8 @@ impl Configurable<Layout> for Layout {
/// it is either "tree", "oneline" or "grid", this returns the corresponding `Layout` variant /// it is either "tree", "oneline" or "grid", this returns the corresponding `Layout` variant
/// in a [Some]. Otherwise this returns [None]. /// in a [Some]. Otherwise this returns [None].
fn from_config(config: &Config) -> Option<Self> { fn from_config(config: &Config) -> Option<Self> {
if let Some(yaml) = &config.yaml { // TODO(zhangwei)
match &yaml["layout"] { None
Yaml::BadValue => None,
Yaml::String(value) => match value.as_ref() {
"tree" => Some(Self::Tree),
"oneline" => Some(Self::OneLine),
"grid" => Some(Self::Grid),
_ => {
config.print_invalid_value_warning("layout", &value);
None
}
},
_ => {
config.print_wrong_type_warning("layout", "string");
None
}
}
} else {
None
}
} }
} }
@ -128,7 +109,7 @@ mod test {
fn test_from_config_empty() { fn test_from_config_empty() {
let yaml_string = "---"; let yaml_string = "---";
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(None, Layout::from_config(&Config::with_yaml(yaml))); assert_eq!(None, Layout::from_config(&Config::with_none()));
} }
#[test] #[test]
@ -137,7 +118,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(Layout::Tree), Some(Layout::Tree),
Layout::from_config(&Config::with_yaml(yaml)) Layout::from_config(&Config::with_none())
); );
} }
@ -147,7 +128,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(Layout::OneLine), Some(Layout::OneLine),
Layout::from_config(&Config::with_yaml(yaml)) Layout::from_config(&Config::with_none())
); );
} }
@ -157,7 +138,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(Layout::Grid), Some(Layout::Grid),
Layout::from_config(&Config::with_yaml(yaml)) Layout::from_config(&Config::with_none())
); );
} }
} }

View file

@ -4,7 +4,6 @@
use crate::config_file::Config; use crate::config_file::Config;
use clap::{ArgMatches, Error, ErrorKind}; use clap::{ArgMatches, Error, ErrorKind};
use yaml_rust::Yaml;
/// The options relating to recursion. /// The options relating to recursion.
#[derive(Clone, Debug, Copy, PartialEq, Eq)] #[derive(Clone, Debug, Copy, PartialEq, Eq)]
@ -43,11 +42,11 @@ impl Recursion {
fn enabled_from(matches: &ArgMatches, config: &Config) -> bool { fn enabled_from(matches: &ArgMatches, config: &Config) -> bool {
let mut result: bool = Default::default(); let mut result: bool = Default::default();
if config.has_yaml() { // if config.has_yaml() {
if let Some(value) = Self::enabled_from_config(config) { // if let Some(value) = Self::enabled_from_config(config) {
result = value; // result = value;
} // }
} // }
if let Some(value) = Self::enabled_from_arg_matches(matches) { if let Some(value) = Self::enabled_from_arg_matches(matches) {
result = value; result = value;
@ -73,18 +72,8 @@ impl Recursion {
/// If the Config's [Yaml] contains a [Boolean](Yaml::Boolean) value pointed to by "recursion" /// If the Config's [Yaml] contains a [Boolean](Yaml::Boolean) value pointed to by "recursion"
/// -> "enabled", this returns its value in a [Some]. Otherwise this returns [None]. /// -> "enabled", this returns its value in a [Some]. Otherwise this returns [None].
fn enabled_from_config(config: &Config) -> Option<bool> { fn enabled_from_config(config: &Config) -> Option<bool> {
if let Some(yaml) = &config.yaml { // TODO(zhangwei):
match &yaml["recursion"]["enabled"] { None
Yaml::BadValue => None,
Yaml::Boolean(value) => Some(*value),
_ => {
config.print_wrong_type_warning("recursion->enabled", "boolean");
None
}
}
} else {
None
}
} }
/// Get the "depth" integer from [ArgMatches], a [Config] or the [Default] value. The first /// Get the "depth" integer from [ArgMatches], a [Config] or the [Default] value. The first
@ -105,11 +94,11 @@ impl Recursion {
fn depth_from(matches: &ArgMatches, config: &Config) -> Result<usize, Error> { fn depth_from(matches: &ArgMatches, config: &Config) -> Result<usize, Error> {
let mut result: Result<usize, Error> = Ok(usize::max_value()); let mut result: Result<usize, Error> = Ok(usize::max_value());
if config.has_yaml() { // if config.has_yaml() {
if let Some(value) = Self::depth_from_config(config) { // if let Some(value) = Self::depth_from_config(config) {
result = Ok(value); // result = Ok(value);
} // }
} // }
if let Some(value) = Self::depth_from_arg_matches(matches) { if let Some(value) = Self::depth_from_arg_matches(matches) {
result = value; result = value;
@ -148,27 +137,8 @@ impl Recursion {
/// If the Config's [Yaml] contains a positive [Integer](Yaml::Integer) value pointed to by /// If the Config's [Yaml] contains a positive [Integer](Yaml::Integer) value pointed to by
/// "recursion" -> "depth", this returns its value in a [Some]. Otherwise this returns [None]. /// "recursion" -> "depth", this returns its value in a [Some]. Otherwise this returns [None].
fn depth_from_config(config: &Config) -> Option<usize> { fn depth_from_config(config: &Config) -> Option<usize> {
if let Some(yaml) = &config.yaml { // TODO(zhangwei):
match &yaml["recursion"]["depth"] { None
Yaml::BadValue => None,
Yaml::Integer(value) => {
if *value > 0 {
Some(*value as usize)
} else {
config.print_warning(
"The recursion->depth value has to be greater than zero.",
);
None
}
}
_ => {
config.print_wrong_type_warning("recursion->depth", "integer");
None
}
}
} else {
None
}
} }
} }
@ -217,7 +187,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
None, None,
Recursion::enabled_from_config(&Config::with_yaml(yaml)) Recursion::enabled_from_config(&Config::with_none())
); );
} }
@ -227,7 +197,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(true), Some(true),
Recursion::enabled_from_config(&Config::with_yaml(yaml)) Recursion::enabled_from_config(&Config::with_none())
); );
} }
@ -237,7 +207,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(false), Some(false),
Recursion::enabled_from_config(&Config::with_yaml(yaml)) Recursion::enabled_from_config(&Config::with_none())
); );
} }
@ -308,7 +278,7 @@ mod test {
fn test_depth_from_config_empty() { fn test_depth_from_config_empty() {
let yaml_string = "---"; let yaml_string = "---";
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(None, Recursion::depth_from_config(&Config::with_yaml(yaml))); assert_eq!(None, Recursion::depth_from_config(&Config::with_none()));
} }
#[test] #[test]
@ -317,7 +287,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(42), Some(42),
Recursion::depth_from_config(&Config::with_yaml(yaml)) Recursion::depth_from_config(&Config::with_none())
); );
} }
@ -325,13 +295,13 @@ mod test {
fn test_depth_from_config_neg_integer() { fn test_depth_from_config_neg_integer() {
let yaml_string = "recursion:\n depth: -42"; let yaml_string = "recursion:\n depth: -42";
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(None, Recursion::depth_from_config(&Config::with_yaml(yaml))); assert_eq!(None, Recursion::depth_from_config(&Config::with_none()));
} }
#[test] #[test]
fn test_depth_from_config_string() { fn test_depth_from_config_string() {
let yaml_string = "recursion:\n depth: foo"; let yaml_string = "recursion:\n depth: foo";
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(None, Recursion::depth_from_config(&Config::with_yaml(yaml))); assert_eq!(None, Recursion::depth_from_config(&Config::with_none()));
} }
} }

View file

@ -6,7 +6,6 @@ use super::Configurable;
use crate::config_file::Config; use crate::config_file::Config;
use clap::ArgMatches; use clap::ArgMatches;
use yaml_rust::Yaml;
/// The flag showing which file size units to use. /// The flag showing which file size units to use.
#[derive(Clone, Debug, Copy, PartialEq, Eq)] #[derive(Clone, Debug, Copy, PartialEq, Eq)]
@ -44,26 +43,8 @@ impl Configurable<Self> for SizeFlag {
/// is either "default", "short" or "bytes", this returns the corresponding `SizeFlag` variant /// is either "default", "short" or "bytes", this returns the corresponding `SizeFlag` variant
/// in a [Some]. Otherwise this returns [None]. /// in a [Some]. Otherwise this returns [None].
fn from_config(config: &Config) -> Option<Self> { fn from_config(config: &Config) -> Option<Self> {
if let Some(yaml) = &config.yaml { // TODO(zhangwei)
match &yaml["size"] { None
Yaml::BadValue => None,
Yaml::String(value) => match value.as_ref() {
"default" => Some(Self::Default),
"short" => Some(Self::Short),
"bytes" => Some(Self::Bytes),
_ => {
config.print_invalid_value_warning("size", &value);
None
}
},
_ => {
config.print_wrong_type_warning("size", "string");
None
}
}
} else {
None
}
} }
} }
@ -124,7 +105,7 @@ mod test {
fn test_from_config_empty() { fn test_from_config_empty() {
let yaml_string = "---"; let yaml_string = "---";
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(None, SizeFlag::from_config(&Config::with_yaml(yaml))); assert_eq!(None, SizeFlag::from_config(&Config::with_none()));
} }
#[test] #[test]
@ -133,7 +114,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(SizeFlag::Default), Some(SizeFlag::Default),
SizeFlag::from_config(&Config::with_yaml(yaml)) SizeFlag::from_config(&Config::with_none())
); );
} }
@ -143,7 +124,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(SizeFlag::Short), Some(SizeFlag::Short),
SizeFlag::from_config(&Config::with_yaml(yaml)) SizeFlag::from_config(&Config::with_none())
); );
} }
@ -153,7 +134,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(SizeFlag::Bytes), Some(SizeFlag::Bytes),
SizeFlag::from_config(&Config::with_yaml(yaml)) SizeFlag::from_config(&Config::with_none())
); );
} }
} }

View file

@ -6,7 +6,6 @@ use super::Configurable;
use crate::config_file::Config; use crate::config_file::Config;
use clap::ArgMatches; use clap::ArgMatches;
use yaml_rust::Yaml;
/// A collection of flags on how to sort the output. /// A collection of flags on how to sort the output.
#[derive(Clone, Debug, Copy, PartialEq, Eq, Default)] #[derive(Clone, Debug, Copy, PartialEq, Eq, Default)]
@ -69,28 +68,8 @@ impl Configurable<Self> for SortColumn {
/// "column" and it is one of "time", "size" or "name", this returns the corresponding variant /// "column" and it is one of "time", "size" or "name", this returns the corresponding variant
/// in a [Some]. Otherwise this returns [None]. /// in a [Some]. Otherwise this returns [None].
fn from_config(config: &Config) -> Option<Self> { fn from_config(config: &Config) -> Option<Self> {
if let Some(yaml) = &config.yaml { // TODO(zhangwei)
match &yaml["sorting"]["column"] { None
Yaml::BadValue => None,
Yaml::String(value) => match value.as_ref() {
"extension" => Some(Self::Extension),
"name" => Some(Self::Name),
"time" => Some(Self::Time),
"size" => Some(Self::Size),
"version" => Some(Self::Version),
_ => {
config.print_invalid_value_warning("sorting->column", &value);
None
}
},
_ => {
config.print_wrong_type_warning("sorting->column", "string");
None
}
}
} else {
None
}
} }
} }
@ -127,24 +106,8 @@ impl Configurable<Self> for SortOrder {
/// "reverse", this returns a mapped variant in a [Some]. Otherwise [None] is returned. A /// "reverse", this returns a mapped variant in a [Some]. Otherwise [None] is returned. A
/// `true` maps to [SortOrder::Reverse] and a `false` maps to [SortOrder::Default]. /// `true` maps to [SortOrder::Reverse] and a `false` maps to [SortOrder::Default].
fn from_config(config: &Config) -> Option<Self> { fn from_config(config: &Config) -> Option<Self> {
if let Some(yaml) = &config.yaml { // TODO(zhangwei):
match &yaml["sorting"]["reverse"] { None
Yaml::BadValue => None,
Yaml::Boolean(value) => {
if *value {
Some(Self::Reverse)
} else {
Some(Self::Default)
}
}
_ => {
config.print_wrong_type_warning("sorting->reverse", "boolean");
None
}
}
} else {
None
}
} }
} }
@ -192,30 +155,8 @@ impl Configurable<Self> for DirGrouping {
/// "dir-grouping" and it is one of "first", "last" or "none", this returns its corresponding /// "dir-grouping" and it is one of "first", "last" or "none", this returns its corresponding
/// variant in a [Some]. Otherwise this returns [None]. /// variant in a [Some]. Otherwise this returns [None].
fn from_config(config: &Config) -> Option<Self> { fn from_config(config: &Config) -> Option<Self> {
if let Some(yaml) = &config.yaml { // TODO(zhangwei):
if let Yaml::Boolean(true) = &yaml["classic"] { None
Some(Self::None)
} else {
match &yaml["sorting"]["dir-grouping"] {
Yaml::BadValue => None,
Yaml::String(value) => match value.as_ref() {
"first" => Some(Self::First),
"last" => Some(Self::Last),
"none" => Some(Self::None),
_ => {
config.print_invalid_value_warning("sorting->dir-grouping", &value);
None
}
},
_ => {
config.print_wrong_type_warning("sorting->dir-grouping", "string");
None
}
}
}
} else {
None
}
} }
} }
@ -333,14 +274,14 @@ mod test_sort_column {
fn test_from_config_empty() { fn test_from_config_empty() {
let yaml_string = "---"; let yaml_string = "---";
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(None, SortColumn::from_config(&Config::with_yaml(yaml))); assert_eq!(None, SortColumn::from_config(&Config::with_none()));
} }
#[test] #[test]
fn test_from_config_invalid() { fn test_from_config_invalid() {
let yaml_string = "sorting:\n column: foo"; let yaml_string = "sorting:\n column: foo";
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(None, SortColumn::from_config(&Config::with_yaml(yaml))); assert_eq!(None, SortColumn::from_config(&Config::with_none()));
} }
#[test] #[test]
@ -349,7 +290,7 @@ mod test_sort_column {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(SortColumn::Extension), Some(SortColumn::Extension),
SortColumn::from_config(&Config::with_yaml(yaml)) SortColumn::from_config(&Config::with_none())
); );
} }
@ -359,7 +300,7 @@ mod test_sort_column {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(SortColumn::Name), Some(SortColumn::Name),
SortColumn::from_config(&Config::with_yaml(yaml)) SortColumn::from_config(&Config::with_none())
); );
} }
@ -369,7 +310,7 @@ mod test_sort_column {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(SortColumn::Time), Some(SortColumn::Time),
SortColumn::from_config(&Config::with_yaml(yaml)) SortColumn::from_config(&Config::with_none())
); );
} }
@ -379,7 +320,7 @@ mod test_sort_column {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(SortColumn::Size), Some(SortColumn::Size),
SortColumn::from_config(&Config::with_yaml(yaml)) SortColumn::from_config(&Config::with_none())
); );
} }
@ -389,7 +330,7 @@ mod test_sort_column {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(SortColumn::Version), Some(SortColumn::Version),
SortColumn::from_config(&Config::with_yaml(yaml)) SortColumn::from_config(&Config::with_none())
); );
} }
} }
@ -430,7 +371,7 @@ mod test_sort_order {
fn test_from_config_empty() { fn test_from_config_empty() {
let yaml_string = "---"; let yaml_string = "---";
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(None, SortOrder::from_config(&Config::with_yaml(yaml))); assert_eq!(None, SortOrder::from_config(&Config::with_none()));
} }
#[test] #[test]
@ -439,7 +380,7 @@ mod test_sort_order {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(SortOrder::Default), Some(SortOrder::Default),
SortOrder::from_config(&Config::with_yaml(yaml)) SortOrder::from_config(&Config::with_none())
); );
} }
@ -449,7 +390,7 @@ mod test_sort_order {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(SortOrder::Reverse), Some(SortOrder::Reverse),
SortOrder::from_config(&Config::with_yaml(yaml)) SortOrder::from_config(&Config::with_none())
); );
} }
} }
@ -520,7 +461,7 @@ mod test_dir_grouping {
fn test_from_config_empty() { fn test_from_config_empty() {
let yaml_string = "---"; let yaml_string = "---";
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(None, DirGrouping::from_config(&Config::with_yaml(yaml))); assert_eq!(None, DirGrouping::from_config(&Config::with_none()));
} }
#[test] #[test]
@ -529,7 +470,7 @@ mod test_dir_grouping {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(DirGrouping::First), Some(DirGrouping::First),
DirGrouping::from_config(&Config::with_yaml(yaml)) DirGrouping::from_config(&Config::with_none())
); );
} }
@ -539,7 +480,7 @@ mod test_dir_grouping {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(DirGrouping::Last), Some(DirGrouping::Last),
DirGrouping::from_config(&Config::with_yaml(yaml)) DirGrouping::from_config(&Config::with_none())
); );
} }
@ -549,7 +490,7 @@ mod test_dir_grouping {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(DirGrouping::None), Some(DirGrouping::None),
DirGrouping::from_config(&Config::with_yaml(yaml)) DirGrouping::from_config(&Config::with_none())
); );
} }
@ -559,7 +500,7 @@ mod test_dir_grouping {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(DirGrouping::None), Some(DirGrouping::None),
DirGrouping::from_config(&Config::with_yaml(yaml)) DirGrouping::from_config(&Config::with_none())
); );
} }
} }

View file

@ -3,7 +3,6 @@ use super::Configurable;
use crate::config_file::Config; use crate::config_file::Config;
use clap::ArgMatches; use clap::ArgMatches;
use yaml_rust::Yaml;
/// The flag showing how to display symbolic arrow. /// The flag showing how to display symbolic arrow.
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq)]
@ -22,18 +21,8 @@ impl Configurable<Self> for SymlinkArrow {
/// "symlink-arrow", this returns its value as the value of the `SymlinkArrow`, in a [Some]. /// "symlink-arrow", this returns its value as the value of the `SymlinkArrow`, in a [Some].
/// Otherwise this returns [None]. /// Otherwise this returns [None].
fn from_config(config: &Config) -> Option<Self> { fn from_config(config: &Config) -> Option<Self> {
if let Some(yaml) = &config.yaml { // TODO(zhangwei)
match &yaml["symlink-arrow"] { None
Yaml::BadValue => None,
Yaml::String(value) => Some(SymlinkArrow(value.to_string())),
_ => {
config.print_wrong_type_warning("symlink-arrow", "string");
None
}
}
} else {
None
}
} }
} }
@ -66,7 +55,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(SymlinkArrow(String::from("\u{21B9}"))), Some(SymlinkArrow(String::from("\u{21B9}"))),
SymlinkArrow::from_config(&Config::with_yaml(yaml)) SymlinkArrow::from_config(&Config::with_none())
); );
} }
@ -74,7 +63,7 @@ mod test {
fn test_symlink_arrow_from_config_type_error() { fn test_symlink_arrow_from_config_type_error() {
let yaml_string = "symlink-arrow: false"; let yaml_string = "symlink-arrow: false";
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(None, SymlinkArrow::from_config(&Config::with_yaml(yaml))); assert_eq!(None, SymlinkArrow::from_config(&Config::with_none()));
} }
#[test] #[test]

View file

@ -6,7 +6,6 @@ use super::Configurable;
use crate::config_file::Config; use crate::config_file::Config;
use clap::ArgMatches; use clap::ArgMatches;
use yaml_rust::Yaml;
/// The flag showing whether to follow symbolic links. /// The flag showing whether to follow symbolic links.
#[derive(Clone, Debug, Copy, PartialEq, Eq, Default)] #[derive(Clone, Debug, Copy, PartialEq, Eq, Default)]
@ -31,18 +30,8 @@ impl Configurable<Self> for NoSymlink {
/// "no-symlink", this returns its value as the value of the `NoSymlink`, in a [Some]. /// "no-symlink", this returns its value as the value of the `NoSymlink`, in a [Some].
/// Otherwise this returns [None]. /// Otherwise this returns [None].
fn from_config(config: &Config) -> Option<Self> { fn from_config(config: &Config) -> Option<Self> {
if let Some(yaml) = &config.yaml { // TODO(zhangwei)
match &yaml["no-symlink"] { None
Yaml::BadValue => None,
Yaml::Boolean(value) => Some(Self(*value)),
_ => {
config.print_wrong_type_warning("no-symlink", "boolean");
None
}
}
} else {
None
}
} }
} }
@ -79,7 +68,7 @@ mod test {
fn test_from_config_empty() { fn test_from_config_empty() {
let yaml_string = "---"; let yaml_string = "---";
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(None, NoSymlink::from_config(&Config::with_yaml(yaml))); assert_eq!(None, NoSymlink::from_config(&Config::with_none()));
} }
#[test] #[test]
@ -88,7 +77,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(NoSymlink(true)), Some(NoSymlink(true)),
NoSymlink::from_config(&Config::with_yaml(yaml)) NoSymlink::from_config(&Config::with_none())
); );
} }
@ -98,7 +87,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(NoSymlink(false)), Some(NoSymlink(false)),
NoSymlink::from_config(&Config::with_yaml(yaml)) NoSymlink::from_config(&Config::with_none())
); );
} }
} }

View file

@ -6,7 +6,6 @@ use super::Configurable;
use crate::config_file::Config; use crate::config_file::Config;
use clap::ArgMatches; use clap::ArgMatches;
use yaml_rust::Yaml;
/// The flag showing whether to show the total size for directories. /// The flag showing whether to show the total size for directories.
#[derive(Clone, Debug, Copy, PartialEq, Eq, Default)] #[derive(Clone, Debug, Copy, PartialEq, Eq, Default)]
@ -31,18 +30,8 @@ impl Configurable<Self> for TotalSize {
/// "total-size", this returns its value as the value of the `TotalSize`, in a [Some]. /// "total-size", this returns its value as the value of the `TotalSize`, in a [Some].
/// Otherwise this returns [None]. /// Otherwise this returns [None].
fn from_config(config: &Config) -> Option<Self> { fn from_config(config: &Config) -> Option<Self> {
if let Some(yaml) = &config.yaml { // TODO(zhangwei)
match &yaml["total-size"] { None
Yaml::BadValue => None,
Yaml::Boolean(value) => Some(Self(*value)),
_ => {
config.print_wrong_type_warning("total-size", "boolean");
None
}
}
} else {
None
}
} }
} }
@ -79,7 +68,7 @@ mod test {
fn test_from_config_empty() { fn test_from_config_empty() {
let yaml_string = "---"; let yaml_string = "---";
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(None, TotalSize::from_config(&Config::with_yaml(yaml))); assert_eq!(None, TotalSize::from_config(&Config::with_none()));
} }
#[test] #[test]
@ -88,7 +77,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(TotalSize(true)), Some(TotalSize(true)),
TotalSize::from_config(&Config::with_yaml(yaml)) TotalSize::from_config(&Config::with_none())
); );
} }
@ -98,7 +87,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone(); let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!( assert_eq!(
Some(TotalSize(false)), Some(TotalSize(false)),
TotalSize::from_config(&Config::with_yaml(yaml)) TotalSize::from_config(&Config::with_none())
); );
} }
} }

View file

@ -48,17 +48,19 @@ use std::path::PathBuf;
#[macro_export] #[macro_export]
macro_rules! print_error { macro_rules! print_error {
($($arg:tt)*) => { ($($arg:tt)*) => {
use std::io::Write;
let stderr = std::io::stderr();
{ {
let mut handle = stderr.lock(); use std::io::Write;
// We can write on stderr, so we simply ignore the error and don't print
// and stop with success. let stderr = std::io::stderr();
let res = handle.write_all(std::format!($($arg)*).as_bytes());
if res.is_err() { {
std::process::exit(0); let mut handle = stderr.lock();
// We can write on stderr, so we simply ignore the error and don't print
// and stop with success.
let res = handle.write_all(std::format!($($arg)*).as_bytes());
if res.is_err() {
std::process::exit(0);
}
} }
} }
}; };

View file

@ -95,7 +95,7 @@ mod tests {
format!("{}", " ⇒ /target"), format!("{}", " ⇒ /target"),
link.render( link.render(
&Colors::new(Theme::NoColor), &Colors::new(Theme::NoColor),
&Flags::configure_from(&matches, &Config::with_yaml(yaml)).unwrap() &Flags::configure_from(&matches, &Config::with_none()).unwrap()
) )
.to_string() .to_string()
); );
@ -115,7 +115,7 @@ mod tests {
format!("{}", " ⇒ /target"), format!("{}", " ⇒ /target"),
link.render( link.render(
&Colors::new(Theme::NoColor), &Colors::new(Theme::NoColor),
&Flags::configure_from(&matches, &Config::with_yaml(yaml)).unwrap() &Flags::configure_from(&matches, &Config::with_none()).unwrap()
) )
.to_string() .to_string()
); );