diff --git a/gleam.toml b/gleam.toml index 9ab4a57..5b9ee6d 100644 --- a/gleam.toml +++ b/gleam.toml @@ -1,5 +1,5 @@ name = "clad" -version = "0.2.1" +version = "0.3.0" # Fill out these fields if you intend to generate HTML documentation or publish # your project to the Hex package manager. diff --git a/src/clad.gleam b/src/clad.gleam index a29390f..89bfecc 100644 --- a/src/clad.gleam +++ b/src/clad.gleam @@ -152,7 +152,6 @@ //// ``` import decode/zero.{type Decoder} -import gleam/bool import gleam/dict.{type Dict} import gleam/dynamic.{type Dynamic} import gleam/float @@ -239,10 +238,16 @@ pub fn positional_arguments( /// let result = clad.decode([], decoder) /// assert result == Ok(False) /// ``` -pub fn flag() -> Decoder(Bool) { - zero.bool - |> zero.optional - |> zero.map(option.unwrap(_, False)) +pub fn flag( + long_name: String, + short_name: String, + next: fn(Bool) -> Decoder(final), +) -> Decoder(final) { + use value <- optional_field(long_name, zero.bool) + case value { + Some(v) -> next(v) + None -> zero.optional_field(short_name, False, zero.bool, next) + } } fn optional_field( @@ -250,23 +255,24 @@ fn optional_field( field_decoder: Decoder(t), next: fn(Option(t)) -> Decoder(final), ) -> Decoder(final) { - let decoding_function = fn(data: Dynamic) { - use <- bool.guard(dynamic.classify(data) == "Nil", Ok(None)) + zero.optional_field(field_name, None, zero.optional(field_decoder), next) + // let decoding_function = fn(data: Dynamic) { + // use <- bool.guard(dynamic.classify(data) == "Nil", Ok(None)) - case zero.run(data, zero.optional(field_decoder)) { - Ok(None) -> { - case zero.run(data, field_decoder) { - Ok(v) -> Ok(Some(v)) - Error(_) -> Ok(None) - } - } - other -> other - } - } + // case zero.run(data, zero.optional(field_decoder)) { + // Ok(None) -> { + // case zero.run(data, field_decoder) { + // Ok(v) -> Ok(Some(v)) + // Error(_) -> Ok(None) + // } + // } + // other -> other + // } + // } - let decoder = zero.new_primitive_decoder(decoding_function, None) + // let decoder = zero.new_primitive_decoder(decoding_function, None) - zero.field(field_name, decoder, next) + // zero.field(field_name, decoder, next) } /// Decode a command line option by either a long name or short name diff --git a/test/clad_test.gleam b/test/clad_test.gleam index 353ade7..d63e239 100644 --- a/test/clad_test.gleam +++ b/test/clad_test.gleam @@ -1,7 +1,6 @@ import clad import decode/zero import gleam/dynamic.{DecodeError} -import gleam/option.{None, Some} import gleeunit import gleeunit/should @@ -26,11 +25,11 @@ pub fn decode_test() { |> clad.decode(["-b", "1"], _) |> should.equal(Ok(1)) - zero.field("z", clad.flag(), zero.success) + clad.flag("baz", "z", zero.success) |> clad.decode(["-z"], _) |> should.equal(Ok(True)) - zero.field("z", clad.flag(), zero.success) + clad.flag("baz", "z", zero.success) |> clad.decode([], _) |> should.equal(Ok(False)) @@ -45,7 +44,7 @@ pub fn decode_test() { let decoder = { use foo <- clad.opt("foo", "f", zero.string) use bar <- clad.opt("bar", "b", zero.int) - use baz <- clad.opt("baz", "z", clad.flag()) + use baz <- clad.flag("baz", "z") use qux <- clad.opt("qux", "q", zero.float) use names <- clad.positional_arguments zero.success(Options(foo:, bar:, baz:, qux:, names:)) @@ -82,7 +81,7 @@ pub fn decode_test() { pub fn decode_errors_test() { zero.field("f", zero.string, zero.success) |> clad.decode(["--bar", "hello"], _) - |> should.equal(Error([DecodeError("String", "Nil", ["f"])])) + |> should.equal(Error([DecodeError("Field", "Nothing", ["f"])])) zero.field("foo", zero.string, zero.success) |> clad.decode(["--foo", "1"], _) @@ -91,7 +90,7 @@ pub fn decode_errors_test() { let decoder = { use foo <- clad.opt("foo", "f", zero.string) use bar <- clad.opt("bar", "b", zero.int) - use baz <- clad.opt("baz", "z", clad.flag()) + use baz <- clad.flag("baz", "z") use qux <- clad.opt("qux", "q", zero.float) use names <- clad.positional_arguments zero.success(Options(foo:, bar:, baz:, qux:, names:)) @@ -102,9 +101,9 @@ pub fn decode_errors_test() { clad.decode(args, decoder) |> should.equal( Error([ - DecodeError("String", "Nil", ["f"]), - DecodeError("Int", "Nil", ["b"]), - DecodeError("Float", "Nil", ["q"]), + DecodeError("Field", "Nothing", ["f"]), + DecodeError("Field", "Nothing", ["b"]), + DecodeError("Field", "Nothing", ["q"]), ]), ) @@ -113,8 +112,8 @@ pub fn decode_errors_test() { clad.decode(args, decoder) |> should.equal( Error([ - DecodeError("String", "Nil", ["f"]), - DecodeError("Float", "Nil", ["q"]), + DecodeError("Field", "Nothing", ["f"]), + DecodeError("Field", "Nothing", ["q"]), ]), ) @@ -122,7 +121,10 @@ pub fn decode_errors_test() { let args = ["--foo", "hello"] clad.decode(args, decoder) |> should.equal( - Error([DecodeError("Int", "Nil", ["b"]), DecodeError("Float", "Nil", ["q"])]), + Error([ + DecodeError("Field", "Nothing", ["b"]), + DecodeError("Field", "Nothing", ["q"]), + ]), ) // wrong type @@ -131,7 +133,7 @@ pub fn decode_errors_test() { |> should.equal( Error([ DecodeError("Int", "String", ["b"]), - DecodeError("Float", "Nil", ["q"]), + DecodeError("Field", "Nothing", ["q"]), ]), ) } @@ -144,25 +146,25 @@ pub fn opt_test() { clad.opt("foo", "f", zero.string, zero.success) |> clad.decode(["-f", "hello"], _) |> should.equal(Ok("hello")) + // clad.opt("foo", "f", zero.string, zero.success) + // |> clad.decode([], _) + // |> should.equal(Error([DecodeError("String", "Nothing", ["f"])])) - clad.opt("foo", "f", zero.string, zero.success) - |> clad.decode([], _) - |> should.equal(Error([DecodeError("String", "Nil", ["f"])])) - - clad.opt("foo", "f", zero.optional(zero.string), zero.success) - |> clad.decode(["-f", "hello"], _) - |> should.equal(Ok(Some("hello"))) + // clad.opt("foo", "f", zero.optional(zero.string), zero.success) + // |> clad.decode(["-f", "hello"], _) + // |> should.equal(Ok(Some("hello"))) - clad.opt("foo", "f", zero.optional(zero.string), zero.success) - |> clad.decode([], _) - |> should.equal(Ok(None)) + // clad.opt("foo", "f", zero.optional(zero.string), zero.success) + // |> clad.decode([], _) + // |> should.equal(Ok(None)) } pub fn flag_test() { let decoder = { - use verbose <- zero.field("v", clad.flag()) + use verbose <- clad.flag("verbose", "v") zero.success(verbose) } + clad.decode(["-v"], decoder) |> should.equal(Ok(True)) @@ -181,7 +183,7 @@ pub fn flag_test() { pub fn positional_arguments_test() { let decoder = { - use a <- zero.field("a", clad.flag()) + use a <- zero.field("a", zero.bool) use b <- zero.field("b", zero.int) use c <- clad.positional_arguments() zero.success(#(a, b, c)) diff --git a/test/examples/student.gleam b/test/examples/student.gleam index ebf2f43..35c2023 100644 --- a/test/examples/student.gleam +++ b/test/examples/student.gleam @@ -17,7 +17,7 @@ pub fn main() { let decoder = { use name <- clad.opt("name", "n", zero.string) use age <- clad.opt("age", "a", zero.int) - use enrolled <- clad.opt("enrolled", "e", clad.flag()) + use enrolled <- clad.flag("enrolled", "e") use classes <- clad.opt("class", "c", clad.list(zero.string)) use notes <- clad.positional_arguments() let notes = string.join(notes, " ")