Skip to content

Commit

Permalink
feat(Validators): adds ability to validate invalid UTF-8
Browse files Browse the repository at this point in the history
  • Loading branch information
glowing-chemist committed Dec 27, 2016
1 parent f49fb88 commit 4723249
Show file tree
Hide file tree
Showing 8 changed files with 21 additions and 13 deletions.
4 changes: 2 additions & 2 deletions src/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ mod help;
// Std
use std::borrow::Borrow;
use std::env;
use std::ffi::OsString;
use std::ffi::{OsStr, OsString};
use std::fmt;
use std::io::{self, BufRead, BufWriter, Write};
use std::path::Path;
Expand Down Expand Up @@ -1525,7 +1525,7 @@ impl<'n, 'e> AnyArg<'n, 'e> for App<'n, 'e> {
fn num_vals(&self) -> Option<u64> { None }
fn possible_vals(&self) -> Option<&[&'e str]> { None }
fn validator(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>> { None }
fn validator_os(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>> { None }
fn validator_os(&self) -> Option<&Rc<Fn(&OsStr) -> StdResult<(), OsString>>> { None }
fn min_vals(&self) -> Option<u64> { None }
fn short(&self) -> Option<char> { None }
fn long(&self) -> Option<&'e str> { None }
Expand Down
4 changes: 2 additions & 2 deletions src/app/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1534,8 +1534,8 @@ impl<'a, 'b> Parser<'a, 'b>
}
}
if let Some(vtor) = arg.validator_os() {
if let Err(e) = vtor(val.to_string_lossy().into_owned()) {
return Err(Error::value_validation(Some(arg), e, self.color()));
if let Err(e) = vtor(val) {
return Err(Error::value_validation(Some(arg), e.into_string().unwrap_or("error invalid UTF-8".to_string()), self.color()));
}
}
if matcher.needs_more_vals(arg) {
Expand Down
3 changes: 2 additions & 1 deletion src/args/any_arg.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Std
use std::rc::Rc;
use std::fmt as std_fmt;
use std::ffi::{OsStr, OsString};

// Third Party
use vec_map::VecMap;
Expand All @@ -26,7 +27,7 @@ pub trait AnyArg<'n, 'e>: std_fmt::Display {
fn num_vals(&self) -> Option<u64>;
fn possible_vals(&self) -> Option<&[&'e str]>;
fn validator(&self) -> Option<&Rc<Fn(String) -> Result<(), String>>>;
fn validator_os(&self) -> Option<&Rc<Fn(String) -> Result<(), String>>>;
fn validator_os(&self) -> Option<&Rc<Fn(&OsStr) -> Result<(), OsString>>>;
fn short(&self) -> Option<char>;
fn long(&self) -> Option<&'e str>;
fn val_delim(&self) -> Option<char>;
Expand Down
11 changes: 7 additions & 4 deletions src/args/arg.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#[cfg(feature = "yaml")]
use std::collections::BTreeMap;
use std::rc::Rc;
use std::ffi::{OsString, OsStr};

#[cfg(feature = "yaml")]
use yaml_rust::Yaml;
Expand Down Expand Up @@ -66,7 +67,7 @@ pub struct Arg<'a, 'b>
#[doc(hidden)]
pub validator: Option<Rc<Fn(String) -> Result<(), String>>>,
#[doc(hidden)]
pub validator_os: Option<Rc<Fn(String) -> Result<(), String>>>,
pub validator_os: Option<Rc<Fn(&OsStr) -> Result<(), OsString>>>,
#[doc(hidden)]
pub overrides: Option<Vec<&'a str>>,
#[doc(hidden)]
Expand Down Expand Up @@ -1915,7 +1916,7 @@ impl<'a, 'b> Arg<'a, 'b> {
/// # Examples
/// ```rust
/// # use clap::{App, Arg};
///fn has_ampersand(v: String) -> Result<(), String> {
///fn has_ampersand(v: &OsStr) -> Result<(), String> {
/// if v.contains("&") { return Ok(()); }
/// Err(String::from("The value did not contain the required & sigil"))
/// }
Expand All @@ -1930,13 +1931,15 @@ impl<'a, 'b> Arg<'a, 'b> {
/// assert_eq!(res.unwrap().value_of("file"), Some("Fish & chips"));
/// ```
/// [`String`]: https://doc.rust-lang.org/std/string/struct.String.html
/// [`OsStr`]: https://doc.rust-lang.org/std/ffi/struct.OsStr.html
/// [`OsString`]: https://doc.rust-lang.org/std/ffi/struct.OsString.html
/// [`Result`]: https://doc.rust-lang.org/std/result/enum.Result.html
/// [`Err(String)`]: https://doc.rust-lang.org/std/result/enum.Result.html#variant.Err
/// [`Rc`]: https://doc.rust-lang.org/std/rc/struct.Rc.html
pub fn validator_os<F>(mut self, f: F) -> Self
where F: Fn(String) -> Result<(), String> + 'static
where F: Fn(&OsStr) -> Result<(), OsString> + 'static
{
self.validator = Some(Rc::new(f));
self.validator_os = Some(Rc::new(f));
self
}

Expand Down
3 changes: 2 additions & 1 deletion src/args/arg_builder/flag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::convert::From;
use std::fmt::{Display, Formatter, Result};
use std::rc::Rc;
use std::result::Result as StdResult;
use std::ffi::{OsStr, OsString};

// Third Party
use vec_map::VecMap;
Expand Down Expand Up @@ -64,7 +65,7 @@ impl<'n, 'e> AnyArg<'n, 'e> for FlagBuilder<'n, 'e> {
fn num_vals(&self) -> Option<u64> { None }
fn possible_vals(&self) -> Option<&[&'e str]> { None }
fn validator(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>> { None }
fn validator_os(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>> { None }
fn validator_os(&self) -> Option<&Rc<Fn(&OsStr) -> StdResult<(), OsString>>> { None }
fn min_vals(&self) -> Option<u64> { None }
fn short(&self) -> Option<char> { self.s.short }
fn long(&self) -> Option<&'e str> { self.s.long }
Expand Down
3 changes: 2 additions & 1 deletion src/args/arg_builder/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
use std::fmt::{Display, Formatter, Result};
use std::rc::Rc;
use std::result::Result as StdResult;
use std::ffi::{OsStr, OsString};

// Third Party
use vec_map::VecMap;
Expand Down Expand Up @@ -107,7 +108,7 @@ impl<'n, 'e> AnyArg<'n, 'e> for OptBuilder<'n, 'e> {
fn validator(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>> {
self.v.validator.as_ref()
}
fn validator_os(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>> {
fn validator_os(&self) -> Option<&Rc<Fn(&OsStr) -> StdResult<(), OsString>>> {
self.v.validator_os.as_ref()
}
fn min_vals(&self) -> Option<u64> { self.v.min_vals }
Expand Down
3 changes: 2 additions & 1 deletion src/args/arg_builder/positional.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::borrow::Cow;
use std::fmt::{Display, Formatter, Result};
use std::rc::Rc;
use std::result::Result as StdResult;
use std::ffi::{OsStr, OsString};

// Third Party
use vec_map::VecMap;
Expand Down Expand Up @@ -111,7 +112,7 @@ impl<'n, 'e> AnyArg<'n, 'e> for PosBuilder<'n, 'e> {
fn validator(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>> {
self.v.validator.as_ref()
}
fn validator_os(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>> {
fn validator_os(&self) -> Option<&Rc<Fn(&OsStr) -> StdResult<(), OsString>>> {
self.v.validator_os.as_ref()
}
fn min_vals(&self) -> Option<u64> { self.v.min_vals }
Expand Down
3 changes: 2 additions & 1 deletion src/args/arg_builder/valued.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::rc::Rc;
use std::ffi::{OsStr, OsString};

use vec_map::VecMap;

Expand All @@ -15,7 +16,7 @@ pub struct Valued<'a, 'b>
pub max_vals: Option<u64>,
pub min_vals: Option<u64>,
pub validator: Option<Rc<Fn(String) -> Result<(), String>>>,
pub validator_os: Option<Rc<Fn(String) -> Result<(), String>>>,
pub validator_os: Option<Rc<Fn(&OsStr) -> Result<(), OsString>>>,
pub val_delim: Option<char>,
pub default_val: Option<&'a str>,
}
Expand Down

0 comments on commit 4723249

Please sign in to comment.