elm-codec icon indicating copy to clipboard operation
elm-codec copied to clipboard

How to validate data from optional fields?

Open n1k0 opened this issue 3 years ago • 3 comments

Hello, thanks for the great library!

I’m struggling with optional field data validation; Trying maybeField:

> import Codec
> type alias Foo =
|       { foo : Maybe String }
|
> test =
|       Codec.object Foo
|           |> Codec.maybeField "foo" .foo Codec.string
|           |> Codec.buildObject
|
Codec { decoder = <internals>, encoder = <function> }
    : Codec { foo : Maybe String }
> """{"foo": "plop"}""" |> Codec.decodeString test
Ok { foo = Just "plop" }
    : Result Codec.Error { foo : Maybe String }
> """{"foo": 123}""" |> Codec.decodeString test
Ok { foo = Nothing }
    : Result Codec.Error { foo : Maybe String }

And nullableField:

> test2 =
|       Codec.object Foo
|           |> Codec.nullableField "foo" .foo Codec.string
|           |> Codec.buildObject
|
Codec { decoder = <internals>, encoder = <function> }
    : Codec { foo : Maybe String }
> """{"foo": "plop"}""" |> Codec.decodeString test2
Ok { foo = Just "plop" }
    : Result Codec.Error { foo : Maybe String }
> """{"foo": 123}""" |> Codec.decodeString test2
Ok { foo = Nothing }
    : Result Codec.Error { foo : Maybe String }

I'd expect one of these to fail with an error when passing an Int where a String is expected, like what Json.Decode.Extra's optionalNullableField does for instance. I'm also struggling as to how could I implement a Codec doing just that, while having no access to the package internals… Any help appreciated!

Thanks

n1k0 avatar Jul 16 '22 22:07 n1k0

You could use Codec.value and then validate with a nested call to Codec.decodeValue. ... not ideal, no. Let me know if you need more details on how to actually do it

Honestly, maybeField should behave like the optionalNullableField you linked to, but the issue is that it would be a breaking change so... I may add another function to do that?

I should probably also improve the docs :thinking:

miniBill avatar Jul 16 '22 23:07 miniBill

Another option is to just go for build and write your encoders and decoders for that specific type, but that's also not ideal

miniBill avatar Jul 16 '22 23:07 miniBill

Honestly, maybeField should behave like the optionalNullableField you linked to, but the issue is that it would be a breaking change so... I may add another function to do that? I should probably also improve the docs 🤔

Yes, I think having an option to validate optional data would be a great benefit to the lib! I also agree that documenting the limitation of the current implementation is important, as it might create really bad surprises to developers…

I think a new function would be great, the most difficult part being — as always — finding a good name for it… maybeFieldStrict, maybeFieldWithValidation? Haha, hell… /o\

Another option is to just go for build and write your encoders and decoders for that specific type

That's what I'm doing meanwhile, but imho there should be some builtin function to do just that :)

Thanks again for your help

n1k0 avatar Jul 17 '22 09:07 n1k0