-- | 'Builder' for normal constructors
module Language.Haskell.TH.Natural.Syntax.Datatype.Con.Normal (
    -- * Type
    newCon,
    ConBuilder,

    -- * Functions
    addField,
    addField',
) where

import Control.Lens
import qualified Language.Haskell.TH as TH
import Language.Haskell.TH.Natural.Syntax.Builder
import Language.Haskell.TH.Natural.Syntax.Datatype.Internal
import Language.Haskell.TH.Syntax.ExtractedCons

type ConBuilder = ConstBuilder NormalC

-- | Builds a normal constructor
newCon :: String -> ConBuilder () -> TH.Q NormalC
newCon :: String -> ConBuilder () -> Q NormalC
newCon String
conN ConBuilder ()
b = ConBuilder () -> NormalC -> Q NormalC
forall {k} (m :: * -> *) s (step :: k) (end :: k).
Monad m =>
BaseBuilder m s step end () -> s -> m s
runBaseBuilder ConBuilder ()
b (Name -> [BangType] -> NormalC
MkNormalC (String -> Name
TH.mkName String
conN) [])

-- | Add a field to the constructor
addField :: TH.Type -> ConBuilder ()
addField :: Type -> ConBuilder ()
addField Type
t = BangType -> ConBuilder ()
addField' (Bang
defaultBang, Type
t)

-- | Same as 'addField', but allow setting the field's 'Kind'
addField' :: (TH.Bang, TH.Type) -> ConBuilder ()
addField' :: BangType -> ConBuilder ()
addField' BangType
bt = ([BangType] -> Identity [BangType]) -> NormalC -> Identity NormalC
forall a b. HasBts a b => Lens' a b
Lens' NormalC [BangType]
bts (([BangType] -> Identity [BangType])
 -> NormalC -> Identity NormalC)
-> BangType -> ConBuilder ()
forall s (m :: * -> *) b a.
(MonadState s m, Snoc b b a a) =>
ASetter s s b b -> a -> m ()
|>= BangType
bt