module Lackey.Internal.HasCode where
import Data.Proxy (Proxy (Proxy))
import GHC.TypeLits (KnownSymbol, symbolVal)
import Lackey.Internal.Endpoint
import Lackey.Internal.Header
import Lackey.Internal.Method
import Lackey.Internal.PathSegment
import Lackey.Internal.QueryItem
import Servant.API ((:>), (:<|>)((:<|>)))
import qualified Servant.API as S
class HasCode a where
type Ruby a
codeFor :: Proxy a -> Endpoint -> Ruby a
instance HasCode S.Raw where
type Ruby S.Raw = ()
codeFor _ _ = ()
instance (HasCode a, HasCode b) => HasCode (a :<|> b) where
type Ruby (a :<|> b) = Ruby a :<|> Ruby b
codeFor _ e = codeFor a e :<|> codeFor b e where
a = Proxy :: Proxy a
b = Proxy :: Proxy b
instance (HasCode c) => HasCode (S.ReqBody a b :> c) where
type Ruby (S.ReqBody a b :> c) = Ruby c
codeFor _ e = codeFor c (e { endpointHasBody = True}) where
c = Proxy :: Proxy c
instance HasCode (S.Delete a b) where
type Ruby (S.Delete a b) = Endpoint
codeFor _ e = e { endpointMethod = Delete }
instance HasCode (S.Get a b) where
type Ruby (S.Get a b) = Endpoint
codeFor _ e = e { endpointMethod = Get }
instance HasCode (S.Patch a b) where
type Ruby (S.Patch a b) = Endpoint
codeFor _ e = e { endpointMethod = Patch }
instance HasCode (S.Post a b) where
type Ruby (S.Post a b) = Endpoint
codeFor _ e = e { endpointMethod = Post }
instance HasCode (S.Put a b) where
type Ruby (S.Put a b) = Endpoint
codeFor _ e = e { endpointMethod = Put }
instance (KnownSymbol s, HasCode a) => HasCode (s :> a) where
type Ruby (s :> a) = Ruby a
codeFor _ e = codeFor a (e { endpointPathSegments = segments }) where
a = Proxy :: Proxy a
segments = endpointPathSegments e ++ [segment]
segment = PathLiteral (symbolVal s)
s = Proxy :: Proxy s
instance (KnownSymbol s, HasCode b) => HasCode (S.Capture s a :> b) where
type Ruby (S.Capture s a :> b) = Ruby b
codeFor _ e = codeFor b (e { endpointPathSegments = segments }) where
b = Proxy :: Proxy b
segments = endpointPathSegments e ++ [segment]
segment = PathCapture (symbolVal s)
s = Proxy :: Proxy s
instance (KnownSymbol s, HasCode a) => HasCode (S.QueryFlag s :> a) where
type Ruby (S.QueryFlag s :> a) = Ruby a
codeFor _ e = codeFor a (e { endpointQueryItems = items }) where
a = Proxy :: Proxy a
items = endpointQueryItems e ++ [item]
item = QueryFlag (symbolVal s)
s = Proxy :: Proxy s
instance (KnownSymbol s, HasCode b) => HasCode (S.QueryParam s a :> b) where
type Ruby (S.QueryParam s a :> b) = Ruby b
codeFor _ e = codeFor b (e { endpointQueryItems = items }) where
b = Proxy :: Proxy b
items = endpointQueryItems e ++ [item]
item = QueryParam (symbolVal s)
s = Proxy :: Proxy s
instance (KnownSymbol s, HasCode b) => HasCode (S.QueryParams s a :> b) where
type Ruby (S.QueryParams s a :> b) = Ruby b
codeFor _ e = codeFor b (e { endpointQueryItems = items }) where
b = Proxy :: Proxy b
items = endpointQueryItems e ++ [item]
item = QueryParams (symbolVal s)
s = Proxy :: Proxy s
instance (KnownSymbol s, HasCode b) => HasCode (S.Header s a :> b) where
type Ruby (S.Header s a :> b) = Ruby b
codeFor _ e = codeFor b (e { endpointHeaders = headers }) where
b = Proxy :: Proxy b
headers = endpointHeaders e ++ [header]
header = Header (symbolVal s)
s = Proxy :: Proxy s