Move command-line arguments into args module
This patch crates the args module, renames the Opt struct to Args and moves it to the new args module. This makes the main.rs file easier to read and allows us to add more details to the Args struct in the future.
This commit is contained in:
parent
c48711f3cf
commit
3a20d662c5
82
src/args.rs
Normal file
82
src/args.rs
Normal file
@ -0,0 +1,82 @@
|
||||
// SPDX-FileCopyrightText: 2020 Robin Krahl <robin.krahl@ireas.org>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use structopt::StructOpt;
|
||||
|
||||
use crate::doc;
|
||||
use crate::viewer;
|
||||
|
||||
/// Command-line viewer for rustdoc documentation
|
||||
///
|
||||
/// rusty-man reads the HTML documentation generated by rustdoc and displays a documentation item.
|
||||
/// Make sure to run `cargo doc` before using rusty-man. Per default, rusty-man looks up
|
||||
/// documentation in the ./target/doc directory relative to the current working directory and in
|
||||
/// the system documentation directories (share/doc/rust{,-doc}/html relative to the Rust sysroot,
|
||||
/// see `rustc --print sysroot`, or /usr). Use the -s/--source option if you want to read the
|
||||
/// documentation from a different directory.
|
||||
///
|
||||
/// 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, StructOpt)]
|
||||
pub struct Args {
|
||||
/// The keyword to open the documentation for, e. g. `rand_core::RngCore`
|
||||
pub keyword: doc::Name,
|
||||
|
||||
/// The sources to check for documentation generated by rustdoc
|
||||
///
|
||||
/// Typically, this is the path of a directory containing the documentation for one or more
|
||||
/// crates in subdirectories.
|
||||
#[structopt(name = "source", short, long, number_of_values = 1)]
|
||||
pub source_paths: Vec<String>,
|
||||
|
||||
/// The viewer for the rustdoc documentation (one of: plain, rich)
|
||||
#[structopt(long, parse(try_from_str = viewer::get_viewer))]
|
||||
pub viewer: Option<Box<dyn viewer::Viewer>>,
|
||||
|
||||
/// Do not search the default documentation sources
|
||||
///
|
||||
/// 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.
|
||||
#[structopt(long)]
|
||||
pub no_default_sources: bool,
|
||||
|
||||
/// Do not read the search index if there is no exact match
|
||||
///
|
||||
/// 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.
|
||||
#[structopt(long)]
|
||||
pub no_search: bool,
|
||||
|
||||
/// Show all examples for the item instead of opening the full documentation.
|
||||
#[structopt(short, long)]
|
||||
pub examples: bool,
|
||||
|
||||
#[structopt(flatten)]
|
||||
pub viewer_args: ViewerArgs,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
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.
|
||||
#[structopt(long)]
|
||||
pub no_syntax_highlight: bool,
|
||||
|
||||
/// The color theme for syntax highlighting
|
||||
///
|
||||
/// rusty-man includes these color themes: base16-ocean.dark, base16-eighties.dark,
|
||||
/// base16-mocha.dark, base16-ocean.light, InspiredGitHub, Solarized (dark), Solarized (light).
|
||||
#[structopt(long, default_value = "base16-eighties.dark")]
|
||||
pub theme: String,
|
||||
}
|
||||
|
||||
impl Args {
|
||||
pub fn load() -> Args {
|
||||
Args::from_args()
|
||||
}
|
||||
}
|
94
src/main.rs
94
src/main.rs
@ -35,6 +35,7 @@
|
||||
//! We don’t support the old index format. As the format of the HTML files is not specified,
|
||||
//! rusty-man might not work with new Rust versions that change the documentation format.
|
||||
|
||||
mod args;
|
||||
mod doc;
|
||||
mod index;
|
||||
mod parser;
|
||||
@ -44,102 +45,31 @@ mod viewer;
|
||||
use std::io;
|
||||
use std::path;
|
||||
|
||||
use structopt::StructOpt;
|
||||
|
||||
/// Command-line viewer for rustdoc documentation
|
||||
///
|
||||
/// rusty-man reads the HTML documentation generated by rustdoc and displays a documentation item.
|
||||
/// Make sure to run `cargo doc` before using rusty-man. Per default, rusty-man looks up
|
||||
/// documentation in the ./target/doc directory relative to the current working directory and in
|
||||
/// the system documentation directories (share/doc/rust{,-doc}/html relative to the Rust sysroot,
|
||||
/// see `rustc --print sysroot`, or /usr). Use the -s/--source option if you want to read the
|
||||
/// documentation from a different directory.
|
||||
///
|
||||
/// 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, StructOpt)]
|
||||
struct Opt {
|
||||
/// The keyword to open the documentation for, e. g. `rand_core::RngCore`
|
||||
keyword: doc::Name,
|
||||
|
||||
/// The sources to check for documentation generated by rustdoc
|
||||
///
|
||||
/// Typically, this is the path of a directory containing the documentation for one or more
|
||||
/// crates in subdirectories.
|
||||
#[structopt(name = "source", short, long, number_of_values = 1)]
|
||||
source_paths: Vec<String>,
|
||||
|
||||
/// The viewer for the rustdoc documentation (one of: plain, rich)
|
||||
#[structopt(long, parse(try_from_str = viewer::get_viewer))]
|
||||
viewer: Option<Box<dyn viewer::Viewer>>,
|
||||
|
||||
/// Do not search the default documentation sources
|
||||
///
|
||||
/// 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.
|
||||
#[structopt(long)]
|
||||
no_default_sources: bool,
|
||||
|
||||
/// Do not read the search index if there is no exact match
|
||||
///
|
||||
/// 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.
|
||||
#[structopt(long)]
|
||||
no_search: bool,
|
||||
|
||||
/// Show all examples for the item instead of opening the full documentation.
|
||||
#[structopt(short, long)]
|
||||
examples: bool,
|
||||
|
||||
#[structopt(flatten)]
|
||||
viewer_args: ViewerArgs,
|
||||
}
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
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.
|
||||
#[structopt(long)]
|
||||
no_syntax_highlight: bool,
|
||||
|
||||
/// The color theme for syntax highlighting
|
||||
///
|
||||
/// rusty-man includes these color themes: base16-ocean.dark, base16-eighties.dark,
|
||||
/// base16-mocha.dark, base16-ocean.light, InspiredGitHub, Solarized (dark), Solarized (light).
|
||||
#[structopt(long, default_value = "base16-eighties.dark")]
|
||||
theme: String,
|
||||
}
|
||||
|
||||
fn main() -> anyhow::Result<()> {
|
||||
env_logger::init();
|
||||
|
||||
let opt = Opt::from_args();
|
||||
let sources = load_sources(&opt.source_paths, !opt.no_default_sources)?;
|
||||
let doc = if let Some(doc) = find_doc(&sources, &opt.keyword)? {
|
||||
let args = args::Args::load();
|
||||
let sources = load_sources(&args.source_paths, !args.no_default_sources)?;
|
||||
let doc = if let Some(doc) = find_doc(&sources, &args.keyword)? {
|
||||
Some(doc)
|
||||
} else if !opt.no_search {
|
||||
search_doc(&sources, &opt.keyword)?
|
||||
} else if !args.no_search {
|
||||
search_doc(&sources, &args.keyword)?
|
||||
} else {
|
||||
anyhow::bail!("Could not find documentation for {}", &opt.keyword);
|
||||
anyhow::bail!("Could not find documentation for {}", &args.keyword);
|
||||
};
|
||||
|
||||
if let Some(doc) = doc {
|
||||
let viewer = opt.viewer.unwrap_or_else(viewer::get_default);
|
||||
if opt.examples {
|
||||
let viewer = args.viewer.unwrap_or_else(viewer::get_default);
|
||||
if args.examples {
|
||||
let examples = doc.find_examples()?;
|
||||
anyhow::ensure!(
|
||||
!examples.is_empty(),
|
||||
"Could not find examples for {}",
|
||||
&opt.keyword
|
||||
&args.keyword
|
||||
);
|
||||
viewer.open_examples(opt.viewer_args, &doc, examples)
|
||||
viewer.open_examples(args.viewer_args, &doc, examples)
|
||||
} else {
|
||||
viewer.open(opt.viewer_args, &doc)
|
||||
viewer.open(args.viewer_args, &doc)
|
||||
}
|
||||
} else {
|
||||
// item selection cancelled by user
|
||||
|
@ -7,14 +7,15 @@ use std::cmp;
|
||||
use std::fmt;
|
||||
use std::io;
|
||||
|
||||
use crate::args;
|
||||
use crate::doc;
|
||||
|
||||
pub trait Viewer: fmt::Debug {
|
||||
fn open(&self, args: crate::ViewerArgs, doc: &doc::Doc) -> anyhow::Result<()>;
|
||||
fn open(&self, args: args::ViewerArgs, doc: &doc::Doc) -> anyhow::Result<()>;
|
||||
|
||||
fn open_examples(
|
||||
&self,
|
||||
args: crate::ViewerArgs,
|
||||
args: args::ViewerArgs,
|
||||
doc: &doc::Doc,
|
||||
examples: Vec<doc::Example>,
|
||||
) -> anyhow::Result<()>;
|
||||
|
@ -8,11 +8,12 @@ use std::fmt;
|
||||
use std::io;
|
||||
use std::marker;
|
||||
|
||||
use crate::args;
|
||||
use crate::doc;
|
||||
use crate::viewer;
|
||||
|
||||
pub trait Printer: fmt::Debug + marker::Sized {
|
||||
fn new(args: crate::ViewerArgs) -> anyhow::Result<Self>;
|
||||
fn new(args: args::ViewerArgs) -> anyhow::Result<Self>;
|
||||
|
||||
fn print_title(&self, left: &str, middle: &str, right: &str) -> io::Result<()>;
|
||||
|
||||
@ -42,7 +43,7 @@ impl<P: Printer> TextViewer<P> {
|
||||
}
|
||||
}
|
||||
|
||||
fn exec<F>(&self, args: crate::ViewerArgs, op: F) -> anyhow::Result<()>
|
||||
fn exec<F>(&self, args: args::ViewerArgs, op: F) -> anyhow::Result<()>
|
||||
where
|
||||
F: FnOnce(&TextRenderer<P>) -> io::Result<()>,
|
||||
{
|
||||
@ -67,13 +68,13 @@ impl TextViewer<rich::RichTextRenderer> {
|
||||
}
|
||||
|
||||
impl<P: Printer> viewer::Viewer for TextViewer<P> {
|
||||
fn open(&self, args: crate::ViewerArgs, doc: &doc::Doc) -> anyhow::Result<()> {
|
||||
fn open(&self, args: args::ViewerArgs, doc: &doc::Doc) -> anyhow::Result<()> {
|
||||
self.exec(args, |r| r.print_doc(doc))
|
||||
}
|
||||
|
||||
fn open_examples(
|
||||
&self,
|
||||
args: crate::ViewerArgs,
|
||||
args: args::ViewerArgs,
|
||||
doc: &doc::Doc,
|
||||
examples: Vec<doc::Example>,
|
||||
) -> anyhow::Result<()> {
|
||||
|
@ -5,6 +5,7 @@ use std::io::{self, Write};
|
||||
|
||||
use html2text::render::text_renderer;
|
||||
|
||||
use crate::args;
|
||||
use crate::doc;
|
||||
use crate::viewer;
|
||||
|
||||
@ -20,7 +21,7 @@ struct Decorator {
|
||||
}
|
||||
|
||||
impl super::Printer for PlainTextRenderer {
|
||||
fn new(_args: crate::ViewerArgs) -> anyhow::Result<Self> {
|
||||
fn new(_args: args::ViewerArgs) -> anyhow::Result<Self> {
|
||||
Ok(Self {
|
||||
line_length: viewer::get_line_length(),
|
||||
})
|
||||
|
@ -5,6 +5,7 @@ use std::io::{self, Write};
|
||||
|
||||
use html2text::render::text_renderer;
|
||||
|
||||
use crate::args;
|
||||
use crate::doc;
|
||||
use crate::viewer;
|
||||
|
||||
@ -54,7 +55,7 @@ impl RichTextRenderer {
|
||||
}
|
||||
|
||||
impl super::Printer for RichTextRenderer {
|
||||
fn new(args: crate::ViewerArgs) -> anyhow::Result<Self> {
|
||||
fn new(args: args::ViewerArgs) -> anyhow::Result<Self> {
|
||||
use anyhow::Context;
|
||||
|
||||
let mut theme_set = syntect::highlighting::ThemeSet::load_defaults();
|
||||
|
Loading…
Reference in New Issue
Block a user