module Exercise03 where
import ClassyPrelude
import Data.Aeson (ToJSON, FromJSON, Value (String), parseJSON, toJSON, withText)
import Language.Haskell.TH
import Exercise02Recall our helper functions trimAndLowerTH, extractConstructors, spliceConstructors, spliceValues. We can
combine them to generate instances for FromJSON, ToJSON, and PrettyShow.
-- |`deriveEnumInstances tyName` takes a type name and derives three instances: `ToJSON`, `FromJSON`, `PrettyShow`. In
-- order to derive those instances we need to extract the constructors and invoke the `spliceConstructors` or
-- `spliceValues` function depending on what type of instance it is (showing or parsing, respectively). For the `Pet`
-- example you would pass in something like:
--
-- @
-- putStrLn $(stringE . pprint =<< deriveEnumInstances ''Pet)
-- @
--
-- and get something like:
--
-- @
-- Instance PrettyShow Pet where
-- prettyShow = \ case
-- PetDog -> "dog"
-- PetCat -> "cat"
-- PetTeddyBear -> "teddyBear"
-- Instance ToJSON Pet where
-- toJSON = \ case
-- PetDog -> String "dog"
-- PetCat -> String "cat"
-- PetTeddyBear -> String "teddyBear"
-- Instance FromJSON Pet where
-- parseJSON = withText "Pet" $ \ case
-- "dog" -> pure PetDog
-- "cat" -> pure PetCat
-- "teddyBear" -> pure PetTeddyBear
-- other -> fail $ "I don't know about " <> other
-- @
--
-- Fill in the body given the function arguments.
deriveEnumInstances :: Name -> Q [Dec]
deriveEnumInstances tyName = do
conNames <- fail "TODO fill me in"
[d| instance PrettyShow $(conT tyName) where
prettyShow = error "TODO fill me in"
instance ToJSON $(conT tyName) where
toJSON = error "TODO fill me in"
instance FromJSON $(conT tyName) where
parseJSON = error "TODO fill me in"
|]