-- | API to which @SubtypePlugin@s should conform.
module Data.Aeson.AutoType.Plugin.Subtype (
    SubtypePlugin (..)
  , SubtypeDesc   (..)
  ) where

import Data.Aeson.AutoType.Type
import Data.Aeson
import Data.Dynamic

-- | Hmm... this should be existential type?
type TypeDesc = String

-- | Operations that @SubtypPlugin@ must implement.
data SubtypePlugin = SubtypePlugin {
    SubtypePlugin -> [Value] -> Maybe SubtypeDesc
detect :: [Value]     -> Maybe SubtypeDesc -- | Check whether a set of values belongs to this type family
  , SubtypePlugin
-> SubtypeDesc -> SubtypeDesc -> Either SubtypeDesc Type
unify  :: SubtypeDesc -> SubtypeDesc -> Either SubtypeDesc Type
  }

-- | Description of a subtype
data SubtypeDesc = SubtypeDesc {
    SubtypeDesc -> String
subtypeName  :: String           -- | Code that is different for different type families
  , SubtypeDesc -> Type
subtypeClass :: Type
  , SubtypeDesc -> String -> String
reference    :: String -> String -- | Show type reference with a given name prefix
  , SubtypeDesc -> String
declare      :: String           -- | Show type declaration
  , SubtypeDesc -> Dynamic
typeInfo     :: Dynamic
  }