Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Prepare for replacing info #3395

Merged
merged 6 commits into from Feb 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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