graphula-2.1.0.0: src/Graphula/Key.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
-- | Convenience functions for working with 'Key' dependencies
module Graphula.Key
( onlyKey
, keys
, Keys
) where
import Database.Persist
import GHC.TypeLits (ErrorMessage (..), TypeError)
import Graphula (Only (..), only)
class EntityKeys a where
-- | Type-class for turning a tuple of 'Entity' into a tuple of 'Key'
--
-- For example, given:
--
-- @
-- instance 'HasDependencies' Course where
-- type Dependencies Course = (SchoolId, TeacherId)
-- @
--
-- You would have to do,
--
-- @
-- course <- 'node' @Course (entityKey school, entityKey teacher) mempty
-- @
--
-- This type-class allows you to do:
--
-- @
-- course <- 'node' @Course ('keys' (school, teacher)) mempty
-- @
--
-- The type class instances currently scale up 4-tuple 'Dependencies'.
type Keys a
keys :: a -> Keys a
instance
TypeError
( 'Text "Cannot use naked ‘"
':<>: 'ShowType (Entity a)
':<>: 'Text "’ as argument to ‘keys’."
':$$: 'Text "Did you mean ‘Only ("
':<>: 'ShowType (Entity a)
':<>: 'Text ")’?"
)
=> EntityKeys (Entity a)
where
type Keys (Entity a) = Key a
keys = entityKey
-- | Equivalent to @'Only' . 'entityKey'@
onlyKey :: Entity a -> Only (Key a)
onlyKey = keys . only
instance EntityKeys (Only (Entity a)) where
type Keys (Only (Entity a)) = Only (Key a)
keys (Only a) = Only (entityKey a)
instance EntityKeys (Entity a, Entity b) where
type Keys (Entity a, Entity b) = (Key a, Key b)
keys (a, b) = (entityKey a, entityKey b)
instance EntityKeys (Entity a, Entity b, Entity c) where
type Keys (Entity a, Entity b, Entity c) = (Key a, Key b, Key c)
keys (a, b, c) = (entityKey a, entityKey b, entityKey c)
-- For some reason, this definition (but no others) triggers
--
-- ERROR: brittany pretty printer returned syntactically invalid result.
--
-- brittany-disable-next-binding
instance EntityKeys (Entity a, Entity b, Entity c, Entity d) where
type
Keys (Entity a, Entity b, Entity c, Entity d) =
(Key a, Key b, Key c, Key d)
keys (a, b, c, d) = (entityKey a, entityKey b, entityKey c, entityKey d)