-- |
-- Module      :  Elm.Export.Persist
-- Copyright   :  (C) 2016-17 William Casarin
-- License     :  MIT
-- Maintainer  :  William Casarin <bill@casarin.me>
-- Stability   :  experimental
-- Portability :  non-portable
--
-- == Usage
-- #usage#
--
-- @
-- newtype 'Ent' (field :: 'Symbol') a = 'Ent' ('Entity' a)
--   deriving ('Generic')
--
-- type 'EntId' a = 'Ent' "id" a
-- @
--
-- 'Ent' is a newtype that wraps Persistent 'Entity's, allowing you to export
-- them to Elm types. Specifically, it adds a {To,From}JSON instance which
-- adds an @id@ field, as well as an @'ElmType'@ instance that adds an @id@
-- field constructor.
--
-- == Example
-- #example#
--
-- Let\'s define a Persistent model:
--
-- @
-- {-\# LANGUAGE FlexibleInstances #-}
-- {-\# LANGUAGE GADTs #-}
-- {-\# LANGUAGE GeneralizedNewtypeDeriving #-}
-- {-\# LANGUAGE MultiParamTypeClasses #-}
-- {-\# LANGUAGE OverloadedStrings #-}
-- {-\# LANGUAGE QuasiQuotes #-}
-- {-\# LANGUAGE TemplateHaskell #-}
-- {-\# LANGUAGE TypeFamilies #-}
-- {-\# LANGUAGE DeriveGeneric #-}
-- {-\# LANGUAGE StandaloneDeriving #-}
--
-- module Main where
--
-- import Data.Aeson
-- import Data.'Text'
-- import Database.Persist.TH
-- import Elm
-- import GHC.Generics
--
-- import Elm.Export.Persist
-- import Elm.Export.Persist.BackendKey ()
--
-- share [mkPersist sqlSettings, mkMigrate "migrateAccount"] [persistLowerCase|
-- Account
--   email 'Text'
--   password 'Text'
--   deriving Show 'Generic'
--   UniqueEmail email
-- |]
--
-- instance 'ToJSON' Account
-- instance 'FromJSON' Account
-- instance 'ElmType' Account
--
-- -- use GeneralizedNewtypeDeriving for ids
-- -- this picks a simpler int-encoding
-- deriving instance 'ElmType' AccountId
-- @
--
-- Now let\'s export it with an id field:
--
-- @
-- module Main where
--
-- import Db
-- import Elm
-- import Data.Proxy
--
-- mkSpecBody :: 'ElmType' a => a -> ['Text']
-- mkSpecBody a =
--   [ toElmTypeSource    a
--   , toElmDecoderSource a
--   , toElmEncoderSource a
--   ]
--
-- defImports :: ['Text']
-- defImports =
--   [ "import Json.Decode exposing (..)"
--   , "import Json.Decode.Pipeline exposing (..)"
--   , "import Json.Encode"
--   , "import Http"
--   , "import String"
--   ]
--
-- accountSpec :: Spec
-- accountSpec =
--   Spec [\"Generated\", \"Account\"] $
--        defImports ++ mkSpecBody ('Proxy' :: 'Proxy' ('EntId' Account))
--
-- main :: IO ()
-- main = specsToDir [accountSpec] \"some\/where\/output\"
-- @
--
-- This generates:
--
-- @
-- module Generated.Account exposing (..)
--
-- import Json.Decode exposing (..)
-- import Json.Decode.Pipeline exposing (..)
-- import Json.Encode
-- import Http
-- import String
--
-- type alias Account =
--     { accountEmail : String
--     , accountPassword : String
--     , id : Int
--     }
--
-- decodeAccount : Decoder Account
-- decodeAccount =
--     decode Account
--         |> required "accountEmail" string
--         |> required "accountPassword" string
--         |> required "id" int
--
-- encodeAccount : Account -> Json.Encode.Value
-- encodeAccount x =
--     Json.Encode.object
--         [ ( "accountEmail", Json.Encode.string x.accountEmail )
--         , ( "accountPassword", Json.Encode.string x.accountPassword )
--         , ( "id", Json.Encode.int x.id )
--         ]
-- @

module Elm.Export.Persist
  ( module Elm.Export.Persist.Ent
  )
  where

import Elm.Export.Persist.Ent