Skip to content

Commit

Permalink
Merge pull request #3395 from epage/box
Browse files Browse the repository at this point in the history
refactor: Prepare for replacing `info`
  • Loading branch information
epage committed Feb 2, 2022
2 parents 6638fc4 + 03832c7 commit 7ca872e
Show file tree
Hide file tree
Showing 31 changed files with 73 additions and 59 deletions.
16 changes: 8 additions & 8 deletions src/build/app/mod.rs
Expand Up @@ -23,14 +23,14 @@ use os_str_bytes::RawOsStr;
use yaml_rust::Yaml;

// Internal
use crate::{
build::{arg::ArgProvider, Arg, ArgGroup, ArgPredicate, ArgSettings},
mkeymap::MKeyMap,
output::{fmt::Colorizer, Help, HelpWriter, Usage},
parse::{ArgMatcher, ArgMatches, Input, Parser},
util::{color::ColorChoice, Id, Key},
Error, ErrorKind, Result as ClapResult, INTERNAL_ERROR_MSG,
};
use crate::build::{arg::ArgProvider, Arg, ArgGroup, ArgPredicate, ArgSettings};
use crate::error::ErrorKind;
use crate::error::Result as ClapResult;
use crate::mkeymap::MKeyMap;
use crate::output::{fmt::Colorizer, Help, HelpWriter, Usage};
use crate::parse::{ArgMatcher, ArgMatches, Input, Parser};
use crate::util::{color::ColorChoice, Id, Key};
use crate::{Error, INTERNAL_ERROR_MSG};

