diff --git a/tests/ObjectCodec.fs b/tests/ObjectCodec.fs index a42d9c9..fdb1eb1 100644 --- a/tests/ObjectCodec.fs +++ b/tests/ObjectCodec.fs @@ -31,6 +31,8 @@ type Large = Baz : Guid } +type Baz = { Baz : string option } + module Codec = let fooBar : Codec = @@ -73,6 +75,13 @@ module Codec = } } + let baz : Codec = + objectCodec { + let! baz = Codec.optional "baz" (fun x -> x.Baz) Codec.string + + return { Baz = baz } + } + let tests = testList "ObjectCodec" @@ -118,4 +127,19 @@ let tests = Expect.equal actual expected "The decoded value must match the original" } + + test "objectCodec optional field works" { + let withValue = { Baz = Some "abc" } + + let withoutValue = { Baz = None } + + let actualWithValue = + roundTrip Codec.baz withValue + + let actualWithoutValue = + roundTrip Codec.baz withoutValue + + Expect.equal actualWithValue withValue "The decoded Some value must match the original" + Expect.equal actualWithoutValue withoutValue "The decoded None value must match the original" + } ] diff --git a/thoth-json-codec/Object.fs b/thoth-json-codec/Object.fs index 853fee4..a9f2095 100644 --- a/thoth-json-codec/Object.fs +++ b/thoth-json-codec/Object.fs @@ -49,3 +49,17 @@ module ObjectCodecComputationExpression = Decoder = Decode.field fieldName fieldCodec.Decoder Picker = picker } + + let optional + (fieldName : string) + (picker : 'u -> 't option) + (fieldCodec : Codec<'t>) + : ObjectCodecFieldSet<'t option, 'u> = + { + Values = + function + | Some i -> [ fieldName, fieldCodec.Encoder i ] + | None -> [] + Decoder = Decode.optional fieldName fieldCodec.Decoder + Picker = picker + }