Skip to content

A different way to store custom types in JSON #17

@lucamug

Description

@lucamug

More a comment than an issue.

I wanted to remove the "tag" and "args" from inside the JSON output.

So I changed a couple of functions and now instead of generating this JSON
(for Red 42 Ciao as per the example in the README)

{
  "args": [
    42,
    "Ciao"
  ],
  "tag": "Red"
}

it generates this:

{
  "Red": [
    42,
    "Ciao"
  ]
}

I wonder if this has been considered as an option and if there are any concerns
about generating this type of JSON.

These are the functions that I modified to achieve this (I commented out the removed code for comparison)

variant :
    String
    -> ((List Value -> Value) -> a)
    -> Decoder v
    -> CustomCodec (a -> b) v
    -> CustomCodec b v
variant name matchPiece decoderPiece (CustomCodec am) =
    let
        enc v =
            JE.object
                -- [ ( "tag", JE.string name )
                -- , ( "args", JE.list identity v )
                -- ]
                [ ( name, JE.list identity v )
                ]
    in
    CustomCodec
        { match = am.match <| matchPiece enc
        , decoder = Dict.insert name decoderPiece am.decoder
        }

buildCustom : CustomCodec (a -> Value) a -> Codec a
buildCustom (CustomCodec am) =
    Codec
        { encoder = \v -> am.match v
        , decoder =
            -- JD.field "tag" JD.string
            --     |> JD.andThen
            --         (\tag ->
            --             case Dict.get tag am.decoder of
            --                 Nothing ->
            --                     JD.fail <| "tag " ++ tag ++ "did not match"
            --
            --                 Just dec ->
            --                     JD.field "args" dec
            --         )
            JD.oneOf
                (List.map
                    (\( tag, dec ) -> JD.field tag dec)
                    (Dict.toList am.decoder)
                )
        }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions