Coder Social home page Coder Social logo

Comments (5)

mankyKitty avatar mankyKitty commented on July 22, 2024 1

You can use either maybeOrNull or maybe. These can be combined in a few different ways to handle optional fields, as well as optional values. Some examples are here, but they might take a bit of squinting. :)

You can pattern match on the constructors like you have in the encodePropertyType function to be able to decide which of the Property constructors you want to encode. An alternative might be to have something like the following:

data FancyProperty = FancyProperty {
    total :: Int
    average :: Int
    required :: Bool
  }

data BaseProperty = BaseProperty {
    name :: Text,
    description :: Text,
    fancyProperties :: Maybe FancyProperty
  }

I tend to avoid records in sum types as it can become troublesome.

from waargonaut.

treffynnon avatar treffynnon commented on July 22, 2024

I've ended up with this using the original record sum type:

encodeProperty :: Applicative f => WE.Encoder f J.Property
encodeProperty = WE.mapLikeObj $ \jss ->
  encodeProperty' jss .
  WE.textAt "name" (name jss) .
  WE.textAt "description" (J.description jss)

encodeProperty' :: Property -> WT.MapLikeObj WT.WS WT.Json -> WT.MapLikeObj WT.WS WT.Json
encodeProperty' jss@(SomeProperty {}) =
  WE.textAt "type" "some"
encodeProperty' jss@(FancyProperty {}) =
  WE.textAt "type" "fancy" .
  maybe id (WE.boolAt "required") (required jss)

from waargonaut.

mankyKitty avatar mankyKitty commented on July 22, 2024

You've plenty of options for how you choose to encode this, which is kind of the point of the library. :)

Some alternatives:

encodePropertyA :: Applicative f => E.Encoder f Property
encodePropertyA = E.mapLikeObj $ \case
  SomeProperty nm desc ->
    baseObj "some" nm desc

  FancyProperty nm desc tot avg reqd ->
    baseObj "fancy" nm desc

    . E.atKey' "total" (E.maybeOrNull E.int) tot
    . E.atKey' "average" (E.maybeOrNull E.int) avg
    . E.atKey' "required" (E.maybeOrNull E.bool)reqd

  where
    baseObj t n d =
        E.textAt "type" t
      . E.textAt "name" n
      . E.textAt "desc" d

encodePropertyB :: Monad f => E.Encoder f Property
encodePropertyB = E.encodeA $ \p -> E.extendMapLikeObject baseObj p $
  case p of
    SomeProperty _ _ -> E.atKey' "type" E.text "some"

    FancyProperty _ _ tot avg reqd ->
        E.atKey' "type" E.text "fancy"
      . E.atKey' "total" (E.maybeOrNull E.int) tot
      . E.atKey' "average" (E.maybeOrNull E.int) avg
      . E.atKey' "required" (E.maybeOrNull E.bool)reqd

  where
    baseObj = E.objEncoder $ \p ->
      E.onObj "name" (name p) E.text mempty >>=
      E.onObj "description" (description p) E.text

from waargonaut.

treffynnon avatar treffynnon commented on July 22, 2024

Thank you for including the example code. In my case I wanted to have the key entirely absent from the object if the value was Nothing rather than provide a default or null. I am writing a little utility to produce JSON Schema files for the input parameters of a set of MS SQL stored procedures.

from waargonaut.

mankyKitty avatar mankyKitty commented on July 22, 2024

Waargonaut should be able to support that as well, although giving it a quick poke it is not as straight-forward as I remember.

I might have to play with that and see what falls out, because having the option of either optional values, or optional key:value pairs is definitely a thing that needs to exist.

Also if you work it out and want to point out the bits that didn't work or could be generalised then I'm all ears. 👍

from waargonaut.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.