Skip to content

Conversation

@m-bock
Copy link
Contributor

@m-bock m-bock commented Nov 25, 2024

Let's say we have a PureScript Sum type, each case has either no fields or a single record field:

data Sample
  = Foo
  | Bar { errors  Int }
  | Baz { active  Boolean, name  String, count  Int }

This PR introduces two new functions : sumFlat and sumFlatWith. They works similar to sum and sumWIth.
However for each constructor a JPropCodec (or unit) must be provided.

sumFlat uses a default encoding, whereas sumFlat can be passed custom encoding options.

In the custom options a type level symbol can be given that represents a case discriminator in the JSON. (usually "type", "kind", "tag"...)

import Data.Codec.Argonaut as C
import Data.Codec.Argonaut.Record as CR
import Data.Codec.Argonaut.Sum as CS

codecSample  JsonCodec Sample
codecSample = CS.sumFlatWith { tag: Proxy @"tag"} "Sample"
  { "Foo": unit
  , "Bar": CR.record { errors: C.int }
  , "Baz": CR.record { active: C.boolean, name: C.string, count: C.int }
  }

This codec can then be used as usual:

C.encode codecSample (Baz { active: true, name: "hello", count: 42 })

It will encode as follows:

{
  "tag": "Baz",
  "active": true,
  "count": 42,
  "name": "hello"
}

It's verified at compile time that the record fields don't conflict with the custom tag. So in this example, if you exchange "name" with "tag" in the type definition, the compilation will fail.

@garyb
Copy link
Owner

garyb commented Nov 26, 2024

Awesome, this looks great. Thanks so much for working on it!

@garyb garyb merged commit 368fc25 into garyb:master Nov 26, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants