Skip to content

Instantly share code, notes, and snippets.

@osfameron
Last active September 1, 2020 11:28
Show Gist options
  • Save osfameron/880b43305d957035dc165a5db812ac45 to your computer and use it in GitHub Desktop.
Save osfameron/880b43305d957035dc165a5db812ac45 to your computer and use it in GitHub Desktop.
Better API for Json passthrough
module JsonTest where
import Prelude (bind, pure, ($), (=<<))
import Data.Argonaut.Core (Json, fromObject, stringify, toObject)
import Data.Argonaut.Decode (JsonDecodeError(..), decodeJson, parseJson)
import Data.Argonaut.Encode (encodeJson)
import Data.Either (Either, note)
import Foreign.Object as O
import Data.Tuple (Tuple(..))
type Foo = { foo :: String, bar :: Number | WithJsonPassthrough }
decodeFoo :: Json -> Either JsonDecodeError Foo
decodeFoo = decodeJson
type WithJsonPassthrough = ( _json :: Json )
j :: String
j = """{"foo":"Hello","bar":1.0,"baz":"extra"}"""
addPassthrough :: Json -> Either JsonDecodeError Json
addPassthrough json = do
obj <- note (TypeMismatch "Json is not an object") $ toObject json
let obj' = O.insert "_json" json obj
pure $ fromObject obj'
mergePassthrough :: Json -> Either JsonDecodeError Json
mergePassthrough json = do
obj <- note (TypeMismatch "Json is not an object") $ toObject json
(Tuple json' obj') <- note MissingValue $ O.pop "_json" obj
orig <- note (TypeMismatch "_json is not an object") $ toObject json'
let merged = O.union obj' orig
pure $ fromObject merged
process :: String -> Either JsonDecodeError String
process s =
do
decoded <- decodeFoo =<< addPassthrough =<< parseJson s
let updated = decoded { foo = "Updated", bar = 2.0 }
encoded <- mergePassthrough $ encodeJson updated
pure $ stringify encoded
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment