浏览代码

test/docs: custom parser definitions

Sam Jaffe 2 年之前
父节点
当前提交
e6c3418b64
共有 2 个文件被更改,包括 57 次插入0 次删除
  1. 18 0
      README.md
  2. 39 0
      test/options_test.cpp

+ 18 - 0
README.md

@@ -41,6 +41,24 @@ $ ./a.out --bounds 1920 1080
 [ "1080" ]
 ```
 
+### Custom Parsers
+You can, however, include custom types in your program arguments.
+```c++
+struct dim2 { int x, y; };
+
+template <> struct string_utils::cast_helper<dim2> {
+  bool operator()(std::string_view str, dim2 & to) const noexcept {
+    return sscanf(str.data(), "%dx%d", &to.x, &to.y) == 2;
+  }
+};
+
+dim2 bounds = options("bounds");
+std::cout << bounds.x << " by " << bounds.y << std::endl;
+
+$ ./a.out --bounds 1920x1080
+1920 by 1080
+```
+
 ### Flags
 Flags are a sub-class of options who do not have a follow-on value, but instead change the state of the given object through being called.
 

+ 39 - 0
test/options_test.cpp

@@ -230,3 +230,42 @@ TEST(GeneratedDefaultTest, CanReferenceThis) {
   EXPECT_THAT(options.pwd, "/opt/local/bin");
   EXPECT_THAT(options.git_dir, "/opt/local/bin/.git");
 }
+
+struct CompoundOptionsTest : program::Arguments<CompoundOptionsTest> {
+  using Arguments::Arguments;
+  std::pair<int, int> screen_size =
+      std::make_pair(option("width"), option("height"));
+};
+
+TEST(CompoundOptionsTest, CanBindTupleElements) {
+  auto const options =
+      parse<CompoundOptionsTest>({"", "--width", "1920", "--height", "1080"});
+  EXPECT_THAT(options.screen_size.first, 1920);
+  EXPECT_THAT(options.screen_size.second, 1080);
+}
+
+struct dim2 {
+  int x, y;
+};
+
+template <> struct string_utils::cast_helper<dim2> {
+  bool operator()(std::string_view str, dim2 & out) {
+    return sscanf(str.data(), "%dx%d", &out.x, &out.y) == 2;
+  }
+};
+
+struct ParsedOptionTest : program::Arguments<ParsedOptionTest> {
+  using Arguments::Arguments;
+  dim2 screen_size = option("screen");
+};
+
+TEST(ParsedOptionTest, CanInvokeSpecialParser) {
+  auto const options = parse<ParsedOptionTest>({"", "--screen", "1920x1080"});
+  EXPECT_THAT(options.screen_size.x, 1920);
+  EXPECT_THAT(options.screen_size.y, 1080);
+}
+
+TEST(ParsedOptionTest, SpecialParserCanFail) {
+  EXPECT_THROW(parse<ParsedOptionTest>({"", "--screen", "1920"}),
+               program::ArgumentStructureError);
+}