Use merge to merge arguments and configuration
This patch adds the merge dependency to automatically merge the command-line arguments and the settings from the configuration file. This means that we no longer have to manually maintain the Args::merge function.
This commit is contained in:
parent
0bf2f15186
commit
225e19a024
@ -8,6 +8,9 @@ SPDX-License-Identifier: MIT
|
||||
# Unreleased
|
||||
|
||||
- Remove suffix from duplicate members (e. g. from Deref implementations).
|
||||
- Use the `merge` crate to merge the command-line arguments and the settings in
|
||||
the configuration file.
|
||||
- Add `merge` dependency in version 0.1.0.
|
||||
|
||||
## v0.3.0 (2020-09-11)
|
||||
|
||||
|
23
Cargo.lock
generated
23
Cargo.lock
generated
@ -462,6 +462,26 @@ name = "matches"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "merge"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"merge_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "merge_derive"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro-error 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.34 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.4.0"
|
||||
@ -818,6 +838,7 @@ dependencies = [
|
||||
"kuchiki 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"markup5ever 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"merge 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pager 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1320,6 +1341,8 @@ dependencies = [
|
||||
"checksum markup5ever 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aae38d669396ca9b707bfc3db254bc382ddb94f57cc5c235f34623a669a01dab"
|
||||
"checksum markup5ever_rcdom 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f015da43bcd8d4f144559a3423f4591d69b8ce0652c905374da7205df336ae2b"
|
||||
"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
|
||||
"checksum merge 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "10bbef93abb1da61525bbc45eeaff6473a41907d19f8f9aa5168d214e10693e9"
|
||||
"checksum merge_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "209d075476da2e63b4b29e72a2ef627b840589588e71400a25e3565c4f849d07"
|
||||
"checksum miniz_oxide 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "be0f75932c1f6cfae3c04000e40114adf955636e19040f9c0a2c380702aa1c7f"
|
||||
"checksum mio 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6e9971bc8349a361217a8f2a41f5d011274686bd4436465ba51730921039d7fb"
|
||||
"checksum miow 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "07b88fb9795d4d36d62a012dfbf49a8f5cf12751f36d31a9dbe66d528e58979e"
|
||||
|
@ -22,6 +22,7 @@ html2text = "0.1.12"
|
||||
kuchiki = "0.8.0"
|
||||
log = "0.4.11"
|
||||
markup5ever = "0.10.0"
|
||||
merge = "0.1.0"
|
||||
pager = "0.15.0"
|
||||
serde_json = "1.0.56"
|
||||
serde_tuple = "0.5.0"
|
||||
|
41
src/args.rs
41
src/args.rs
@ -4,6 +4,7 @@
|
||||
use std::fs;
|
||||
use std::path;
|
||||
|
||||
use merge::Merge;
|
||||
use serde::Deserialize;
|
||||
use structopt::StructOpt;
|
||||
|
||||
@ -22,10 +23,11 @@ use crate::viewer;
|
||||
/// rusty-man tries to find an item that exactly matches the given keyword. If it doesn’t find an
|
||||
/// exact match, it reads the search indexes of all available sources and tries to find a partial
|
||||
/// match.
|
||||
#[derive(Debug, Default, Deserialize, StructOpt)]
|
||||
#[derive(Debug, Default, Deserialize, Merge, StructOpt)]
|
||||
#[serde(default)]
|
||||
pub struct Args {
|
||||
/// The keyword to open the documentation for, e. g. `rand_core::RngCore`
|
||||
#[merge(skip)]
|
||||
#[serde(skip)]
|
||||
pub keyword: doc::Name,
|
||||
|
||||
@ -33,6 +35,7 @@ pub struct Args {
|
||||
///
|
||||
/// Typically, this is the path of a directory containing the documentation for one or more
|
||||
/// crates in subdirectories.
|
||||
#[merge(strategy = merge::vec::prepend)]
|
||||
#[structopt(name = "source", short, long, number_of_values = 1)]
|
||||
pub source_paths: Vec<String>,
|
||||
|
||||
@ -46,6 +49,7 @@ pub struct Args {
|
||||
/// If this option is not set, rusty-man appends `$sysroot/share/doc/rust{,-doc}/html` and
|
||||
/// `target/doc` to the list of sources if they exist. `$sysroot` is the output of `rustc
|
||||
/// --print sysroot` or `/usr` if that command does not output a valid path.
|
||||
#[merge(strategy = merge::bool::overwrite_false)]
|
||||
#[structopt(long)]
|
||||
pub no_default_sources: bool,
|
||||
|
||||
@ -54,10 +58,12 @@ pub struct Args {
|
||||
/// Per default, rusty-man reads the search indexes of all sources and tries to find matching
|
||||
/// items if there is no exact match for the keyword. If this option is set, the search
|
||||
/// indexes are not read.
|
||||
#[merge(strategy = merge::bool::overwrite_false)]
|
||||
#[structopt(long)]
|
||||
pub no_search: bool,
|
||||
|
||||
/// Show all examples for the item instead of opening the full documentation.
|
||||
#[merge(strategy = merge::bool::overwrite_false)]
|
||||
#[structopt(short, long)]
|
||||
pub examples: bool,
|
||||
|
||||
@ -70,6 +76,7 @@ pub struct Args {
|
||||
///
|
||||
/// If this option is set, rusty-man reads the given configuration file instead. If this
|
||||
/// option is set to "-", rusty-man does not read any configuration files.
|
||||
#[merge(skip)]
|
||||
#[structopt(short, long)]
|
||||
#[serde(skip)]
|
||||
pub config_file: Option<String>,
|
||||
@ -79,13 +86,14 @@ pub struct Args {
|
||||
pub viewer_args: ViewerArgs,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize, StructOpt)]
|
||||
#[derive(Debug, Default, Deserialize, Merge, StructOpt)]
|
||||
#[serde(default)]
|
||||
pub struct ViewerArgs {
|
||||
/// Disable syntax highlighting.
|
||||
///
|
||||
/// Per default, rusty-man tries to highlight Rust code snippets in its output if the rich text
|
||||
/// viewer is selected. If this option is set, it renders the HTML representation instead.
|
||||
#[merge(strategy = merge::bool::overwrite_false)]
|
||||
#[structopt(long)]
|
||||
pub no_syntax_highlight: bool,
|
||||
|
||||
@ -109,8 +117,8 @@ pub struct ViewerArgs {
|
||||
///
|
||||
/// Unless the --width option is set, rusty-man sets the width of the text output based on the
|
||||
/// width of the terminal with the maximum width set with this optioj.
|
||||
#[structopt(long, default_value = "100")]
|
||||
pub max_width: usize,
|
||||
#[structopt(long)]
|
||||
pub max_width: Option<usize>,
|
||||
}
|
||||
|
||||
impl Args {
|
||||
@ -143,31 +151,6 @@ impl Args {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
fn merge(&mut self, mut args: Args) {
|
||||
if !args.source_paths.is_empty() {
|
||||
args.source_paths.append(&mut self.source_paths);
|
||||
self.source_paths = args.source_paths;
|
||||
}
|
||||
if self.viewer.is_none() {
|
||||
self.viewer = args.viewer;
|
||||
}
|
||||
if !self.no_default_sources {
|
||||
self.no_default_sources = args.no_default_sources;
|
||||
}
|
||||
if !self.no_search {
|
||||
self.no_search = args.no_search;
|
||||
}
|
||||
if !self.examples {
|
||||
self.examples = args.examples;
|
||||
}
|
||||
if !self.viewer_args.no_syntax_highlight {
|
||||
self.viewer_args.no_syntax_highlight = args.viewer_args.no_syntax_highlight;
|
||||
}
|
||||
if self.viewer_args.theme.is_none() {
|
||||
self.viewer_args.theme = args.viewer_args.theme;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_viewer<'de, D>(d: D) -> Result<Option<Box<dyn viewer::Viewer>>, D::Error>
|
||||
|
@ -114,9 +114,9 @@ pub fn get_line_length(args: &args::ViewerArgs) -> usize {
|
||||
if let Some(width) = args.width {
|
||||
width
|
||||
} else if let Ok((cols, _)) = crossterm::terminal::size() {
|
||||
cmp::min(cols.into(), args.max_width)
|
||||
cmp::min(cols.into(), args.max_width.unwrap_or(100))
|
||||
} else {
|
||||
args.max_width
|
||||
args.max_width.unwrap_or(100)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user