Skip to content

Instantly share code, notes, and snippets.

@kritzcreek
Created December 19, 2020 11:22
Show Gist options
  • Save kritzcreek/73fcb7342fbef1663a682944cee090b3 to your computer and use it in GitHub Desktop.
Save kritzcreek/73fcb7342fbef1663a682944cee090b3 to your computer and use it in GitHub Desktop.
Decoding mixed Json
module Main where
import Prelude
import Effect (Effect)
import Data.Either (Either(..))
import Data.Traversable (traverse)
import TryPureScript (render, withConsole)
import Type.Row (type (+))
import Data.Argonaut as A
import Record as R
import Foreign.Object as FO
import Effect.Console as Console
import Data.Symbol (SProxy(..))
input :: String
input = """
[{"from":"Joachim","trigger":"private","text":"Hi!","when":1608373464,"response":"Du Nerd!"},{"exception":"name 'true' is not defined","when":1608373305,"trigger":"eval"},{"when":1608372753,"trigger":"eval"}]
"""
type CommonR r = (trigger :: String, when :: Int | r)
type LogR r = (rest :: FO.Object A.Json | r)
type Log = Record (CommonR + LogR + ())
decodeLogs :: String -> Either String (Array Log)
decodeLogs input = do
jsons <- A.jsonParser input
A.caseJsonArray (Left "Logs were not an Array") (traverse decodeLog) jsons
where
decodeLog :: A.Json -> Either String Log
decodeLog json = do
common :: Record (CommonR ()) <- A.decodeJson json
rest <- A.caseJsonObject (Left "Log was not an Object") Right json
Right (R.union common { rest: FO.delete "trigger" (FO.delete "when" rest) })
main :: Effect Unit
main = render =<< withConsole do
case decodeLogs input of
Left err ->
Console.log err
Right res ->
Console.logShow (map (R.modify (SProxy::_"rest") (A.stringify <<< A.fromObject)) res)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment