Comments (5)
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.
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.
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.
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.
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)
- Waargonaut.Decode.either's document or implementation maybe wrong HOT 1
- CommaSeparated's _Empty Prism doesn't obey Prism law
- Default / example parser? HOT 2
- Restrictive upper bounds for generics-sop-0.40.1 HOT 2
- Encoder mapLikeObj API thoughts HOT 1
- Uppercase HeXDigit's aren't interpreted correctly
- JSON unicode strings should be parsed into... well, unicode.
- Help: Prettier HOT 3
- Changing compiler via nix doesn't apply overlays
- Upgrade to latest hw-json
- documentation incorrect
- _optionsFieldName is called twice when generating an encoding using Waargonaut.Generic.gEncoder HOT 1
- Fix CI for GHC 8.0.2 HOT 1
- ByteString.Char8 encoder HOT 6
- GHC 8.10 support? HOT 2
- Nix build is stale HOT 4
- Not available in Stackage
- Conversion of Scientific to JNumber computes an incorrect exponent
- Still not available on Stackage
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from waargonaut.