Implement custom string parser from either &str or &OsStr.#28
Conversation
TeXitoi
left a comment
There was a problem hiding this comment.
Great work! Thanks a lot for this great feature!
| //! | `from_str` | `fn(&str) -> T` | `::std::convert::From::from` | | ||
| //! | `try_from_str` | `fn(&str) -> Result<T, E>` | `::std::str::FromStr::from_str` | | ||
| //! | `from_os_str` | `fn(&OsStr) -> T` | `::std::convert::From::from` | | ||
| //! | `try_from_os_str` | `fn(&OsStr) -> Result<T, OsString>` | (no default function) | |
There was a problem hiding this comment.
Result<T, E> no?
Maybe say somewhere what we do with the error (call .to_string() on it).
There was a problem hiding this comment.
The tricky thing is that validator_os accepts
fn validator_os<F>(self, f: F) -> Self
where
F: Fn(&OsStr) -> Result<(), OsString> + 'static, Maybe it's fine to ignore the lossy conversion from OsStr to String when used for display?
There was a problem hiding this comment.
OK then, better to not lose things.
| //! type, and the `Arg::validator` method is set to a method using | ||
| //! `FromStr::Err::description()` (`FromStr::Err` must implement | ||
| //! `std::Error::Error`). | ||
| //! `std::Error::Error`). If you would like to use a custom string parser other |
There was a problem hiding this comment.
We should change that to say that E::to_string will be called instead, no?
There was a problem hiding this comment.
The existing implementation still uses description(). Or would you like to change that to to_string() too? 😉
There was a problem hiding this comment.
Yes better to use the same thing everywhere.
| .next() | ||
| } | ||
|
|
||
| fn despecialize_bool_and_u64(cur_type: Ty) -> Ty { |
There was a problem hiding this comment.
Too specific name, prefer the intent (convert_with_custom_parse or something like that).
| validator(|s| s.parse::<#convert_type>() | ||
| .map(|_| ()) | ||
| .map_err(|e| e.description().into())) | ||
| let (cur_type, validator) = match get_parser(field) { |
There was a problem hiding this comment.
let (cur_type, validator) = match get_parser(field).unwrap_or((Parser::TryFromStr, "::std::std::FromStr::from_str")) {But it way not pass type check, something should be done for that (maybe just using .map(|_: #convert_type| ())).
| "test", "-a=?", "-b=?", "-c=?", "-d=?", | ||
| ])) | ||
| ); | ||
| } No newline at end of file |
There was a problem hiding this comment.
Lack tests with default value:
-
parse(from_str)(with aVec<u8>for example) -
parse(try_from_str)(with au64for example) -
parse(from_os_str)(PathBuf)
and an empty line at the end of file
There was a problem hiding this comment.
Vec<u8> as a field doesn't work, because Vec and Option are still treated specially. I've defined a type alias instead.
BTW the following also work, but I think this is a defect:
#[derive(StructOpt, PartialEq, Debug)]
struct DefaultedOpt {
#[structopt(short = "b", parse(from_str))]
bytes: (Vec<u8>), // <-- with '(' ... ')'.
}| //! | Kind | Signature | Default | | ||
| //! |-------------------|---------------------------------------|---------------------------------| | ||
| //! | `from_str` | `fn(&str) -> T` | `::std::convert::From::from` | | ||
| //! | `try_from_str` | `fn(&str) -> Result<T, E>` | `::std::str::FromStr::from_str` | |
There was a problem hiding this comment.
That's a bit confusing that ::std::str::FromStr::from_str is the default for try_from_str and not from_str but I can't find a better idea.
|
Thanks |
|
v0.1.4 published |
* added limits * review update * change default for maniac_nodes to 4096
Fix #2.
Fix #3.
Syntax:
structopt(parse(...)),boolandu64will be treated as the same asTy::Other, butVec<T>andOption<T>remains special.try_from_strwill be converted to string using.to_string()instead of.description(), as the latter is not being recommended (see Using Error well: .description() vs Display rust-lang/rust#44842 and Provide better guidance forError::descriptionrust-lang/rust#45249).