Skip to content

Commit

Permalink
Add convinience methods.
Browse files Browse the repository at this point in the history
  • Loading branch information
BonnyAD9 committed Dec 16, 2024
1 parent 6f8cbd6 commit 9310a55
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 39 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
# CHANGELOG

## Future
## v0.6.0
- Add `all_arg`, `remaining` and `cur_remaining` to `Pareg`.
- Add `cur_val_or_next` to `Pareg`.
- Add new error for checking value validity `ArgError::InvalidValue`.
- Add `err_invalid`, `err_invalid_value` and `err_invalid_span` to `Pareg`.
- Make `ArgErrCtx::from_msg` take `impl Into<Cow>` instead of `String`.
- Add `ArgErrCtx::spanned` and `ArgError::spanned`.
- Add `ArgErrCtx::from_inner`.
- Add `part_of`, `inline_msg` and `main_msg` to `ArgErrCtx` and `ArgError`.
- Add `parse_msg` and `err` to `ArgError`
- Require `FromArg` to return `Result<ArgError, T>`
- Remove unncesary mut requirements on `Pareg`.

## v0.5.2
Expand Down
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pareg"
version = "0.5.2"
version = "0.6.0"
edition = "2021"
license-file = "LICENSE"
description = "Rust library with useful tools for command line argument parsing"
Expand All @@ -17,5 +17,5 @@ members = [
]

[dependencies]
pareg_core = { version = "0.5.2", path = "pareg_core" }
pareg_proc = { version = "0.5.2", path = "pareg_proc" }
pareg_core = { version = "0.6.0", path = "pareg_core" }
pareg_proc = { version = "0.6.0", path = "pareg_proc" }
2 changes: 1 addition & 1 deletion pareg_core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pareg_core"
version = "0.5.2"
version = "0.6.0"
edition = "2021"
license-file = "../LICENSE"
description = "This library contains the implementation for the pareg library."
Expand Down
37 changes: 34 additions & 3 deletions pareg_core/src/err/arg_err_ctx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,21 @@ pub struct ArgErrCtx {
}

