{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE KindSignatures #-}
module Data.Generics.Internal.Errors
 ( NoGeneric
 , Defined
 , Defined_list
 , QuoteType
 , PrettyError
 ) where
import GHC.Generics
import GHC.TypeLits
import Data.Kind
type family NoGeneric (a :: Type) (ctxt :: [ErrorMessage]) :: Constraint where
  NoGeneric a ctxt = PrettyError ('Text "No instance for " ':<>: QuoteType (Generic a)
                                   ': ctxt)
type family PrettyError (ctxt :: [ErrorMessage]) :: k where
  PrettyError '[] = TypeError ('Text "")
  PrettyError (c ': cs) = TypeError ('Text "| " ':<>: c ':$$: PrettyLines cs)
type family PrettyLines (ctxt :: [ErrorMessage]) :: ErrorMessage where
  PrettyLines '[] = 'Text ""
  PrettyLines (c ': cs) = 'Text "|   " ':<>: c ':$$: PrettyLines cs
type family Defined (break :: Type -> Type) (err :: Constraint) (a :: k) :: k where
  Defined Void1 _ _ = Any
  Defined _ _     k = k
type family Defined_list (break :: [*]) (err :: Constraint) (a :: k) :: k where
  Defined_list '[Void] _ _ = Any
  Defined_list _ _        k = k
data Void1 a
data Void
type family Any :: k
type family QuoteType (typ :: k) :: ErrorMessage where
  QuoteType typ = 'Text "‘" ':<>: 'ShowType typ ':<>: 'Text "’"