I have the following json-data
value :: Maybe Value
value = decode
"{ \"import\" : { \"starttime\": \"2017-02-20T18:45:456.45645\" \
\ , \"endtime\" : \"2017-02-20T18:45:456.45645\" \
\ } \
\ , \"export\" : { \"starttime\": \"2017-02-20T18:45:456.45645\" \
\ , \"endtime\" : \"2017-02-20T18:45:456.45645\" \
\ } \
\ , \"cleanup\" : { \"starttime\": \"2017-02-20T18:45:456.45645\" \
\ , \"endtime\" : \"2017-02-20T18:45:456.45645\" \
\ , \"errormsg\" : \"It is dead Jim!\" \
\ } \
\ }"
and my goal would be to rewrite this object such that it only contains the "direct path" to a given key - e.g. if I search for "errormsg" it should only be
Just "{\"cleanup\":\"It is dead Jim!\"}"
or
Just "{\"cleanup\": {\"errormsg\":\"It is dead Jim!\"}}"
and Nothing
in the case where the key is not present, my knowledge about Prisms and Traversals is still in the stage of development so the only thing I managed to do is:
#!/usr/bin/env stack
-- stack runhaskell --package=lens --package=aeson --package=lens-aeson-lens --package=bytestring
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Control.Lens
import Data.Aeson
import Data.Foldable
import Data.Aeson.Lens
import Data.Maybe
import qualified Data.ByteString.Lazy.Char8 as B
value :: Maybe Value
value = decode
"{ \"import\" : { \"starttime\": \"2017-02-20T18:45:456.45645\" \
\ , \"endtime\" : \"2017-02-20T18:45:456.45645\" \
\ } \
\ , \"export\" : { \"starttime\": \"2017-02-20T18:45:456.45645\" \
\ , \"endtime\" : \"2017-02-20T18:45:456.45645\" \
\ } \
\ , \"cleanup\" : { \"starttime\": \"2017-02-20T18:45:456.45645\" \
\ , \"endtime\" : \"2017-02-20T18:45:456.45645\" \
\ , \"errormsg\" : \"It is dead Jim!\" \
\ } \
\ }"
main :: IO ()
main = do
traverse_ (traverse (B.putStrLn . encode))
[ value & _Just . members %~ fromMaybe Null . preview (key "errormsg")
, value & _Just . members %~ fromMaybe Null . preview (key "not here")
]
which yields
{"export":null,"cleanup":"It is dead Jim!","import":null}
{"export":null,"cleanup":null,"import":null}