impl ArgErrCtx {
pub fn from_inner<E: Display>(e: E, arg: String) -> Self {
Self::from_msg(e.to_string(), arg)
}

/// Creates simple error with just message and the errornous argument.
pub fn from_msg(
message: impl Into<Cow<'static, str>>,
arg: String,
) -> Self {
let message = message.into();
Self {
error_span: 0..arg.len(),
args: vec![arg],
error_idx: 0,
long_message: Some(message.clone()),
message,
long_message: None,
message: message.into(),
hint: None,
color: ColorMode::default(),
}
Expand All @@ -51,6 +54,22 @@ impl ArgErrCtx {
self
}

/// Sets new argument. If the original argument is substring of this,
/// span will be adjusted.
pub fn part_of(mut self, arg: String) -> Self {
if self.args[self.error_idx].len() == arg.len() {
self.error_span = 0..arg.len();
self.args[self.error_idx] = arg;
return self;
}
if let Some(shift) = arg.find(&self.args[self.error_idx]) {
self.error_span.start += shift;
self.error_span.end += shift;
}
self.args[self.error_idx] = arg;
self
}

/// Add arguments to the error so that it may have better error message.
/// Mostly useful internaly in pareg.
pub fn add_args(mut self, args: Vec<String>, idx: usize) -> Self {
Expand All @@ -76,6 +95,18 @@ impl ArgErrCtx {
self.error_span = span;
self
}

/// Sets the short message that is inlined with the code.
pub fn inline_msg(mut self, msg: impl Into<Cow<'static, str>>) -> Self {
self.message = msg.into();
self
}

/// Sets the primary (non inline) message.
pub fn main_msg(mut self, msg: impl Into<Cow<'static, str>>) -> Self {
self.long_message = Some(msg.into());
self
}
}

impl Display for ArgErrCtx {
Expand Down
28 changes: 27 additions & 1 deletion pareg_core/src/err/arg_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::{borrow::Cow, ops::Range};

use thiserror::Error;

use super::ArgErrCtx;
use super::{ArgErrCtx, Result};

/// Errors thrown when parsing arguments.
#[derive(Debug, Error)]
Expand Down Expand Up @@ -36,6 +36,11 @@ pub enum ArgError {
}

impl ArgError {
/// Shortcut for creating parse error.
pub fn parse_msg(msg: impl Into<Cow<'static, str>>, arg: String) -> Self {
Self::FailedToParse(Box::new(ArgErrCtx::from_msg(msg, arg)))
}

/// Moves the span in the error message by `cnt` and changes the
/// errornous argument to `new_arg`.
pub fn shift_span(self, cnt: usize, new_arg: String) -> Self {
Expand All @@ -58,6 +63,27 @@ impl ArgError {
self.map_ctx(|c| c.spanned(span))
}

/// Sets the short message that is inlined with the code.
pub fn inline_msg(self, msg: impl Into<Cow<'static, str>>) -> Self {
self.map_ctx(|c| c.inline_msg(msg))
}

/// Sets the primary (non inline) message.
pub fn main_msg(self, msg: impl Into<Cow<'static, str>>) -> Self {
self.map_ctx(|c| c.main_msg(msg))
}

/// Sets new argument. If the original argument is substring of this,
/// span will be adjusted.
pub fn part_of(self, arg: String) -> Self {
self.map_ctx(|c| c.part_of(arg))
}

/// Helper method to wrap this in error and make it a result.
pub fn err<T>(self) -> Result<T> {
Err(self)
}

pub fn map_ctx(self, f: impl FnOnce(ArgErrCtx) -> ArgErrCtx) -> Self {
match self {
ArgError::UnknownArgument(mut ctx) => {
Expand Down
39 changes: 15 additions & 24 deletions pareg_core/src/from_arg.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use std::{
borrow::Cow,
ffi::{OsStr, OsString},
fmt::Display,
net::{
IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6,
},
Expand All @@ -14,7 +13,7 @@ use std::{
use crate::{
err::{ArgError, Result},
impl_all::impl_all,
ArgErrCtx, ColorMode,
ArgErrCtx,
};

/// Represents a trait similar to [`FromStr`], in addition it may return type
Expand All @@ -35,40 +34,32 @@ pub trait FromArg<'a>: Sized {
}

/// Default implementation for [`FromArg`] for types that implement [`FromStr`]
pub trait FromArgStr: FromStr {}
pub trait FromArgStr: FromStr<Err = ArgError> {}

impl<'a, T> FromArg<'a> for T
impl<T> FromArg<'_> for T
where
T: FromArgStr,
T::Err: Display,
{
#[inline]
fn from_arg(arg: &str) -> Result<Self> {
T::from_str(arg).map_err(|e| {
ArgError::FailedToParse(
ArgErrCtx {
args: vec![arg.into()],
error_idx: 0,
error_span: 0..arg.len(),
message: e.to_string().into(),
long_message: Some(
format!("Failed to parse the value `{arg}`: {e}.")
.into(),
),
hint: None,
color: ColorMode::default(),
}
.into(),
)
})
T::from_str(arg)
}
}

impl_all! { FromArgStr:
impl_all! { impl<'a> FromArg<'a>:
u8, i8, u16, i16, u32, i32, u64, i64, u128, i128, f32, f64, usize, isize,
bool, char, String, PathBuf, OsString, IpAddr, SocketAddr, Ipv4Addr,
Ipv6Addr, SocketAddrV4, SocketAddrV6,
=> {}
=> {
#[inline(always)]
fn from_arg(arg: &'a str) -> Result<Self> {
Self::from_str(arg).map_err(|e| {
ArgError::FailedToParse(Box::new(
ArgErrCtx::from_inner(e, arg.to_string())
))
})
}
}
}

impl<'a> FromArg<'a> for &'a str {
Expand Down
4 changes: 2 additions & 2 deletions pareg_proc/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pareg_proc"
version = "0.5.2"
version = "0.6.0"
edition = "2021"
license-file = "../LICENSE"
description = "This library contains proc macros for the pareg library."
Expand All @@ -14,4 +14,4 @@ readme = "../README.md"
proc-macro = true

[dependencies]
pareg_core = { version = "0.5.2", path = "../pareg_core" }
pareg_core = { version = "0.6.0", path = "../pareg_core" }

0 comments on commit 9310a55

Please sign in to comment.