{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Servant.Record (RecordParam, UnRecordParam) where
import Data.Kind
import Data.Proxy
import GHC.Generics
import GHC.TypeLits
import Servant.API
import Servant.TypeLevel
data RecordParam (mod :: Symbol -> Exp Symbol) (a :: Type)
type family ServantAppend x y where
ServantAppend (a :> b) c = a :> ServantAppend b c
ServantAppend a c = a :> c
type family UnRecordParam (mod :: Symbol -> Exp Symbol) (x :: Type) :: Type where
UnRecordParam mod (a :> b) = ServantAppend (UnRecordParam mod a) b
UnRecordParam mod (RecordParam mod a) = UnRecordParam mod (Rep a ())
UnRecordParam mod (D1 m c d) = UnRecordParam mod (c d)
UnRecordParam mod ((a :*: b) d) =
ServantAppend
(UnRecordParam mod (a d))
(UnRecordParam mod (b d))
UnRecordParam mod (C1 m a d) = UnRecordParam mod (a d)
UnRecordParam mod (S1 ('MetaSel ('Just sym) d1 d2 d3) (Rec0 Bool) d) =
QueryFlag (Eval (mod sym))
UnRecordParam mod (S1 ('MetaSel ('Just sym) d1 d2 d3) (Rec0 [a]) d) =
QueryParams (Eval (mod sym)) a
UnRecordParam mod (S1 ('MetaSel ('Just sym) d1 d2 d3) (Rec0 (Maybe a)) d) =
QueryParam' [Optional, Strict] (Eval (mod sym)) a
UnRecordParam mod (S1 ('MetaSel ('Just sym) d1 d2 d3) (Rec0 a) d) =
QueryParam' [Required, Strict] (Eval (mod sym)) a
instance (Generic a, GHasLink mod (Rep a) sub) => HasLink (RecordParam mod a :> sub) where
type MkLink (RecordParam mod a :> sub) b = a -> MkLink sub b
toLink :: forall a.
(Link -> a)
-> Proxy (RecordParam mod a :> sub)
-> Link
-> MkLink (RecordParam mod a :> sub) a
toLink Link -> a
toA Proxy (RecordParam mod a :> sub)
_ Link
l a
record = forall {k} (mod :: Symbol -> Exp Symbol) (a :: * -> *) (sub :: k)
b.
GHasLink mod a sub =>
Proxy mod
-> (Link -> b) -> Proxy sub -> Link -> a () -> MkLink sub b
gToLink (forall {k} (t :: k). Proxy t
Proxy :: Proxy mod) Link -> a
toA (forall {k} (t :: k). Proxy t
Proxy :: Proxy sub) Link
l (forall a x. Generic a => a -> Rep a x
from a
record :: Rep a ())
data GParam (mod :: Symbol -> Exp Symbol) a
instance GHasLink mod a sub => HasLink (GParam mod (a ()) :> sub) where
type MkLink (GParam mod (a ()) :> sub) b = a () -> MkLink sub b
toLink :: forall a.
(Link -> a)
-> Proxy (GParam mod (a ()) :> sub)
-> Link
-> MkLink (GParam mod (a ()) :> sub) a
toLink Link -> a
toA Proxy (GParam mod (a ()) :> sub)
_ = forall {k} (mod :: Symbol -> Exp Symbol) (a :: * -> *) (sub :: k)
b.
GHasLink mod a sub =>
Proxy mod
-> (Link -> b) -> Proxy sub -> Link -> a () -> MkLink sub b
gToLink (forall {k} (t :: k). Proxy t
Proxy :: Proxy mod) Link -> a
toA (forall {k} (t :: k). Proxy t
Proxy :: Proxy sub)
{-# INLINE toLink #-}
class HasLink sub => GHasLink (mod :: Symbol -> Exp Symbol) (a :: Type -> Type) sub where
gToLink :: Proxy mod -> (Link -> b) -> Proxy sub -> Link -> a () -> MkLink sub b
instance GHasLink mod c sub => GHasLink mod (D1 m c) sub where
gToLink :: forall b.
Proxy mod
-> (Link -> b) -> Proxy sub -> Link -> D1 m c () -> MkLink sub b
gToLink Proxy mod
_ Link -> b
toA Proxy sub
_ Link
l (M1 c ()
x) = forall {k} (mod :: Symbol -> Exp Symbol) (a :: * -> *) (sub :: k)
b.
GHasLink mod a sub =>
Proxy mod
-> (Link -> b) -> Proxy sub -> Link -> a () -> MkLink sub b
gToLink (forall {k} (t :: k). Proxy t
Proxy :: Proxy mod) Link -> b
toA (forall {k} (t :: k). Proxy t
Proxy :: Proxy sub) Link
l c ()
x
{-# INLINE gToLink #-}
instance
( HasLink sub
, GHasLink mod a (GParam mod (b ()) :> sub)
) =>
GHasLink mod (a :*: b) sub
where
gToLink :: forall b.
Proxy mod
-> (Link -> b) -> Proxy sub -> Link -> (:*:) a b () -> MkLink sub b
gToLink Proxy mod
_ Link -> b
toA Proxy sub
_ Link
l (a ()
a :*: b ()
b) =
forall {k} (mod :: Symbol -> Exp Symbol) (a :: * -> *) (sub :: k)
b.
GHasLink mod a sub =>
Proxy mod
-> (Link -> b) -> Proxy sub -> Link -> a () -> MkLink sub b
gToLink (forall {k} (t :: k). Proxy t
Proxy :: Proxy mod) Link -> b
toA (forall {k} (t :: k). Proxy t
Proxy :: Proxy (GParam mod (b ()) :> sub)) Link
l a ()
a b ()
b
{-# INLINE gToLink #-}
instance
( GHasLink mod a sub
, HasLink sub
) =>
GHasLink mod (C1 m a) sub
where
gToLink :: forall b.
Proxy mod
-> (Link -> b) -> Proxy sub -> Link -> C1 m a () -> MkLink sub b
gToLink Proxy mod
_ Link -> b
toA Proxy sub
_ Link
l (M1 a ()
x) = forall {k} (mod :: Symbol -> Exp Symbol) (a :: * -> *) (sub :: k)
b.
GHasLink mod a sub =>
Proxy mod
-> (Link -> b) -> Proxy sub -> Link -> a () -> MkLink sub b
gToLink (forall {k} (t :: k). Proxy t
Proxy :: Proxy mod) Link -> b
toA (forall {k} (t :: k). Proxy t
Proxy :: Proxy sub) Link
l a ()
x
{-# INLINE gToLink #-}
instance
{-# OVERLAPPING #-}
( KnownSymbol sym
, KnownSymbol (Eval (mod sym))
, HasLink (sub :: Type)
) =>
GHasLink mod (S1 ('MetaSel ('Just sym) d1 d2 d3) (Rec0 Bool)) sub
where
gToLink :: forall b.
Proxy mod
-> (Link -> b)
-> Proxy sub
-> Link
-> S1 ('MetaSel ('Just sym) d1 d2 d3) (Rec0 Bool) ()
-> MkLink sub b
gToLink Proxy mod
_ Link -> b
toA Proxy sub
_ Link
l (M1 (K1 Bool
x)) =
forall {k} (endpoint :: k) a.
HasLink endpoint =>
(Link -> a) -> Proxy endpoint -> Link -> MkLink endpoint a
toLink Link -> b
toA (forall {k} (t :: k). Proxy t
Proxy :: Proxy (QueryFlag (Eval (mod sym)) :> sub)) Link
l Bool
x
{-# INLINE gToLink #-}
instance
{-# OVERLAPPING #-}
( KnownSymbol sym
, KnownSymbol (Eval (mod sym))
, ToHttpApiData a
, HasLink (a :> sub)
, HasLink sub
) =>
GHasLink mod (S1 ('MetaSel ('Just sym) d1 d2 d3) (Rec0 [a])) sub
where
gToLink :: forall b.
Proxy mod
-> (Link -> b)
-> Proxy sub
-> Link
-> S1 ('MetaSel ('Just sym) d1 d2 d3) (Rec0 [a]) ()
-> MkLink sub b
gToLink Proxy mod
_ Link -> b
toA Proxy sub
_ Link
l (M1 (K1 [a]
x)) =
forall {k} (endpoint :: k) a.
HasLink endpoint =>
(Link -> a) -> Proxy endpoint -> Link -> MkLink endpoint a
toLink Link -> b
toA (forall {k} (t :: k). Proxy t
Proxy :: Proxy (QueryParams (Eval (mod sym)) a :> sub)) Link
l [a]
x
{-# INLINE gToLink #-}
instance
{-# OVERLAPPING #-}
( KnownSymbol sym
, KnownSymbol (Eval (mod sym))
, ToHttpApiData a
, HasLink (a :> sub)
, HasLink sub
) =>
GHasLink mod (S1 ('MetaSel ('Just sym) d1 d2 d3) (Rec0 (Maybe a))) sub
where
gToLink :: forall b.
Proxy mod
-> (Link -> b)
-> Proxy sub
-> Link
-> S1 ('MetaSel ('Just sym) d1 d2 d3) (Rec0 (Maybe a)) ()
-> MkLink sub b
gToLink Proxy mod
_ Link -> b
toA Proxy sub
_ Link
l (M1 (K1 Maybe a
x)) =
forall {k} (endpoint :: k) a.
HasLink endpoint =>
(Link -> a) -> Proxy endpoint -> Link -> MkLink endpoint a
toLink Link -> b
toA (forall {k} (t :: k). Proxy t
Proxy :: Proxy (QueryParam' '[Optional, Strict] (Eval (mod sym)) a :> sub)) Link
l Maybe a
x
{-# INLINE gToLink #-}
instance
{-# OVERLAPPABLE #-}
( KnownSymbol sym
, KnownSymbol (Eval (mod sym))
, ToHttpApiData a
, HasLink (a :> sub)
, HasLink sub
) =>
GHasLink mod (S1 ('MetaSel ('Just sym) d1 d2 d3) (Rec0 a)) sub
where
gToLink :: forall b.
Proxy mod
-> (Link -> b)
-> Proxy sub
-> Link
-> S1 ('MetaSel ('Just sym) d1 d2 d3) (Rec0 a) ()
-> MkLink sub b
gToLink Proxy mod
_ Link -> b
toA Proxy sub
_ Link
l (M1 (K1 a
x)) =
forall {k} (endpoint :: k) a.
HasLink endpoint =>
(Link -> a) -> Proxy endpoint -> Link -> MkLink endpoint a
toLink Link -> b
toA (forall {k} (t :: k). Proxy t
Proxy :: Proxy (QueryParam' '[Required, Strict] (Eval (mod sym)) a :> sub)) Link
l a
x
{-# INLINE gToLink #-}