aboutsummaryrefslogtreecommitdiff
path: root/structopt/tests/custom-string-parsers.rs
diff options
context:
space:
mode:
authorRobin Krahl <robin.krahl@ireas.org>2020-01-07 11:18:04 +0000
committerDaniel Mueller <deso@posteo.net>2020-01-08 09:20:25 -0800
commit5e20a29b4fdc8a2d442d1093681b396dcb4b816b (patch)
tree55ab083fa8999d2ccbb5e921c1ffe52560dca152 /structopt/tests/custom-string-parsers.rs
parent203e691f46d591a2cc8acdfd850fa9f5b0fb8a98 (diff)
downloadnitrocli-5e20a29b4fdc8a2d442d1093681b396dcb4b816b.tar.gz
nitrocli-5e20a29b4fdc8a2d442d1093681b396dcb4b816b.tar.bz2
Add structopt dependency in version 0.3.7
This patch series replaces argparse with structopt in the argument handling code. As a first step, we need structopt as a dependency. Import subrepo structopt/:structopt at efbdda4753592e27bc430fb01f7b9650b2f3174d Import subrepo bitflags/:bitflags at 30668016aca6bd3b02c766e8347e0b4080d4c296 Import subrepo clap/:clap at 784524f7eb193e35f81082cc69454c8c21b948f7 Import subrepo heck/:heck at 093d56fbf001e1506e56dbfa38631d99b1066df1 Import subrepo proc-macro-error/:proc-macro-error at 6c4cfe79a622c5de8ae68557993542be46eacae2 Import subrepo proc-macro2/:proc-macro2 at d5d48eddca4566e5438e8a2cbed4a74e049544de Import subrepo quote/:quote at 727436c6c137b20f0f34dde5d8fda2679b9747ad Import subrepo rustversion/:rustversion at 0c5663313516263059ce9059ef81fc7a1cf655ca Import subrepo syn-mid/:syn-mid at 5d3d85414a9e6674e1857ec22a87b96e04a6851a Import subrepo syn/:syn at e87c27e87f6f4ef8919d0372bdb056d53ef0d8f3 Import subrepo textwrap/:textwrap at abcd618beae3f74841032aa5b53c1086b0a57ca2 Import subrepo unicode-segmentation/:unicode-segmentation at 637c9874c4fe0c205ff27787faf150a40295c6c3 Import subrepo unicode-width/:unicode-width at 3033826f8bf05e82724140a981d5941e48fce393 Import subrepo unicode-xid/:unicode-xid at 4baae9fffb156ba229665b972a9cd5991787ceb7
Diffstat (limited to 'structopt/tests/custom-string-parsers.rs')
-rw-r--r--structopt/tests/custom-string-parsers.rs306
1 files changed, 306 insertions, 0 deletions
diff --git a/structopt/tests/custom-string-parsers.rs b/structopt/tests/custom-string-parsers.rs
new file mode 100644
index 0000000..89070ed
--- /dev/null
+++ b/structopt/tests/custom-string-parsers.rs
@@ -0,0 +1,306 @@
+// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use structopt::StructOpt;
+
+use std::ffi::{CString, OsStr, OsString};
+use std::num::ParseIntError;
+use std::path::PathBuf;
+
+#[derive(StructOpt, PartialEq, Debug)]
+struct PathOpt {
+ #[structopt(short, long, parse(from_os_str))]
+ path: PathBuf,
+
+ #[structopt(short, default_value = "../", parse(from_os_str))]
+ default_path: PathBuf,
+
+ #[structopt(short, parse(from_os_str))]
+ vector_path: Vec<PathBuf>,
+
+ #[structopt(short, parse(from_os_str))]
+ option_path_1: Option<PathBuf>,
+
+ #[structopt(short = "q", parse(from_os_str))]
+ option_path_2: Option<PathBuf>,
+}
+
+#[test]
+fn test_path_opt_simple() {
+ assert_eq!(
+ PathOpt {
+ path: PathBuf::from("/usr/bin"),
+ default_path: PathBuf::from("../"),
+ vector_path: vec![
+ PathBuf::from("/a/b/c"),
+ PathBuf::from("/d/e/f"),
+ PathBuf::from("/g/h/i"),
+ ],
+ option_path_1: None,
+ option_path_2: Some(PathBuf::from("j.zip")),
+ },
+ PathOpt::from_clap(&PathOpt::clap().get_matches_from(&[
+ "test", "-p", "/usr/bin", "-v", "/a/b/c", "-v", "/d/e/f", "-v", "/g/h/i", "-q",
+ "j.zip",
+ ]))
+ );
+}
+
+fn parse_hex(input: &str) -> Result<u64, ParseIntError> {
+ u64::from_str_radix(input, 16)
+}
+
+#[derive(StructOpt, PartialEq, Debug)]
+struct HexOpt {
+ #[structopt(short, parse(try_from_str = parse_hex))]
+ number: u64,
+}
+
+#[test]
+#[allow(clippy::unreadable_literal)]
+fn test_parse_hex() {
+ assert_eq!(
+ HexOpt { number: 5 },
+ HexOpt::from_clap(&HexOpt::clap().get_matches_from(&["test", "-n", "5"]))
+ );
+ assert_eq!(
+ HexOpt { number: 0xabcdef },
+ HexOpt::from_clap(&HexOpt::clap().get_matches_from(&["test", "-n", "abcdef"]))
+ );
+
+ let err = HexOpt::clap()
+ .get_matches_from_safe(&["test", "-n", "gg"])
+ .unwrap_err();
+ assert!(err.message.contains("invalid digit found in string"), err);
+}
+
+fn custom_parser_1(_: &str) -> &'static str {
+ "A"
+}
+fn custom_parser_2(_: &str) -> Result<&'static str, u32> {
+ Ok("B")
+}
+fn custom_parser_3(_: &OsStr) -> &'static str {
+ "C"
+}
+fn custom_parser_4(_: &OsStr) -> Result<&'static str, OsString> {
+ Ok("D")
+}
+
+#[derive(StructOpt, PartialEq, Debug)]
+struct NoOpOpt {
+ #[structopt(short, parse(from_str = custom_parser_1))]
+ a: &'static str,
+ #[structopt(short, parse(try_from_str = custom_parser_2))]
+ b: &'static str,
+ #[structopt(short, parse(from_os_str = custom_parser_3))]
+ c: &'static str,
+ #[structopt(short, parse(try_from_os_str = custom_parser_4))]
+ d: &'static str,
+}
+
+#[test]
+fn test_every_custom_parser() {
+ assert_eq!(
+ NoOpOpt {
+ a: "A",
+ b: "B",
+ c: "C",
+ d: "D"
+ },
+ NoOpOpt::from_clap(
+ &NoOpOpt::clap().get_matches_from(&["test", "-a=?", "-b=?", "-c=?", "-d=?"])
+ )
+ );
+}
+
+// Note: can't use `Vec<u8>` directly, as structopt would instead look for
+// conversion function from `&str` to `u8`.
+type Bytes = Vec<u8>;
+
+#[derive(StructOpt, PartialEq, Debug)]
+struct DefaultedOpt {
+ #[structopt(short, parse(from_str))]
+ bytes: Bytes,
+
+ #[structopt(short, parse(try_from_str))]
+ integer: u64,
+
+ #[structopt(short, parse(from_os_str))]
+ path: PathBuf,
+}
+
+#[test]
+fn test_parser_with_default_value() {
+ assert_eq!(
+ DefaultedOpt {
+ bytes: b"E\xc2\xb2=p\xc2\xb2c\xc2\xb2+m\xc2\xb2c\xe2\x81\xb4".to_vec(),
+ integer: 9000,
+ path: PathBuf::from("src/lib.rs"),
+ },
+ DefaultedOpt::from_clap(&DefaultedOpt::clap().get_matches_from(&[
+ "test",
+ "-b",
+ "E²=p²c²+m²c⁴",
+ "-i",
+ "9000",
+ "-p",
+ "src/lib.rs",
+ ]))
+ );
+}
+
+#[derive(PartialEq, Debug)]
+struct Foo(u8);
+
+fn foo(value: u64) -> Foo {
+ Foo(value as u8)
+}
+
+#[derive(StructOpt, PartialEq, Debug)]
+struct Occurrences {
+ #[structopt(short, long, parse(from_occurrences))]
+ signed: i32,
+
+ #[structopt(short, parse(from_occurrences))]
+ little_signed: i8,
+
+ #[structopt(short, parse(from_occurrences))]
+ unsigned: usize,
+
+ #[structopt(short = "r", parse(from_occurrences))]
+ little_unsigned: u8,
+
+ #[structopt(short, long, parse(from_occurrences = foo))]
+ custom: Foo,
+}
+
+#[test]
+fn test_parser_occurrences() {
+ assert_eq!(
+ Occurrences {
+ signed: 3,
+ little_signed: 1,
+ unsigned: 0,
+ little_unsigned: 4,
+ custom: Foo(5),
+ },
+ Occurrences::from_clap(&Occurrences::clap().get_matches_from(&[
+ "test", "-s", "--signed", "--signed", "-l", "-rrrr", "-cccc", "--custom",
+ ]))
+ );
+}
+
+#[test]
+fn test_custom_bool() {
+ fn parse_bool(s: &str) -> Result<bool, String> {
+ match s {
+ "true" => Ok(true),
+ "false" => Ok(false),
+ _ => Err(format!("invalid bool {}", s)),
+ }
+ }
+ #[derive(StructOpt, PartialEq, Debug)]
+ struct Opt {
+ #[structopt(short, parse(try_from_str = parse_bool))]
+ debug: bool,
+ #[structopt(
+ short,
+ default_value = "false",
+ parse(try_from_str = parse_bool)
+ )]
+ verbose: bool,
+ #[structopt(short, parse(try_from_str = parse_bool))]
+ tribool: Option<bool>,
+ #[structopt(short, parse(try_from_str = parse_bool))]
+ bitset: Vec<bool>,
+ }
+
+ assert!(Opt::clap().get_matches_from_safe(&["test"]).is_err());
+ assert!(Opt::clap().get_matches_from_safe(&["test", "-d"]).is_err());
+ assert!(Opt::clap()
+ .get_matches_from_safe(&["test", "-dfoo"])
+ .is_err());
+ assert_eq!(
+ Opt {
+ debug: false,
+ verbose: false,
+ tribool: None,
+ bitset: vec![],
+ },
+ Opt::from_iter(&["test", "-dfalse"])
+ );
+ assert_eq!(
+ Opt {
+ debug: true,
+ verbose: false,
+ tribool: None,
+ bitset: vec![],
+ },
+ Opt::from_iter(&["test", "-dtrue"])
+ );
+ assert_eq!(
+ Opt {
+ debug: true,
+ verbose: false,
+ tribool: None,
+ bitset: vec![],
+ },
+ Opt::from_iter(&["test", "-dtrue", "-vfalse"])
+ );
+ assert_eq!(
+ Opt {
+ debug: true,
+ verbose: true,
+ tribool: None,
+ bitset: vec![],
+ },
+ Opt::from_iter(&["test", "-dtrue", "-vtrue"])
+ );
+ assert_eq!(
+ Opt {
+ debug: true,
+ verbose: false,
+ tribool: Some(false),
+ bitset: vec![],
+ },
+ Opt::from_iter(&["test", "-dtrue", "-tfalse"])
+ );
+ assert_eq!(
+ Opt {
+ debug: true,
+ verbose: false,
+ tribool: Some(true),
+ bitset: vec![],
+ },
+ Opt::from_iter(&["test", "-dtrue", "-ttrue"])
+ );
+ assert_eq!(
+ Opt {
+ debug: true,
+ verbose: false,
+ tribool: None,
+ bitset: vec![false, true, false, false],
+ },
+ Opt::from_iter(&["test", "-dtrue", "-bfalse", "-btrue", "-bfalse", "-bfalse"])
+ );
+}
+
+#[test]
+fn test_cstring() {
+ #[derive(StructOpt)]
+ struct Opt {
+ #[structopt(parse(try_from_str = CString::new))]
+ c_string: CString,
+ }
+ assert!(Opt::clap().get_matches_from_safe(&["test"]).is_err());
+ assert_eq!(Opt::from_iter(&["test", "bla"]).c_string.to_bytes(), b"bla");
+ assert!(Opt::clap()
+ .get_matches_from_safe(&["test", "bla\0bla"])
+ .is_err());
+}