aeson-qq
aeson-qq copied to clipboard
Pattern matching quasi-quoter
I'm very happy with aeson-qq for my quite simple serializing needs along the lines of:
recordToJSON (Person name age) =
[aesonQQ| { name: #{name}, age: #{age} |]
However, reverse transformation is now looking pretty ugly in comparison with all that pattern-matching on Aeson.Values and descending into arrays and values. I can't help but wonder if it's possible to have a dual quasiquoter so you could write something like this:
jsonToRecord data =
let [unaesonQQ| { name: #{name}, age: #{age} } |] = data
in Person name age
@ethercrow If you have a data type, you can use GHCs generics to get instances for free:
{-# LANGUAGE DeriveGeneric #-}
module Person where
import GHC.Generics
import Data.Aeson
data Person = Person {
name :: String
, age :: Int
} deriving (Eq, Show, Generic)
instance ToJSON Person
instance FromJSON Person
Yeah, that helps in some, probably most, situations. But when you're not controlling json structure and field names (and they contain dashes or spaces for example), this method doesn't really work.
If you can define a mapping from record field names to JSON names (e.g. striping a prefix or converting CamelCase to snake_case) you can still use genericToJSON/genericParseJSON with custom options.
Regarding your question for a dual quasiquoter, in general it is possible to use QuasiQuoters as patterns. I haven't looked into it, but it may be possible to achieve this by defining quotePat for aesonQQ.
Patches welcome ;)