Skip to content

Implement custom string parser from either &str or &OsStr.#28

Merged
TeXitoi merged 2 commits into
TeXitoi:masterfrom
kennytm:from-str
Nov 9, 2017
Merged

Implement custom string parser from either &str or &OsStr.#28
TeXitoi merged 2 commits into
TeXitoi:masterfrom
kennytm:from-str

Conversation

@kennytm

@kennytm kennytm commented Nov 8, 2017

Copy link
Copy Markdown
Contributor

Fix #2.
Fix #3.

Syntax:

#[derive(StructOpt)]
struct HexReader {
    #[structopt(short = "n", parse(try_from_str = "parse_hex"))]
    number: u32,
    #[structopt(short = "o", parse(from_os_str))]
    output: PathBuf,
} 

@TeXitoi TeXitoi left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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) |

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Result<T, E> no?

Maybe say somewhere what we do with the error (call .to_string() on it).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK then, better to not lose things.

Comment thread structopt-derive/src/lib.rs Outdated
//! 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

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should change that to say that E::to_string will be called instead, no?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The existing implementation still uses description(). Or would you like to change that to to_string() too? 😉

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes better to use the same thing everywhere.

Comment thread structopt-derive/src/lib.rs Outdated
.next()
}

fn despecialize_bool_and_u64(cur_type: Ty) -> Ty {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Too specific name, prefer the intent (convert_with_custom_parse or something like that).

Comment thread structopt-derive/src/lib.rs Outdated
validator(|s| s.parse::<#convert_type>()
.map(|_| ())
.map_err(|e| e.description().into()))
let (cur_type, validator) = match get_parser(field) {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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| ())).

Comment thread tests/custom-string-parsers.rs Outdated
"test", "-a=?", "-b=?", "-c=?", "-d=?",
]))
);
} No newline at end of file

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lack tests with default value:

  • parse(from_str) (with a Vec<u8> for example)
  • parse(try_from_str) (with a u64 for example)
  • parse(from_os_str) (PathBuf)

and an empty line at the end of file

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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` |

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@TeXitoi TeXitoi merged commit 13fc4fb into TeXitoi:master Nov 9, 2017
@TeXitoi

TeXitoi commented Nov 9, 2017

Copy link
Copy Markdown
Owner

Thanks

@TeXitoi

TeXitoi commented Nov 9, 2017

Copy link
Copy Markdown
Owner

v0.1.4 published

@kennytm kennytm deleted the from-str branch November 9, 2017 09:53
@CAD97 CAD97 mentioned this pull request Feb 17, 2018
11 tasks
Eijebong pushed a commit to Eijebong/structopt that referenced this pull request Jan 2, 2019
* added limits

* review update

* change default for maniac_nodes to 4096
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants