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"
checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
[[package]]
name = "dtoa"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b"
[[package]]
name = "float-cmp"
version = "0.8.0"
@ -345,6 +351,8 @@ dependencies = [
"libc",
"lscolors",
"predicates",
"serde",
"serde_yaml",
"tempfile",
"term_grid",
"terminal_size",
@ -424,6 +432,24 @@ dependencies = [
"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]]
name = "rand"
version = "0.7.3"
@ -530,12 +556,55 @@ dependencies = [
"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]]
name = "strsim"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
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]]
name = "tempfile"
version = "3.1.0"
@ -621,6 +690,12 @@ version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
[[package]]
name = "unicode-xid"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]]
name = "users"
version = "0.11.0"

View file

@ -35,6 +35,8 @@ wild = "2.0.*"
globset = "0.4.*"
xdg = "2.1.*"
yaml-rust = "0.4.*"
serde = { version = "1.0", features = ["derive"] }
serde_yaml = "0.8"
[target.'cfg(unix)'.dependencies]
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.
use std::fs::File;
use std::io::prelude::*;
use std::fs;
use std::io::BufReader;
use std::path::PathBuf;
use xdg::BaseDirectories;
use crate::print_error;
#[cfg(not(windows))]
use xdg::BaseDirectories;
use yaml_rust::{Yaml, YamlLoader};
const CONF_DIR: &str = "lsd";
const CONF_FILE_NAME: &str = "config";
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
/// around error handling in a config file.
#[derive(Clone, Debug)]
#[derive(Debug, Deserialize)]
pub struct Config {
pub file: Option<String>,
pub yaml: Option<Yaml>,
pub classic: Option<bool>,
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 {
/// This constructs a Config struct without a file [String] and without a [Yaml].
pub fn with_none() -> Self {
Self {
file: None,
yaml: None,
}
Self::default()
}
/// This constructs a Config struct with a passed file [String] and without a [Yaml].
pub fn with_file(file: String) -> Self {
Self {
file: Some(file),
yaml: None,
// TODO(zhangwei) Box<Error>
pub fn with_file(file: String) -> Option<Self> {
match fs::read(&file) {
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].
#[cfg(test)]
pub fn with_yaml(yaml: Yaml) -> Self {
Self {
file: None,
yaml: Some(yaml),
}
}
/// 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
fn with_yaml(yaml: &str) -> Option<Self> {
match serde_yaml::from_str(yaml) {
Ok(c) => Some(c),
Err(e) => {
print_error!("configuration file format error, {}\n\n", e);
None
}
}
}
/// This provides two paths for a configuration file (the first with the long yaml extension,
/// the second with the short yml extension), according to the XDG_BASE_DIRS specification.
/// This provides the path for a configuration file, according to the XDG_BASE_DIRS specification.
/// not checking the error because this is static
#[cfg(not(windows))]
pub fn config_file_paths(name: &str) -> Option<(PathBuf, PathBuf)> {
let base_dirs;
match BaseDirectories::with_prefix(CONF_DIR) {
Ok(result) => base_dirs = result,
_ => return None,
fn config_file_path() -> PathBuf {
BaseDirectories::with_prefix(CONF_DIR)
.unwrap()
.place_config_file([CONF_FILE_NAME, YAML_LONG_EXT].join("."))
.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,
/// the second with the short yml extension) inside the %APPDATA% directory.
/// This provides the path for a configuration file, inside the %APPDATA% directory.
/// not checking the error because this is static
#[cfg(windows)]
pub fn config_file_paths(name: &str) -> Option<(PathBuf, PathBuf)> {
let mut config_file_long_path;
match dirs::config_dir() {
Some(path) => config_file_long_path = path,
_ => return None,
}
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
));
fn config_file_path() -> PathBuf {
dirs::config_dir()
.unwrap()
.join(CONF_DIR)
.join(CONF_FILE_NAME)
.set_extension(YAML_LONG_EXT)
}
}
impl Default for Config {
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 clap::{ArgMatches, Error, ErrorKind};
use yaml_rust::Yaml;
/// A struct to hold a [Vec] of [Block]s and to provide methods to create it.
#[derive(Clone, Debug, PartialEq, Eq)]
@ -41,7 +40,7 @@ impl Blocks {
};
if matches.is_present("long") {
if config.has_yaml() {
if !matches.is_present("ignore-config") {
if let Some(value) = Self::from_config(config) {
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
/// returns [None].
fn from_config(config: &Config) -> Option<Self> {
if let Some(yaml) = &config.yaml {
match &yaml["blocks"] {
Yaml::BadValue => None,
Yaml::Array(values) => Self::from_yaml_array(values, config),
_ => {
config.print_wrong_type_warning("blocks", "array");
if let Some(c) = &config.blocks {
None
}
}
} else {
None
}
@ -117,23 +109,23 @@ impl Blocks {
/// Get a [Blocks] from a [Yaml] array. The [Config] is used to log warnings about wrong values
/// in a Yaml.
fn from_yaml_array(values: &[Yaml], config: &Config) -> Option<Self> {
let mut blocks: Vec<Block> = vec![];
for array_el in values.iter() {
match array_el {
Yaml::String(value) => match Block::try_from(value.as_str()) {
Ok(block) => blocks.push(block),
Err(err) => config.print_warning(&err),
},
_ => config.print_warning("The blocks config values have to be strings."),
}
}
if blocks.is_empty() {
None
} else {
Some(Self(blocks))
}
}
// fn from_yaml_array(values: &[Yaml], config: &Config) -> Option<Self> {
// let mut blocks: Vec<Block> = vec![];
// for array_el in values.iter() {
// match array_el {
// Yaml::String(value) => match Block::try_from(value.as_str()) {
// Ok(block) => blocks.push(block),
// Err(err) => config.print_warning(&err),
// },
// _ => config.print_warning("The blocks config values have to be strings."),
// }
// }
// if blocks.is_empty() {
// None
// } else {
// Some(Self(blocks))
// }
// }
/// This returns a Blocks struct for the long format.
///
@ -424,7 +416,7 @@ mod test_blocks {
fn test_from_config_empty() {
let yaml_string = "---";
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]
@ -432,7 +424,7 @@ mod test_blocks {
let yaml_string = "blocks:\n - permission";
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
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]
@ -454,7 +446,7 @@ mod test_blocks {
Block::User,
Block::Permission,
]);
assert_eq!(Some(blocks), Blocks::from_config(&Config::with_yaml(yaml)));
assert_eq!(Some(blocks), Blocks::from_config(&Config::with_none()));
}
#[test]
@ -466,7 +458,7 @@ mod test_blocks {
";
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
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]
@ -478,7 +470,7 @@ mod test_blocks {
";
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
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 crate::config_file::Config;
use crate::print_error;
use clap::ArgMatches;
use yaml_rust::Yaml;
/// A collection of flags on how to use colors.
#[derive(Clone, Debug, Copy, PartialEq, Eq, Default)]
@ -42,7 +42,7 @@ impl ColorOption {
"auto" => Some(Self::Auto),
"never" => Some(Self::Never),
_ => {
config.print_invalid_value_warning("color->when", &value);
print_error!("color->when: {}", &value);
None
}
}
@ -78,24 +78,13 @@ impl Configurable<Self> for ColorOption {
/// "when" and it is one of "always", "auto" or "never", this returns its corresponding variant
/// in a [Some]. Otherwise this returns [None].
fn from_config(config: &Config) -> Option<Self> {
if let Some(yaml) = &config.yaml {
if let Yaml::Boolean(true) = &yaml["classic"] {
Some(Self::Never)
} 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");
if let Some(_c) = &config.color {
// TODO(zhangwei)
return None
}
None
}
}
}
} else {
None
}
}
}
/// The default value for `ColorOption` is [ColorOption::Auto].
impl Default for ColorOption {
@ -170,7 +159,7 @@ mod test_color_option {
fn test_from_config_empty() {
let yaml_string = "---";
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]
@ -179,7 +168,7 @@ mod test_color_option {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(
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();
assert_eq!(
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();
assert_eq!(
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();
assert_eq!(
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::config_file::Config;
use crate::print_error;
use clap::ArgMatches;
use yaml_rust::Yaml;
/// The flag showing which kind of time stamps to display.
#[derive(Clone, Debug, PartialEq, Eq)]
@ -24,7 +24,7 @@ impl DateFlag {
match app::validate_time_format(&value) {
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
}
}
@ -38,7 +38,7 @@ impl DateFlag {
"relative" => Some(Self::Relative),
_ 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
}
}
@ -76,24 +76,10 @@ impl Configurable<Self> for DateFlag {
/// is one of "date" or "relative", this returns its corresponding variant in a [Some].
/// Otherwise this returns [None].
fn from_config(config: &Config) -> Option<Self> {
if let Some(yaml) = &config.yaml {
if let Yaml::Boolean(true) = &yaml["classic"] {
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");
// TODO(zhangwei)
None
}
}
}
} else {
None
}
}
}
/// The default value for `DateFlag` is [DateFlag::Date].
impl Default for DateFlag {
@ -170,7 +156,7 @@ mod test {
fn test_from_config_empty() {
let yaml_string = "---";
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]
@ -179,7 +165,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(
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();
assert_eq!(
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();
assert_eq!(
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() {
let yaml_string = "date: +%J";
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]
@ -216,7 +202,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(
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 clap::ArgMatches;
use yaml_rust::Yaml;
/// The flag showing whether to dereference symbolic links.
#[derive(Clone, Debug, Copy, PartialEq, Eq, Default)]
@ -31,20 +30,10 @@ impl Configurable<Self> for Dereference {
/// "dereference", this returns its value as the value of the `Dereference`, in a [Some].
/// Otherwise this returns [None].
fn from_config(config: &Config) -> Option<Self> {
if let Some(yaml) = &config.yaml {
match &yaml["dereference"] {
Yaml::BadValue => None,
Yaml::Boolean(value) => Some(Self(*value)),
_ => {
config.print_wrong_type_warning("dereference", "boolean");
// TODO(zhangwei)
None
}
}
} else {
None
}
}
}
#[cfg(test)]
mod test {
@ -82,7 +71,7 @@ mod test {
fn test_from_config_empty() {
let yaml_string = "---";
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]
@ -91,7 +80,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(
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();
assert_eq!(
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 crate::config_file::Config;
use crate::print_error;
use clap::ArgMatches;
use yaml_rust::Yaml;
/// The flag showing which file system nodes to display.
#[derive(Clone, Debug, Copy, PartialEq, Eq)]
@ -26,7 +26,7 @@ impl Display {
"almost-all" => Some(Self::AlmostAll),
"directory-only" => Some(Self::DirectoryItself),
_ => {
config.print_invalid_value_warning("display", &value);
print_error!("display: {}", &value);
None
}
}
@ -57,20 +57,10 @@ impl Configurable<Self> for Display {
/// it is either "all", "almost-all" or "directory-only", this returns the corresponding
/// `Display` variant in a [Some]. Otherwise this returns [None].
fn from_config(config: &Config) -> Option<Self> {
if let Some(yaml) = &config.yaml {
match &yaml["display"] {
Yaml::BadValue => None,
Yaml::String(value) => Self::from_yaml_string(&value, &config),
_ => {
config.print_wrong_type_warning("display", "string");
// TODO(zhangwei)
None
}
}
} else {
None
}
}
}
/// The default value for `Display` is [Display::DisplayOnlyVisible].
impl Default for Display {
@ -132,7 +122,7 @@ mod test {
fn test_from_config_empty() {
let yaml_string = "---";
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]
@ -141,7 +131,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(
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();
assert_eq!(
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();
assert_eq!(
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 crate::config_file::Config;
use crate::print_error;
use clap::ArgMatches;
use yaml_rust::Yaml;
/// A collection of flags on how to use icons.
#[derive(Clone, Debug, Copy, PartialEq, Eq, Default)]
@ -46,7 +46,7 @@ impl IconOption {
"auto" => Some(Self::Auto),
"never" => Some(Self::Never),
_ => {
config.print_invalid_value_warning("icons->when", &value);
print_error!("icons->when: {}", &value);
None
}
}
@ -82,24 +82,10 @@ impl Configurable<Self> for IconOption {
/// "when" and it is one of "always", "auto" or "never", this returns its corresponding variant
/// in a [Some]. Otherwise this returns [None].
fn from_config(config: &Config) -> Option<Self> {
if let Some(yaml) = &config.yaml {
if let Yaml::Boolean(true) = &yaml["classic"] {
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");
// TODO(zhangwei)
None
}
}
}
} else {
None
}
}
}
/// The default value for the `IconOption` is [IconOption::Auto].
impl Default for IconOption {
@ -123,7 +109,7 @@ impl IconTheme {
"fancy" => Some(Self::Fancy),
"unicode" => Some(Self::Unicode),
_ => {
config.print_invalid_value_warning("icons->theme", &value);
print_error!("icons->theme: {}", &value);
None
}
}
@ -153,20 +139,10 @@ impl Configurable<Self> for IconTheme {
/// "theme" and it is one of "fancy" or "unicode", this returns its corresponding variant in a
/// [Some]. Otherwise this returns [None].
fn from_config(config: &Config) -> Option<Self> {
if let Some(yaml) = &config.yaml {
match &yaml["icons"]["theme"] {
Yaml::BadValue => None,
Yaml::String(value) => Self::from_yaml_string(&value, &config),
_ => {
config.print_wrong_type_warning("icons->theme", "string");
// TODO(zhangwei):
None
}
}
} else {
None
}
}
}
/// The default value for `IconTheme` is [IconTheme::Fancy].
impl Default for IconTheme {
@ -241,7 +217,7 @@ mod test_icon_option {
fn test_from_config_empty() {
let yaml_string = "---";
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]
@ -250,7 +226,7 @@ mod test_icon_option {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(
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();
assert_eq!(
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();
assert_eq!(
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();
assert_eq!(
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() {
let yaml_string = "---";
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]
@ -340,7 +316,7 @@ mod test_icon_theme {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(
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();
assert_eq!(
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 globset::{Glob, GlobSet, GlobSetBuilder};
use yaml_rust::Yaml;
/// The struct holding a [GlobSet] and methods to build it.
#[derive(Clone, Debug)]
@ -29,7 +28,7 @@ impl IgnoreGlobs {
pub fn configure_from(matches: &ArgMatches, config: &Config) -> Result<Self, Error> {
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) {
match value {
Ok(glob_set) => result = Ok(Self(glob_set)),
@ -82,32 +81,9 @@ impl IgnoreGlobs {
/// encountered while building, an [Error] is returned in the Result instead. If the Yaml does
/// not contain such a key, this returns [None].
fn from_config(config: &Config) -> Option<Result<GlobSet, Error>> {
if let Some(yaml) = &config.yaml {
match &yaml["ignore-globs"] {
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");
// TODO(zhangwei)
None
}
}
} else {
None
}
}
/// Create a [Glob] from a provided pattern.
///
@ -180,7 +156,7 @@ mod test {
fn test_from_config_empty() {
let yaml_string = "---";
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,
_ => false,
});

View file

@ -6,7 +6,6 @@ use super::Configurable;
use crate::config_file::Config;
use clap::ArgMatches;
use yaml_rust::Yaml;
/// The flag showing whether to print file type indicators.
#[derive(Clone, Debug, Copy, PartialEq, Eq, Default)]
@ -31,20 +30,10 @@ impl Configurable<Self> for Indicators {
/// "indicators", this returns its value as the value of the `Indicators`, in a [Some].
/// Otherwise this returns [None].
fn from_config(config: &Config) -> Option<Self> {
if let Some(yaml) = &config.yaml {
match &yaml["indicators"] {
Yaml::BadValue => None,
Yaml::Boolean(value) => Some(Self(*value)),
_ => {
config.print_wrong_type_warning("indicators", "boolean");
// TODO(zhangwei)
None
}
}
} else {
None
}
}
}
#[cfg(test)]
mod test {
@ -82,7 +71,7 @@ mod test {
fn test_from_config_empty() {
let yaml_string = "---";
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]
@ -91,7 +80,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(
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();
assert_eq!(
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 clap::ArgMatches;
use yaml_rust::Yaml;
/// The flag showing which output layout to print.
#[derive(Clone, Debug, Copy, PartialEq, Eq)]
@ -44,27 +43,9 @@ impl Configurable<Layout> for Layout {
/// it is either "tree", "oneline" or "grid", this returns the corresponding `Layout` variant
/// in a [Some]. Otherwise this returns [None].
fn from_config(config: &Config) -> Option<Self> {
if let Some(yaml) = &config.yaml {
match &yaml["layout"] {
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);
// TODO(zhangwei)
None
}
},
_ => {
config.print_wrong_type_warning("layout", "string");
None
}
}
} else {
None
}
}
}
/// The default value for `Layout` is [Layout::Grid].
@ -128,7 +109,7 @@ mod test {
fn test_from_config_empty() {
let yaml_string = "---";
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]
@ -137,7 +118,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(
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();
assert_eq!(
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();
assert_eq!(
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 clap::{ArgMatches, Error, ErrorKind};
use yaml_rust::Yaml;
/// The options relating to recursion.
#[derive(Clone, Debug, Copy, PartialEq, Eq)]
@ -43,11 +42,11 @@ impl Recursion {
fn enabled_from(matches: &ArgMatches, config: &Config) -> bool {
let mut result: bool = Default::default();
if config.has_yaml() {
if let Some(value) = Self::enabled_from_config(config) {
result = value;
}
}
// if config.has_yaml() {
// if let Some(value) = Self::enabled_from_config(config) {
// result = value;
// }
// }
if let Some(value) = Self::enabled_from_arg_matches(matches) {
result = value;
@ -73,19 +72,9 @@ impl 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].
fn enabled_from_config(config: &Config) -> Option<bool> {
if let Some(yaml) = &config.yaml {
match &yaml["recursion"]["enabled"] {
Yaml::BadValue => None,
Yaml::Boolean(value) => Some(*value),
_ => {
config.print_wrong_type_warning("recursion->enabled", "boolean");
// TODO(zhangwei):
None
}
}
} else {
None
}
}
/// Get the "depth" integer from [ArgMatches], a [Config] or the [Default] value. The first
/// value that is not [None] is used. The order of precedence for the value used is:
@ -105,11 +94,11 @@ impl Recursion {
fn depth_from(matches: &ArgMatches, config: &Config) -> Result<usize, Error> {
let mut result: Result<usize, Error> = Ok(usize::max_value());
if config.has_yaml() {
if let Some(value) = Self::depth_from_config(config) {
result = Ok(value);
}
}
// if config.has_yaml() {
// if let Some(value) = Self::depth_from_config(config) {
// result = Ok(value);
// }
// }
if let Some(value) = Self::depth_from_arg_matches(matches) {
result = value;
@ -148,29 +137,10 @@ impl Recursion {
/// 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].
fn depth_from_config(config: &Config) -> Option<usize> {
if let Some(yaml) = &config.yaml {
match &yaml["recursion"]["depth"] {
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.",
);
// TODO(zhangwei):
None
}
}
_ => {
config.print_wrong_type_warning("recursion->depth", "integer");
None
}
}
} else {
None
}
}
}
/// The default values for `Recursion` are the boolean default and [prim@usize::max_value()].
impl Default for Recursion {
@ -217,7 +187,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(
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();
assert_eq!(
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();
assert_eq!(
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() {
let yaml_string = "---";
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]
@ -317,7 +287,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(
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() {
let yaml_string = "recursion:\n depth: -42";
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]
fn test_depth_from_config_string() {
let yaml_string = "recursion:\n depth: foo";
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 clap::ArgMatches;
use yaml_rust::Yaml;
/// The flag showing which file size units to use.
#[derive(Clone, Debug, Copy, PartialEq, Eq)]
@ -44,27 +43,9 @@ impl Configurable<Self> for SizeFlag {
/// is either "default", "short" or "bytes", this returns the corresponding `SizeFlag` variant
/// in a [Some]. Otherwise this returns [None].
fn from_config(config: &Config) -> Option<Self> {
if let Some(yaml) = &config.yaml {
match &yaml["size"] {
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);
// TODO(zhangwei)
None
}
},
_ => {
config.print_wrong_type_warning("size", "string");
None
}
}
} else {
None
}
}
}
/// The default value for `SizeFlag` is [SizeFlag::Default].
@ -124,7 +105,7 @@ mod test {
fn test_from_config_empty() {
let yaml_string = "---";
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]
@ -133,7 +114,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(
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();
assert_eq!(
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();
assert_eq!(
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 clap::ArgMatches;
use yaml_rust::Yaml;
/// A collection of flags on how to sort the output.
#[derive(Clone, Debug, Copy, PartialEq, Eq, Default)]
@ -69,29 +68,9 @@ impl Configurable<Self> for SortColumn {
/// "column" and it is one of "time", "size" or "name", this returns the corresponding variant
/// in a [Some]. Otherwise this returns [None].
fn from_config(config: &Config) -> Option<Self> {
if let Some(yaml) = &config.yaml {
match &yaml["sorting"]["column"] {
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);
// TODO(zhangwei)
None
}
},
_ => {
config.print_wrong_type_warning("sorting->column", "string");
None
}
}
} else {
None
}
}
}
/// The default value for `SortColumn` is [SortColumn::Name].
@ -127,26 +106,10 @@ impl Configurable<Self> for SortOrder {
/// "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].
fn from_config(config: &Config) -> Option<Self> {
if let Some(yaml) = &config.yaml {
match &yaml["sorting"]["reverse"] {
Yaml::BadValue => None,
Yaml::Boolean(value) => {
if *value {
Some(Self::Reverse)
} else {
Some(Self::Default)
}
}
_ => {
config.print_wrong_type_warning("sorting->reverse", "boolean");
// TODO(zhangwei):
None
}
}
} else {
None
}
}
}
/// The default value for `SortOrder` is [SortOrder::Default].
impl Default for SortOrder {
@ -192,31 +155,9 @@ impl Configurable<Self> for DirGrouping {
/// "dir-grouping" and it is one of "first", "last" or "none", this returns its corresponding
/// variant in a [Some]. Otherwise this returns [None].
fn from_config(config: &Config) -> Option<Self> {
if let Some(yaml) = &config.yaml {
if let Yaml::Boolean(true) = &yaml["classic"] {
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);
// TODO(zhangwei):
None
}
},
_ => {
config.print_wrong_type_warning("sorting->dir-grouping", "string");
None
}
}
}
} else {
None
}
}
}
/// The default value for `DirGrouping` is [DirGrouping::None].
@ -333,14 +274,14 @@ mod test_sort_column {
fn test_from_config_empty() {
let yaml_string = "---";
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]
fn test_from_config_invalid() {
let yaml_string = "sorting:\n column: foo";
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]
@ -349,7 +290,7 @@ mod test_sort_column {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(
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();
assert_eq!(
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();
assert_eq!(
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();
assert_eq!(
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();
assert_eq!(
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() {
let yaml_string = "---";
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]
@ -439,7 +380,7 @@ mod test_sort_order {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(
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();
assert_eq!(
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() {
let yaml_string = "---";
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]
@ -529,7 +470,7 @@ mod test_dir_grouping {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(
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();
assert_eq!(
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();
assert_eq!(
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();
assert_eq!(
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 clap::ArgMatches;
use yaml_rust::Yaml;
/// The flag showing how to display symbolic arrow.
#[derive(Clone, Debug, Eq, PartialEq)]
@ -22,20 +21,10 @@ impl Configurable<Self> for SymlinkArrow {
/// "symlink-arrow", this returns its value as the value of the `SymlinkArrow`, in a [Some].
/// Otherwise this returns [None].
fn from_config(config: &Config) -> Option<Self> {
if let Some(yaml) = &config.yaml {
match &yaml["symlink-arrow"] {
Yaml::BadValue => None,
Yaml::String(value) => Some(SymlinkArrow(value.to_string())),
_ => {
config.print_wrong_type_warning("symlink-arrow", "string");
// TODO(zhangwei)
None
}
}
} else {
None
}
}
}
/// The default value for the `SymlinkArrow` is `\u{21d2}(⇒)`
impl Default for SymlinkArrow {
@ -66,7 +55,7 @@ mod test {
let yaml = YamlLoader::load_from_str(yaml_string).unwrap()[0].clone();
assert_eq!(
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() {
let yaml_string = "symlink-arrow: false";
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]

View file

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

View file

@ -48,6 +48,7 @@ use std::path::PathBuf;
#[macro_export]
macro_rules! print_error {
($($arg:tt)*) => {
{
use std::io::Write;
let stderr = std::io::stderr();
@ -61,6 +62,7 @@ macro_rules! print_error {
std::process::exit(0);
}
}
}
};
}

View file

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