Proper JsonObjCodec with Fleece for Complex, Nested Discriminated Unions Proper JsonObjCodec with Fleece for Complex, Nested Discriminated Unions json json

Proper JsonObjCodec with Fleece for Complex, Nested Discriminated Unions


The Problem

Fleece provides Json codecs, not string codecs, so defining ToString and FromString is not the way to go, unless you need them for other stuff.

The solution

Define ToJson and OfJson for your internal DUs. Then remove all the |> string fragments in JsonObjCodec body.

Here's a quick and dirty example (I advise error handling to be improved) for Comparator :

    static member ToJson x = JString (string x)    static member OfJson x =        match x with        | JString x -> Ok (Comparator.FromString x)        | _ -> Error (Uncategorized "JString expected")

Alternative solution

Leave all your internal DUs like this, but add the missing "parse" section in your JsonObjCodec:

    ...    with    static member JsonObjCodec =        (fun (a, b) -> Age (Comparator.FromString a, AgeMeasure.FromString b)) <!> jreq "Age" (function Age (comp, ageMeasure) -> Some (comp |> string, ageMeasure |> string) | _ -> None)    <|> ...

this becomes a bit verbose but will do the job.

Tips

  • Instead of using the <|> operator to add codecs, you colud use the jchoice combinator, it will read better.

  • If you really need your String / FromString methods I would suggest renaming FromString to Parse or renaming it to TryParse and returning an option type. This way you can take advantage of FSharpPlus tryParse function.

  • Also, if you are using the string/parse pattern everywhere it might worth to create a codec combinator that works from transforming to/from strings. This is not an easy task but it might worth the mental effort.

  • For debugging stuff like this purpose, try not to open the namespace FSharpPlus as it contains generic definitions of operators like <|>, <!> and <*>, this way you'll get better compile error messages.