-- | Specification for valid Request component types used at the Kind and Type level for -- creating an API structure. -- module Hreq.Core.API.Request where import Data.Kind (Type) import Data.Singletons (Sing, SingI(..)) import GHC.TypeLits (Symbol) -- * Request Type data ReqContent a = Path a Symbol | Params [(Symbol, a)] | QueryFlags a [Symbol] | Captures [a] | BasicAuth a Symbol | CaptureAll a | ReqBody a a | StreamBody a a | ReqHeaders [(Symbol, a)] -- * Request Type Synonyms type Captures = 'Captures type QueryFlags = 'QueryFlags () type Params = 'Params type ReqBody = 'ReqBody type StreamBody = 'StreamBody type ReqHeaders = 'ReqHeaders type CaptureAll = 'CaptureAll type BasicAuth = 'BasicAuth () type Path = 'Path () type QueryFlag (s :: Symbol) = QueryFlags '[ s ] type Param s t = Params '[ '( s, t ) ] type Capture t = Captures '[ t ] -- * Request as a Singleton GADT data SReqContent (a :: ReqContent Type) = forall t s . a ~ 'Path t s => SPath (Sing t) (Sing s) | forall ts (b :: Type) . a ~ 'QueryFlags b ts => SQueryFlags (Sing b) (Sing ts) | forall b . a ~ 'CaptureAll b => SCaptureAll (Sing b) | forall ts . a ~ 'Captures ts => SCaptures (Sing ts) | forall ctyp b . a ~ 'ReqBody ctyp b => SReqBody (Sing ctyp) (Sing b) | forall ctyp b . a ~ 'StreamBody ctyp b => SStreamBody (Sing ctyp) (Sing b) | forall ts . a ~ ReqHeaders ts => SReqHeaders (Sing ts) | forall ts . a ~ Params ts => SParams (Sing ts) | forall b s . a ~ 'BasicAuth b s => SBasicAuth (Sing b) (Sing s) type instance Sing = SReqContent instance (SingI a, SingI s) => SingI ('BasicAuth a s :: ReqContent Type) where sing = SBasicAuth sing sing instance (SingI a, SingI s) => SingI ('Path a s :: ReqContent Type) where sing = SPath sing sing instance SingI ts => SingI ('Params ts :: ReqContent Type) where sing = SParams sing instance (SingI a, SingI ts) => SingI ('QueryFlags a ts :: ReqContent Type) where sing = SQueryFlags sing sing instance SingI ts => SingI ('Captures ts :: ReqContent Type) where sing = SCaptures sing instance (SingI a) => SingI ('CaptureAll a :: ReqContent Type) where sing = SCaptureAll sing instance (SingI a, SingI ctyp) => SingI ('ReqBody ctyp a :: ReqContent Type) where sing = SReqBody sing sing instance (SingI a, SingI ctyp) => SingI ('StreamBody ctyp a :: ReqContent Type) where sing = SStreamBody sing sing instance SingI a => SingI ('ReqHeaders a :: ReqContent Type) where sing = SReqHeaders sing