/// Build a command-line interface.
///
Expand Down
2 changes: 1 addition & 1 deletion src/build/usage_parser.rs
Expand Up @@ -1260,7 +1260,7 @@ mod test {

#[test]
fn issue_665() {
use crate::{App, ErrorKind};
use crate::{error::ErrorKind, App};
// Verify fix for "arg_from_usage(): required values not being enforced when followed by another option"
let res = App::new("tester")
.arg(Arg::from_usage("-v, --reroll-count=[N] 'Mark the patch series as PATCH vN'"))
Expand Down
4 changes: 3 additions & 1 deletion src/lib.rs
Expand Up @@ -26,13 +26,15 @@
#[cfg(not(feature = "std"))]
compile_error!("`std` feature is currently required to build `clap`");

pub use crate::parse::error;
pub use crate::parse::error::{ErrorKind, Result};
#[cfg(feature = "color")]
pub use crate::util::color::ColorChoice;
pub use crate::{
build::{
App, AppFlags, AppSettings, Arg, ArgFlags, ArgGroup, ArgSettings, PossibleValue, ValueHint,
},
parse::errors::{Error, ErrorKind, Result},
parse::error::Error,
parse::{ArgMatches, Indices, OsValues, Values},
};

Expand Down
48 changes: 30 additions & 18 deletions src/parse/errors.rs → src/parse/error.rs
@@ -1,3 +1,5 @@
//! Error reporting

// Std
use std::{
borrow::Cow,
Expand All @@ -20,7 +22,7 @@ use crate::{
/// Short hand for [`Result`] type
///
/// [`Result`]: std::result::Result
pub type Result<T> = StdResult<T, Error>;
pub type Result<T, E = Error> = StdResult<T, E>;

/// Command line argument parser kind of error
#[derive(Debug, Copy, Clone, PartialEq)]
Expand Down Expand Up @@ -431,13 +433,20 @@ pub enum ErrorKind {
/// [`App::error`]: crate::App::error
#[derive(Debug)]
pub struct Error {
/// Formatted error message, enhancing the cause message with extra information
message: Message,
inner: Box<ErrorInner>,
/// The type of error
pub kind: ErrorKind,
/// Additional information depending on the error kind, like values and argument names.
/// Useful when you want to render an error of your own.
pub info: Vec<String>,
}

#[derive(Debug)]
struct ErrorInner {
/// The type of error
kind: ErrorKind,
/// Formatted error message, enhancing the cause message with extra information
message: Message,
source: Option<Box<dyn error::Error + Send + Sync>>,
wait_on_exit: bool,
backtrace: Option<Backtrace>,
Expand All @@ -461,14 +470,14 @@ impl Error {
pub fn format(mut self, app: &mut App) -> Self {
app._build();
let usage = app.render_usage();
self.message.format(app, usage);
self.wait_on_exit = app.settings.is_set(AppSettings::WaitOnError);
self.inner.message.format(app, usage);
self.inner.wait_on_exit = app.settings.is_set(AppSettings::WaitOnError);
self
}

/// Type of error for programmatic processing
pub fn kind(&self) -> ErrorKind {
self.kind
self.inner.kind
}

/// Should the message be written to `stdout` or not?
Expand All @@ -489,7 +498,7 @@ impl Error {
// Swallow broken pipe errors
let _ = self.print();

if self.wait_on_exit {
if self.inner.wait_on_exit {
wlnerr!("\nPress [ENTER] / [RETURN] to continue...");
let mut s = String::new();
let i = io::stdin();
Expand Down Expand Up @@ -521,7 +530,7 @@ impl Error {
/// };
/// ```
pub fn print(&self) -> io::Result<()> {
self.message.formatted().print()
self.inner.message.formatted().print()
}

/// Deprecated, replaced with [`App::error`]
Expand All @@ -534,12 +543,15 @@ impl Error {

pub(crate) fn new(message: impl Into<Message>, kind: ErrorKind, wait_on_exit: bool) -> Self {
Self {
message: message.into(),
inner: Box::new(ErrorInner {
kind,
message: message.into(),
source: None,
wait_on_exit,
backtrace: Backtrace::new(),
}),
kind,
info: vec![],
source: None,
wait_on_exit,
backtrace: Backtrace::new(),
}
}

Expand All @@ -564,7 +576,7 @@ impl Error {
}

pub(crate) fn set_source(mut self, source: Box<dyn error::Error + Send + Sync>) -> Self {
self.source = Some(source);
self.inner.source = Some(source);
self
}

Expand Down Expand Up @@ -885,7 +897,7 @@ impl Error {
app.get_color(),
app.settings.is_set(AppSettings::WaitOnError),
);
match &mut err.message {
match &mut err.inner.message {
Message::Raw(_) => {
unreachable!("`value_validation_with_color` only deals in formatted errors")
}
Expand All @@ -900,7 +912,7 @@ impl Error {
err: Box<dyn error::Error + Send + Sync>,
) -> Self {
let mut err = Self::value_validation_with_color(arg, val, err, ColorChoice::Never, false);
match &mut err.message {
match &mut err.inner.message {
Message::Raw(_) => {
unreachable!("`value_validation_with_color` only deals in formatted errors")
}
Expand Down Expand Up @@ -1073,15 +1085,15 @@ impl From<fmt::Error> for Error {
impl error::Error for Error {
#[allow(trivial_casts)]
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
self.source.as_ref().map(|e| e.as_ref() as _)
self.inner.source.as_ref().map(|e| e.as_ref() as _)
}
}

impl Display for Error {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
// Assuming `self.message` already has a trailing newline, from `try_help` or similar
write!(f, "{}", self.message.formatted())?;
if let Some(backtrace) = self.backtrace.as_ref() {
write!(f, "{}", self.inner.message.formatted())?;
if let Some(backtrace) = self.inner.backtrace.as_ref() {
writeln!(f)?;
writeln!(f, "Backtrace:")?;
writeln!(f, "{}", backtrace)?;
Expand Down
2 changes: 1 addition & 1 deletion src/parse/mod.rs
@@ -1,4 +1,4 @@
pub mod errors;
pub mod error;
pub mod features;

mod arg_matcher;
Expand Down
6 changes: 3 additions & 3 deletions src/parse/parser.rs
Expand Up @@ -14,9 +14,9 @@ use crate::{
build::{App, Arg, ArgSettings},
mkeymap::KeyType,
output::{fmt::Colorizer, Help, HelpWriter, Usage},
parse::errors::Error as ClapError,
parse::errors::ErrorKind,
parse::errors::Result as ClapResult,
parse::error::Error as ClapError,
parse::error::ErrorKind,
parse::error::Result as ClapResult,
parse::features::suggestions,
parse::{ArgMatcher, SubCommand},
parse::{Validator, ValueType},
Expand Down
2 changes: 1 addition & 1 deletion src/parse/validator.rs
Expand Up @@ -3,7 +3,7 @@ use crate::{
build::{arg::PossibleValue, App, AppSettings as AS, Arg, ArgSettings},
output::Usage,
parse::{
errors::{Error, ErrorKind, Result as ClapResult},
error::{Error, ErrorKind, Result as ClapResult},
ArgMatcher, MatchedArg, ParseState, Parser,
},
util::Id,
Expand Down
2 changes: 1 addition & 1 deletion tests/builder/app_from_crate.rs
@@ -1,6 +1,6 @@
#![cfg(feature = "cargo")]

use clap::{app_from_crate, ErrorKind};
use clap::{app_from_crate, error::ErrorKind};

static EVERYTHING: &str = "clap {{version}}
A simple to use, efficient, and full-featured Command Line Argument Parser
Expand Down
2 changes: 1 addition & 1 deletion tests/builder/app_settings.rs
@@ -1,6 +1,6 @@
use crate::utils;

use clap::{arg, App, AppSettings, Arg, ErrorKind};
use clap::{arg, error::ErrorKind, App, AppSettings, Arg};

static ALLOW_EXT_SC: &str = "clap-test v1.4.8
Expand Down
2 changes: 1 addition & 1 deletion tests/builder/cargo.rs
@@ -1,6 +1,6 @@
#![cfg(feature = "cargo")]

use clap::{crate_authors, crate_description, crate_name, crate_version, App, ErrorKind};
use clap::{crate_authors, crate_description, crate_name, crate_version, error::ErrorKind, App};

static DESCRIPTION_ONLY: &str = "prog 1
A simple to use, efficient, and full-featured Command Line Argument Parser
Expand Down
2 changes: 1 addition & 1 deletion tests/builder/conflicts.rs
@@ -1,6 +1,6 @@
use crate::utils;

use clap::{arg, App, Arg, ArgGroup, ErrorKind};
use clap::{arg, error::ErrorKind, App, Arg, ArgGroup};

static CONFLICT_ERR: &str = "error: The argument '--flag' cannot be used with '-F'
Expand Down
2 changes: 1 addition & 1 deletion tests/builder/default_vals.rs
@@ -1,5 +1,5 @@
use crate::utils;
use clap::{arg, App, Arg, ErrorKind};
use clap::{arg, error::ErrorKind, App, Arg};

#[test]
fn opts() {
Expand Down
2 changes: 1 addition & 1 deletion tests/builder/double_require.rs
@@ -1,4 +1,4 @@
use clap::{App, Arg, ErrorKind};
use clap::{error::ErrorKind, App, Arg};

static HELP: &str = "prog
Expand Down
2 changes: 1 addition & 1 deletion tests/builder/empty_values.rs
@@ -1,6 +1,6 @@
use crate::utils;

use clap::{App, Arg, ErrorKind};
use clap::{error::ErrorKind, App, Arg};

#[test]
fn empty_values() {
Expand Down
2 changes: 1 addition & 1 deletion tests/builder/error.rs
@@ -1,6 +1,6 @@
use crate::utils;

use clap::{arg, App, Arg, Error, ErrorKind};
use clap::{arg, error::ErrorKind, App, Arg, Error};

fn compare_error(
err: Error,
Expand Down
2 changes: 1 addition & 1 deletion tests/builder/flag_subcommands.rs
@@ -1,6 +1,6 @@
use crate::utils;

use clap::{arg, App, AppSettings, Arg, ErrorKind};
use clap::{arg, error::ErrorKind, App, AppSettings, Arg};

#[test]
fn flag_subcommand_normal() {
Expand Down
2 changes: 1 addition & 1 deletion tests/builder/flags.rs
Expand Up @@ -89,7 +89,7 @@ fn flag_using_long() {

#[test]
fn flag_using_long_with_literals() {
use clap::ErrorKind;
use clap::error::ErrorKind;

let m = App::new("flag")
.arg(Arg::new("rainbow").long("rainbow"))
Expand Down
2 changes: 1 addition & 1 deletion tests/builder/groups.rs
@@ -1,6 +1,6 @@
use crate::utils;

use clap::{arg, App, Arg, ArgGroup, ErrorKind};
use clap::{arg, error::ErrorKind, App, Arg, ArgGroup};

static REQ_GROUP_USAGE: &str = "error: The following required arguments were not provided:
<base|--delete>
Expand Down
2 changes: 1 addition & 1 deletion tests/builder/help.rs
@@ -1,6 +1,6 @@
use crate::utils;

use clap::{arg, App, AppSettings, Arg, ArgGroup, ErrorKind, PossibleValue};
use clap::{arg, error::ErrorKind, App, AppSettings, Arg, ArgGroup, PossibleValue};

static REQUIRE_DELIM_HELP: &str = "test 1.3
Kevin K.
Expand Down
2 changes: 1 addition & 1 deletion tests/builder/multiple_occurrences.rs
@@ -1,4 +1,4 @@
use clap::{arg, App, Arg, ErrorKind};
use clap::{arg, error::ErrorKind, App, Arg};

#[test]
fn multiple_occurrences_of_flags_long() {
Expand Down
2 changes: 1 addition & 1 deletion tests/builder/multiple_values.rs
@@ -1,4 +1,4 @@
use clap::{App, Arg, ErrorKind};
use clap::{error::ErrorKind, App, Arg};

#[test]
fn option_long() {
Expand Down
2 changes: 1 addition & 1 deletion tests/builder/opts.rs
@@ -1,6 +1,6 @@
use crate::utils;

use clap::{arg, App, AppSettings, Arg, ArgMatches, ErrorKind};
use clap::{arg, error::ErrorKind, App, AppSettings, Arg, ArgMatches};

#[cfg(feature = "suggestions")]
static DYM: &str =
Expand Down
2 changes: 1 addition & 1 deletion tests/builder/positionals.rs
@@ -1,4 +1,4 @@
use clap::{arg, App, Arg, ErrorKind};
use clap::{arg, error::ErrorKind, App, Arg};

#[test]
fn only_pos_follow() {
Expand Down
2 changes: 1 addition & 1 deletion tests/builder/posix_compatible.rs
@@ -1,4 +1,4 @@
use clap::{arg, App, Arg, ErrorKind};
use clap::{arg, error::ErrorKind, App, Arg};

#[test]
fn flag_overrides_itself() {
Expand Down
2 changes: 1 addition & 1 deletion tests/builder/possible_values.rs
@@ -1,6 +1,6 @@
use crate::utils;

use clap::{App, Arg, ErrorKind, PossibleValue};
use clap::{error::ErrorKind, App, Arg, PossibleValue};

#[cfg(feature = "suggestions")]
static PV_ERROR: &str = "error: \"slo\" isn't a valid value for '-O <option>'
Expand Down
2 changes: 1 addition & 1 deletion tests/builder/regex.rs
@@ -1,6 +1,6 @@
#![cfg(feature = "regex")]

use clap::{App, Arg, ErrorKind};
use clap::{error::ErrorKind, App, Arg};
use regex::{Regex, RegexSet};

#[test]
Expand Down
2 changes: 1 addition & 1 deletion tests/builder/require.rs
@@ -1,6 +1,6 @@
use crate::utils;

use clap::{arg, App, Arg, ArgGroup, ErrorKind};
use clap::{arg, error::ErrorKind, App, Arg, ArgGroup};

static REQUIRE_EQUALS: &str = "error: The following required arguments were not provided:
--opt=<FILE>
Expand Down
2 changes: 1 addition & 1 deletion tests/builder/subcommands.rs
@@ -1,6 +1,6 @@
use crate::utils;

use clap::{arg, App, AppSettings, Arg, ErrorKind};
use clap::{arg, error::ErrorKind, App, AppSettings, Arg};

static VISIBLE_ALIAS_HELP: &str = "clap-test 2.6
Expand Down
2 changes: 1 addition & 1 deletion tests/builder/utf8.rs
@@ -1,6 +1,6 @@
#![cfg(not(windows))]

use clap::{arg, App, AppSettings, Arg, ErrorKind};
use clap::{arg, error::ErrorKind, App, AppSettings, Arg};
use std::ffi::OsString;
use std::os::unix::ffi::OsStringExt;

Expand Down

0 comments on commit 7ca872e

Please sign in to comment.