hschema-aeson-0.0.1.0: test/Test/Schema/Model.hs
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeFamilies #-}
module Test.Schema.Model where
import Control.Lens
import Data.Aeson
import Data.Convertible
import Data.Schema (HasSchema (..))
import qualified Data.Schema as S
import Data.Schema.JSON
import qualified Data.Schema.JSON.Simple as JSON
import Data.Time (UTCTime)
import Test.QuickCheck
import Test.Schema.QuickCheck
utcTimeSchema :: JsonSchema UTCTime
utcTimeSchema = S.alias (iso convert convert) (JSON.int :: JsonSchema Integer)
data Role =
UserRole UserRole
| AdminRole AdminRole
deriving (Eq, Show)
data UserRole = UserRole'
deriving (Eq, Show)
data AdminRole = AdminRole' { department :: String, subordinateCount :: Int }
deriving (Eq, Show)
mkUserRole :: Role
mkUserRole = UserRole $ UserRole'
mkAdminRole :: String -> Int -> Role
mkAdminRole dpt subs = AdminRole $ AdminRole' dpt subs
_UserRole :: Prism' Role UserRole
_UserRole = prism' UserRole $ \case
UserRole x -> Just x
_ -> Nothing
_AdminRole :: Prism' Role AdminRole
_AdminRole = prism' AdminRole $ \case
AdminRole x -> Just x
_ -> Nothing
adminRole :: JsonSchema AdminRole
adminRole = S.record
( AdminRole'
<$> S.field "department" JSON.string (to department)
<*> S.field "subordinateCount" JSON.int (to subordinateCount)
)
roleSchema :: JsonSchema Role
roleSchema = S.oneOf
[ S.alt "user" (S.const UserRole') _UserRole
, S.alt "admin" adminRole _AdminRole
]
data Person = Person { personName :: String, birthDate :: Maybe UTCTime, roles :: [Role] }
deriving (Eq, Show)
personSchema :: JsonSchema Person
personSchema = S.record
( Person
<$> S.field "name" JSON.string (to personName)
<*> S.optional "birthDate" utcTimeSchema (to birthDate)
<*> S.field "roles" (JSON.list roleSchema) (to roles)
)
instance HasSchema Person where
type PrimitivesOf Person = JsonType
getSchema = personSchema