mu-rpc 0.2.0.0 → 0.3.0.0
raw patch · 4 files changed
+405/−121 lines, 4 filesdep ~mu-schemaPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: mu-schema
API changes (from Hackage documentation)
- Mu.Rpc: [ViaRegistry] :: Registry -> Type -> Nat -> TypeRef
- Mu.Rpc: [ViaSchema] :: Schema typeName fieldName -> typeName -> TypeRef
- Mu.Rpc: [ViaTH] :: Type -> TypeRef
- Mu.Rpc.Examples: instance GHC.Base.Functor f => Mu.Schema.Class.FromSchema f Mu.Rpc.Examples.QuickstartSchema "HelloRequest" (Mu.Rpc.Examples.HelloRequest f)
- Mu.Rpc.Examples: instance GHC.Base.Functor f => Mu.Schema.Class.FromSchema f Mu.Rpc.Examples.QuickstartSchema "HelloResponse" (Mu.Rpc.Examples.HelloResponse f)
- Mu.Rpc.Examples: instance GHC.Base.Functor f => Mu.Schema.Class.FromSchema f Mu.Rpc.Examples.QuickstartSchema "HiRequest" (Mu.Rpc.Examples.HiRequest f)
- Mu.Rpc.Examples: instance GHC.Base.Functor f => Mu.Schema.Class.ToSchema f Mu.Rpc.Examples.QuickstartSchema "HelloRequest" (Mu.Rpc.Examples.HelloRequest f)
- Mu.Rpc.Examples: instance GHC.Base.Functor f => Mu.Schema.Class.ToSchema f Mu.Rpc.Examples.QuickstartSchema "HelloResponse" (Mu.Rpc.Examples.HelloResponse f)
- Mu.Rpc.Examples: instance GHC.Base.Functor f => Mu.Schema.Class.ToSchema f Mu.Rpc.Examples.QuickstartSchema "HiRequest" (Mu.Rpc.Examples.HiRequest f)
- Mu.Rpc.Examples: instance GHC.Generics.Generic (Mu.Rpc.Examples.HelloRequest f)
- Mu.Rpc.Examples: instance GHC.Generics.Generic (Mu.Rpc.Examples.HelloResponse f)
- Mu.Rpc.Examples: instance GHC.Generics.Generic (Mu.Rpc.Examples.HiRequest f)
- Mu.Server: [:<|>:] :: Handles w args ret m h => h -> HandlersT w ms m hs -> HandlersT w ('Method name anns args ret : ms) m (h : hs)
- Mu.Server: [Server] :: HandlersT w methods m hs -> ServerT w ('Service sname anns methods) m hs
- Mu.Server: infixr 5 :<|>:
- Mu.Server: instance (Control.Monad.Error.Class.MonadError Mu.Server.ServerError m, Mu.Server.FromRef w ref t, Mu.Server.Handles w args ret m h, handler GHC.Types.~ (Data.Conduit.Internal.Conduit.ConduitT () t m () -> h)) => Mu.Server.Handles w ('Mu.Rpc.ArgStream ref : args) ret m handler
- Mu.Server: instance (Control.Monad.Error.Class.MonadError Mu.Server.ServerError m, Mu.Server.ToRef w eref e, Mu.Server.ToRef w vref v, handler GHC.Types.~ m (Data.Either.Either e v)) => Mu.Server.Handles w '[] ('Mu.Rpc.RetThrows eref vref) m handler
- Mu.Server: instance (Control.Monad.Error.Class.MonadError Mu.Server.ServerError m, Mu.Server.ToRef w ref v, handler GHC.Types.~ (Data.Conduit.Internal.Conduit.ConduitT v Data.Void.Void m () -> m ())) => Mu.Server.Handles w '[] ('Mu.Rpc.RetStream ref) m handler
- Mu.Server: instance (Control.Monad.Error.Class.MonadError Mu.Server.ServerError m, Mu.Server.ToRef w ref v, handler GHC.Types.~ m v) => Mu.Server.Handles w '[] ('Mu.Rpc.RetSingle ref) m handler
- Mu.Server: instance (Control.Monad.Error.Class.MonadError Mu.Server.ServerError m, handler GHC.Types.~ m ()) => Mu.Server.Handles w '[] 'Mu.Rpc.RetNothing m handler
- Mu.Server: instance (Mu.Server.FromRef w ref t, Mu.Server.Handles w args ret m h, handler GHC.Types.~ (t -> h)) => Mu.Server.Handles w ('Mu.Rpc.ArgSingle ref : args) ret m handler
- Mu.Server: instance Mu.Server.FromRef w ('Mu.Rpc.ViaRegistry subject t last) t
- Mu.Server: instance Mu.Server.ToRef w ('Mu.Rpc.ViaRegistry subject t last) t
- Mu.Server: instance forall typeName fieldName (w :: * -> *) (sch :: Mu.Schema.Definition.Schema typeName fieldName) (sty :: typeName) t. Mu.Schema.Class.FromSchema w sch sty t => Mu.Server.FromRef w ('Mu.Rpc.ViaSchema sch sty) t
- Mu.Server: instance forall typeName fieldName (w :: * -> *) (sch :: Mu.Schema.Definition.Schema typeName fieldName) (sty :: typeName) t. Mu.Schema.Class.ToSchema w sch sty t => Mu.Server.ToRef w ('Mu.Rpc.ViaSchema sch sty) t
+ Mu.Rpc: Package :: Maybe serviceName -> [Service serviceName methodName argName] -> Package serviceName methodName argName
+ Mu.Rpc: [ListRef] :: TypeRef serviceName -> TypeRef serviceName
+ Mu.Rpc: [ObjectRef] :: serviceName -> TypeRef serviceName
+ Mu.Rpc: [OptionalRef] :: TypeRef serviceName -> TypeRef serviceName
+ Mu.Rpc: [PrimitiveRef] :: Type -> TypeRef serviceName
+ Mu.Rpc: [RegistryRef] :: Registry -> Type -> Nat -> TypeRef serviceName
+ Mu.Rpc: [SchemaRef] :: Schema typeName fieldName -> typeName -> TypeRef serviceName
+ Mu.Rpc: [THRef] :: Type -> TypeRef serviceName
+ Mu.Rpc: type Argument' = Argument Symbol Symbol
+ Mu.Rpc: type Method' = Method Symbol Symbol Symbol
+ Mu.Rpc: type Object = 'Service
+ Mu.Rpc: type ObjectField = 'Method
+ Mu.Rpc: type Package' = Package Symbol Symbol Symbol
+ Mu.Rpc.Examples: apolloServer :: forall m. MonadServer m => ServerT ApolloBookAuthor ApolloService m _
+ Mu.Rpc.Examples: instance GHC.Classes.Eq Mu.Rpc.Examples.HelloRequest
+ Mu.Rpc.Examples: instance GHC.Classes.Eq Mu.Rpc.Examples.HelloResponse
+ Mu.Rpc.Examples: instance GHC.Classes.Eq Mu.Rpc.Examples.HiRequest
+ Mu.Rpc.Examples: instance GHC.Generics.Generic Mu.Rpc.Examples.HelloRequest
+ Mu.Rpc.Examples: instance GHC.Generics.Generic Mu.Rpc.Examples.HelloResponse
+ Mu.Rpc.Examples: instance GHC.Generics.Generic Mu.Rpc.Examples.HiRequest
+ Mu.Rpc.Examples: instance GHC.Show.Show Mu.Rpc.Examples.HelloRequest
+ Mu.Rpc.Examples: instance GHC.Show.Show Mu.Rpc.Examples.HelloResponse
+ Mu.Rpc.Examples: instance GHC.Show.Show Mu.Rpc.Examples.HiRequest
+ Mu.Rpc.Examples: instance Mu.Schema.Class.FromSchema Mu.Rpc.Examples.QuickstartSchema "HelloRequest" Mu.Rpc.Examples.HelloRequest
+ Mu.Rpc.Examples: instance Mu.Schema.Class.FromSchema Mu.Rpc.Examples.QuickstartSchema "HelloResponse" Mu.Rpc.Examples.HelloResponse
+ Mu.Rpc.Examples: instance Mu.Schema.Class.FromSchema Mu.Rpc.Examples.QuickstartSchema "HiRequest" Mu.Rpc.Examples.HiRequest
+ Mu.Rpc.Examples: instance Mu.Schema.Class.ToSchema Mu.Rpc.Examples.QuickstartSchema "HelloRequest" Mu.Rpc.Examples.HelloRequest
+ Mu.Rpc.Examples: instance Mu.Schema.Class.ToSchema Mu.Rpc.Examples.QuickstartSchema "HelloResponse" Mu.Rpc.Examples.HelloResponse
+ Mu.Rpc.Examples: instance Mu.Schema.Class.ToSchema Mu.Rpc.Examples.QuickstartSchema "HiRequest" Mu.Rpc.Examples.HiRequest
+ Mu.Rpc.Examples: type ApolloBookAuthor = '["Book" :-> (String, Integer), "Author" :-> Integer]
+ Mu.Rpc.Examples: type ApolloService = 'Package ('Just "apollo") '[Object "Book" '[] '[ObjectField "title" '[] '[] ('RetSingle ('PrimitiveRef String)), ObjectField "author" '[] '[] ('RetSingle ('ObjectRef "Author"))], Object "Author" '[] '[ObjectField "name" '[] '[] ('RetSingle ('PrimitiveRef String)), ObjectField "books" '[] '[] ('RetSingle ('ListRef ('ObjectRef "Book")))]]
+ Mu.Server: [:<&>:] :: HandlersT chn (MappingRight chn sname) methods m hs -> ServicesT chn rest m hss -> ServicesT chn ('Service sname anns methods : rest) m (hs : hss)
+ Mu.Server: [:<||>:] :: Handles chn args ret m h => (inh -> h) -> HandlersT chn inh ms m hs -> HandlersT chn inh ('Method name anns args ret : ms) m (h : hs)
+ Mu.Server: [:|:] :: Named n h -> NamedList hs -> NamedList ('(n, h) : hs)
+ Mu.Server: [N0] :: NamedList '[]
+ Mu.Server: [S0] :: ServicesT chn '[] m '[]
+ Mu.Server: [Services] :: ServicesT chn s m hs -> ServerT chn ('Package pname s) m hs
+ Mu.Server: class FromRef (chn :: ServiceChain snm) (ref :: TypeRef snm) (t :: Type)
+ Mu.Server: class Handles (chn :: ServiceChain snm) (args :: [Argument snm anm]) (ret :: Return snm) (m :: Type -> Type) (h :: Type)
+ Mu.Server: class ToRef (chn :: ServiceChain snm) (ref :: TypeRef snm) (t :: Type)
+ Mu.Server: data NamedList (hs :: [(Symbol, *)])
+ Mu.Server: data ServicesT (chn :: ServiceChain snm) (s :: [Service snm mnm anm]) (m :: Type -> Type) (hs :: [[Type]])
+ Mu.Server: field :: forall n h. h -> Named n h
+ Mu.Server: infixr 3 :<&>:
+ Mu.Server: infixr 4 :<||>:
+ Mu.Server: instance (h GHC.Types.~ h') => Mu.Server.FindService name h ('(name, h') : rest)
+ Mu.Server: instance (inh GHC.Types.~ inh', h GHC.Types.~ h') => Mu.Server.FindHandler name inh h ('(name, inh' -> h') : rest)
+ Mu.Server: instance Mu.Server.ToNamedList () '[]
+ Mu.Server: instance Mu.Server.ToNamedList (Mu.Server.Named n h) '[ '(n, h)]
+ Mu.Server: instance Mu.Server.ToNamedList (Mu.Server.Named n1 h1, Mu.Server.Named n2 h2) '[ '(n1, h1), '(n2, h2)]
+ Mu.Server: instance Mu.Server.ToNamedList (Mu.Server.Named n1 h1, Mu.Server.Named n2 h2, Mu.Server.Named n3 h3) '[ '(n1, h1), '(n2, h2), '(n3, h3)]
+ Mu.Server: instance Mu.Server.ToNamedList (Mu.Server.Named n1 h1, Mu.Server.Named n2 h2, Mu.Server.Named n3 h3, Mu.Server.Named n4 h4) '[ '(n1, h1), '(n2, h2), '(n3, h3), '(n4, h4)]
+ Mu.Server: instance Mu.Server.ToNamedList (Mu.Server.Named n1 h1, Mu.Server.Named n2 h2, Mu.Server.Named n3 h3, Mu.Server.Named n4 h4, Mu.Server.Named n5 h5) '[ '(n1, h1), '(n2, h2), '(n3, h3), '(n4, h4), '(n5, h5)]
+ Mu.Server: instance Mu.Server.ToNamedList (Mu.Server.Named n1 h1, Mu.Server.Named n2 h2, Mu.Server.Named n3 h3, Mu.Server.Named n4 h4, Mu.Server.Named n5 h5, Mu.Server.Named n6 h6) '[ '(n1, h1), '(n2, h2), '(n3, h3), '(n4, h4), '(n5, h5), '(n6, h6)]
+ Mu.Server: instance Mu.Server.ToNamedList (Mu.Server.Named n1 h1, Mu.Server.Named n2 h2, Mu.Server.Named n3 h3, Mu.Server.Named n4 h4, Mu.Server.Named n5 h5, Mu.Server.Named n6 h6, Mu.Server.Named n7 h7) '[ '(n1, h1), '(n2, h2), '(n3, h3), '(n4, h4), '(n5, h5), '(n6, h6), '(n7, h7)]
+ Mu.Server: instance Mu.Server.ToNamedList (Mu.Server.Named n1 h1, Mu.Server.Named n2 h2, Mu.Server.Named n3 h3, Mu.Server.Named n4 h4, Mu.Server.Named n5 h5, Mu.Server.Named n6 h6, Mu.Server.Named n7 h7, Mu.Server.Named n8 h8) '[ '(n1, h1), '(n2, h2), '(n3, h3), '(n4, h4), '(n5, h5), '(n6, h6), '(n7, h7), '(n8, h8)]
+ Mu.Server: instance Mu.Server.ToNamedList (Mu.Server.Named n1 h1, Mu.Server.Named n2 h2, Mu.Server.Named n3 h3, Mu.Server.Named n4 h4, Mu.Server.Named n5 h5, Mu.Server.Named n6 h6, Mu.Server.Named n7 h7, Mu.Server.Named n8 h8, Mu.Server.Named n9 h9) '[ '(n1, h1), '(n2, h2), '(n3, h3), '(n4, h4), '(n5, h5), '(n6, h6), '(n7, h7), '(n8, h8), '(n9, h9)]
+ Mu.Server: instance Mu.Server.ToNamedList (Mu.Server.NamedList nl) nl
+ Mu.Server: instance forall k (name :: k) h (rest :: [(GHC.Types.Symbol, *)]) (thing :: (GHC.Types.Symbol, *)). Mu.Server.FindService name h rest => Mu.Server.FindService name h (thing : rest)
+ Mu.Server: instance forall k (name :: k) inh h (rest :: [(GHC.Types.Symbol, *)]) (thing :: (GHC.Types.Symbol, *)). Mu.Server.FindHandler name inh h rest => Mu.Server.FindHandler name inh h (thing : rest)
+ Mu.Server: instance forall k h (name :: k). (h GHC.Types.~ (TypeError ...)) => Mu.Server.FindService name h '[]
+ Mu.Server: instance forall k inh h (name :: k). (inh GHC.Types.~ h, h GHC.Types.~ (TypeError ...)) => Mu.Server.FindHandler name inh h '[]
+ Mu.Server: instance forall mnm serviceName anm (name :: mnm) inh h (nl :: [(GHC.Types.Symbol, *)]) (chn :: Mu.Server.ServiceChain serviceName) (args :: [Mu.Rpc.Argument serviceName anm]) (ret :: Mu.Rpc.Return serviceName) (m :: * -> *) (ms :: [Mu.Rpc.Method serviceName mnm anm]) (hs :: [*]) (anns :: [Mu.Rpc.ServiceAnnotation]). (Mu.Server.FindHandler name inh h nl, Mu.Server.Handles chn args ret m h, Mu.Server.ToHandlers chn inh ms m hs nl) => Mu.Server.ToHandlers chn inh ('Mu.Rpc.Method name anns args ret : ms) m (h : hs) nl
+ Mu.Server: instance forall serviceName (chn :: Mu.Schema.Definition.Mappings serviceName *) (ref :: serviceName) t. (Mu.Schema.Definition.MappingRight chn ref GHC.Types.~ t) => Mu.Server.FromRef chn ('Mu.Rpc.ObjectRef ref) t
+ Mu.Server: instance forall serviceName (chn :: Mu.Schema.Definition.Mappings serviceName *) (ref :: serviceName) t. (Mu.Schema.Definition.MappingRight chn ref GHC.Types.~ t) => Mu.Server.ToRef chn ('Mu.Rpc.ObjectRef ref) t
+ Mu.Server: instance forall serviceName (chn :: Mu.Server.ServiceChain serviceName) (ref :: Mu.Rpc.TypeRef serviceName) t s. (Mu.Server.FromRef chn ref t, GHC.Maybe.Maybe t GHC.Types.~ s) => Mu.Server.FromRef chn ('Mu.Rpc.OptionalRef ref) s
+ Mu.Server: instance forall serviceName (chn :: Mu.Server.ServiceChain serviceName) (ref :: Mu.Rpc.TypeRef serviceName) t s. (Mu.Server.FromRef chn ref t, [t] GHC.Types.~ s) => Mu.Server.FromRef chn ('Mu.Rpc.ListRef ref) s
+ Mu.Server: instance forall serviceName (chn :: Mu.Server.ServiceChain serviceName) (ref :: Mu.Rpc.TypeRef serviceName) t s. (Mu.Server.ToRef chn ref t, GHC.Maybe.Maybe t GHC.Types.~ s) => Mu.Server.ToRef chn ('Mu.Rpc.OptionalRef ref) s
+ Mu.Server: instance forall serviceName (chn :: Mu.Server.ServiceChain serviceName) (ref :: Mu.Rpc.TypeRef serviceName) t s. (Mu.Server.ToRef chn ref t, [t] GHC.Types.~ s) => Mu.Server.ToRef chn ('Mu.Rpc.ListRef ref) s
+ Mu.Server: instance forall serviceName anm (chn :: Mu.Server.ServiceChain serviceName) (ref :: Mu.Rpc.TypeRef serviceName) t (args :: [Mu.Rpc.Argument serviceName anm]) (ret :: Mu.Rpc.Return serviceName) (m :: * -> *) h handler (aname :: GHC.Maybe.Maybe anm) (anns :: [Mu.Rpc.ServiceAnnotation]). (Mu.Server.FromRef chn ref t, Mu.Server.Handles chn args ret m h, handler GHC.Types.~ (t -> h)) => Mu.Server.Handles chn ('Mu.Rpc.ArgSingle aname anns ref : args) ret m handler
+ Mu.Server: instance forall serviceName anm (m :: * -> *) (chn :: Mu.Server.ServiceChain serviceName) (eref :: Mu.Rpc.TypeRef serviceName) e (vref :: Mu.Rpc.TypeRef serviceName) v handler. (Control.Monad.Error.Class.MonadError Mu.Server.ServerError m, Mu.Server.ToRef chn eref e, Mu.Server.ToRef chn vref v, handler GHC.Types.~ m (Data.Either.Either e v)) => Mu.Server.Handles chn '[] ('Mu.Rpc.RetThrows eref vref) m handler
+ Mu.Server: instance forall serviceName anm (m :: * -> *) (chn :: Mu.Server.ServiceChain serviceName) (ref :: Mu.Rpc.TypeRef serviceName) t (args :: [Mu.Rpc.Argument serviceName anm]) (ret :: Mu.Rpc.Return serviceName) h handler (aname :: GHC.Maybe.Maybe anm) (anns :: [Mu.Rpc.ServiceAnnotation]). (Control.Monad.Error.Class.MonadError Mu.Server.ServerError m, Mu.Server.FromRef chn ref t, Mu.Server.Handles chn args ret m h, handler GHC.Types.~ (Data.Conduit.Internal.Conduit.ConduitT () t m () -> h)) => Mu.Server.Handles chn ('Mu.Rpc.ArgStream aname anns ref : args) ret m handler
+ Mu.Server: instance forall serviceName anm (m :: * -> *) (chn :: Mu.Server.ServiceChain serviceName) (ref :: Mu.Rpc.TypeRef serviceName) v handler. (Control.Monad.Error.Class.MonadError Mu.Server.ServerError m, Mu.Server.ToRef chn ref v, handler GHC.Types.~ (Data.Conduit.Internal.Conduit.ConduitT v Data.Void.Void m () -> m ())) => Mu.Server.Handles chn '[] ('Mu.Rpc.RetStream ref) m handler
+ Mu.Server: instance forall serviceName anm (m :: * -> *) (chn :: Mu.Server.ServiceChain serviceName) (ref :: Mu.Rpc.TypeRef serviceName) v handler. (Control.Monad.Error.Class.MonadError Mu.Server.ServerError m, Mu.Server.ToRef chn ref v, handler GHC.Types.~ m v) => Mu.Server.Handles chn '[] ('Mu.Rpc.RetSingle ref) m handler
+ Mu.Server: instance forall serviceName mnm anm (name :: serviceName) (chn :: Mu.Server.ServiceChain serviceName) (methods :: [Mu.Rpc.Method serviceName mnm anm]) (m :: * -> *) (h :: [*]) (nl :: [(GHC.Types.Symbol, *)]) (ss :: [Mu.Rpc.Service serviceName mnm anm]) (hs :: [[*]]) (anns :: [Mu.Rpc.ServiceAnnotation]). (Mu.Server.FindService name (Mu.Server.HandlersT chn (Mu.Schema.Definition.MappingRight chn name) methods m h) nl, Mu.Server.ToServices chn ss m hs nl) => Mu.Server.ToServices chn ('Mu.Rpc.Service name anns methods : ss) m (h : hs) nl
+ Mu.Server: instance forall snm anm (m :: * -> *) handler (chn :: Mu.Server.ServiceChain snm). (Control.Monad.Error.Class.MonadError Mu.Server.ServerError m, handler GHC.Types.~ m ()) => Mu.Server.Handles chn '[] 'Mu.Rpc.RetNothing m handler
+ Mu.Server: instance forall snm mnm anm (chn :: Mu.Server.ServiceChain snm) (m :: * -> *) (nl :: [(GHC.Types.Symbol, *)]). Mu.Server.ToServices chn '[] m '[] nl
+ Mu.Server: instance forall snm mnm anm (chn :: Mu.Server.ServiceChain snm) inh (m :: * -> *) (nl :: [(GHC.Types.Symbol, *)]). Mu.Server.ToHandlers chn inh '[] m '[] nl
+ Mu.Server: instance forall snm t s (chn :: Mu.Server.ServiceChain snm) (subject :: Mu.Schema.Registry.Registry) (last :: GHC.Types.Nat). (t GHC.Types.~ s) => Mu.Server.FromRef chn ('Mu.Rpc.RegistryRef subject t last) s
+ Mu.Server: instance forall snm t s (chn :: Mu.Server.ServiceChain snm) (subject :: Mu.Schema.Registry.Registry) (last :: GHC.Types.Nat). (t GHC.Types.~ s) => Mu.Server.ToRef chn ('Mu.Rpc.RegistryRef subject t last) s
+ Mu.Server: instance forall snm t s (chn :: Mu.Server.ServiceChain snm). (t GHC.Types.~ s) => Mu.Server.FromRef chn ('Mu.Rpc.PrimitiveRef t) s
+ Mu.Server: instance forall snm t s (chn :: Mu.Server.ServiceChain snm). (t GHC.Types.~ s) => Mu.Server.ToRef chn ('Mu.Rpc.PrimitiveRef t) s
+ Mu.Server: instance forall typeName fieldName snm (sch :: Mu.Schema.Definition.Schema typeName fieldName) (sty :: typeName) t (chn :: Mu.Server.ServiceChain snm). Mu.Schema.Class.FromSchema sch sty t => Mu.Server.FromRef chn ('Mu.Rpc.SchemaRef sch sty) t
+ Mu.Server: instance forall typeName fieldName snm (sch :: Mu.Schema.Definition.Schema typeName fieldName) (sty :: typeName) t (chn :: Mu.Server.ServiceChain snm). Mu.Schema.Class.ToSchema sch sty t => Mu.Server.ToRef chn ('Mu.Rpc.SchemaRef sch sty) t
+ Mu.Server: method :: forall n p. p -> Named n (() -> p)
+ Mu.Server: noContext :: b -> a -> b
+ Mu.Server: object :: forall sname p nl chn ms m hs. (ToNamedList p nl, ToHandlers chn (MappingRight chn sname) ms m hs nl) => p -> Named sname (HandlersT chn (MappingRight chn sname) ms m hs)
+ Mu.Server: pattern Server :: MappingRight chn sname ~ () => HandlersT chn () methods m hs -> ServerT chn ('Package pname '[ 'Service sname sanns methods]) m '[hs]
+ Mu.Server: pattern (:<|>:) :: Handles chn args ret m h => h -> HandlersT chn () ms m hs -> HandlersT chn () ('Method name anns args ret : ms) m (h : hs)
+ Mu.Server: resolver :: (ToNamedList p nl, ToServices chn ss m hs nl) => p -> ServerT chn ('Package pname ss) m hs
+ Mu.Server: singleService :: (ToNamedList p nl, ToHandlers chn () methods m hs nl, MappingRight chn sname ~ ()) => p -> ServerT chn ('Package pname '[ 'Service sname sanns methods]) m '[hs]
+ Mu.Server: type ServiceChain snm = Mappings snm Type
+ Mu.Server: type SingleServerT = ServerT '[]
- Mu.Rpc: Method :: methodName -> [ServiceAnnotation] -> [Argument] -> Return -> Method methodName
+ Mu.Rpc: Method :: methodName -> [ServiceAnnotation] -> [Argument serviceName argName] -> Return serviceName -> Method serviceName methodName argName
- Mu.Rpc: Service :: serviceName -> [ServiceAnnotation] -> [Method methodName] -> Service serviceName methodName
+ Mu.Rpc: Service :: serviceName -> [ServiceAnnotation] -> [Method serviceName methodName argName] -> Service serviceName methodName argName
- Mu.Rpc: [ArgSingle] :: TypeRef -> Argument
+ Mu.Rpc: [ArgSingle] :: Maybe argName -> [ServiceAnnotation] -> TypeRef serviceName -> Argument serviceName argName
- Mu.Rpc: [ArgStream] :: TypeRef -> Argument
+ Mu.Rpc: [ArgStream] :: Maybe argName -> [ServiceAnnotation] -> TypeRef serviceName -> Argument serviceName argName
- Mu.Rpc: [RetNothing] :: Return
+ Mu.Rpc: [RetNothing] :: Return serviceName
- Mu.Rpc: [RetSingle] :: TypeRef -> Return
+ Mu.Rpc: [RetSingle] :: TypeRef serviceName -> Return serviceName
- Mu.Rpc: [RetStream] :: TypeRef -> Return
+ Mu.Rpc: [RetStream] :: TypeRef serviceName -> Return serviceName
- Mu.Rpc: [RetThrows] :: TypeRef -> TypeRef -> Return
+ Mu.Rpc: [RetThrows] :: TypeRef serviceName -> TypeRef serviceName -> Return serviceName
- Mu.Rpc: data Argument
+ Mu.Rpc: data Argument serviceName argName
- Mu.Rpc: data Method methodName
+ Mu.Rpc: data Method serviceName methodName argName
- Mu.Rpc: data Package (s :: Symbol)
+ Mu.Rpc: data Package serviceName methodName argName
- Mu.Rpc: data Return
+ Mu.Rpc: data Return serviceName
- Mu.Rpc: data Service serviceName methodName
+ Mu.Rpc: data Service serviceName methodName argName
- Mu.Rpc: data TypeRef
+ Mu.Rpc: data TypeRef serviceName
- Mu.Rpc: type Service' = Service Symbol Symbol
+ Mu.Rpc: type Service' = Service Symbol Symbol Symbol
- Mu.Rpc: type family (:-->:) (s :: Service snm mnm) (m :: mnm) :: Method mnm
+ Mu.Rpc: type family LookupMethod (s :: [Method snm mnm anm]) (m :: mnm) :: Method snm mnm anm
- Mu.Rpc.Examples: HelloRequest :: f Text -> HelloRequest f
+ Mu.Rpc.Examples: HelloRequest :: Text -> HelloRequest
- Mu.Rpc.Examples: HelloResponse :: f Text -> HelloResponse f
+ Mu.Rpc.Examples: HelloResponse :: Text -> HelloResponse
- Mu.Rpc.Examples: HiRequest :: f Int -> HiRequest f
+ Mu.Rpc.Examples: HiRequest :: Int -> HiRequest
- Mu.Rpc.Examples: [message] :: HelloResponse f -> f Text
+ Mu.Rpc.Examples: [message] :: HelloResponse -> Text
- Mu.Rpc.Examples: [name] :: HelloRequest f -> f Text
+ Mu.Rpc.Examples: [name] :: HelloRequest -> Text
- Mu.Rpc.Examples: [number] :: HiRequest f -> f Int
+ Mu.Rpc.Examples: [number] :: HiRequest -> Int
- Mu.Rpc.Examples: newtype HelloRequest f
+ Mu.Rpc.Examples: newtype HelloRequest
- Mu.Rpc.Examples: newtype HelloResponse f
+ Mu.Rpc.Examples: newtype HelloResponse
- Mu.Rpc.Examples: newtype HiRequest f
+ Mu.Rpc.Examples: newtype HiRequest
- Mu.Rpc.Examples: quickstartServer :: forall m f. (MonadServer m, Applicative f, MaybeLike f) => ServerT f QuickStartService m _
+ Mu.Rpc.Examples: quickstartServer :: forall m. MonadServer m => ServerT '[] QuickStartService m _
- Mu.Rpc.Examples: type QuickStartService = 'Service "Greeter" '[Package "helloworld"] '[ 'Method "SayHello" '[] '[ 'ArgSingle ('ViaSchema QuickstartSchema "HelloRequest")] ('RetSingle ('ViaSchema QuickstartSchema "HelloResponse")), 'Method "SayHi" '[] '[ 'ArgSingle ('ViaSchema QuickstartSchema "HiRequest")] ('RetStream ('ViaSchema QuickstartSchema "HelloResponse")), 'Method "SayManyHellos" '[] '[ 'ArgStream ('ViaSchema QuickstartSchema "HelloRequest")] ('RetStream ('ViaSchema QuickstartSchema "HelloResponse"))]
+ Mu.Rpc.Examples: type QuickStartService = 'Package ('Just "helloworld") '[ 'Service "Greeter" '[] '[ 'Method "SayHello" '[] '[ 'ArgSingle 'Nothing '[] ('SchemaRef QuickstartSchema "HelloRequest")] ('RetSingle ('SchemaRef QuickstartSchema "HelloResponse")), 'Method "SayHi" '[] '[ 'ArgSingle 'Nothing '[] ('SchemaRef QuickstartSchema "HiRequest")] ('RetStream ('SchemaRef QuickstartSchema "HelloResponse")), 'Method "SayManyHellos" '[] '[ 'ArgStream 'Nothing '[] ('SchemaRef QuickstartSchema "HelloRequest")] ('RetStream ('SchemaRef QuickstartSchema "HelloResponse"))]]
- Mu.Server: [H0] :: HandlersT w '[] m '[]
+ Mu.Server: [H0] :: HandlersT chn inh '[] m '[]
- Mu.Server: data HandlersT (w :: Type -> Type) (methods :: [Method mnm]) (m :: Type -> Type) (hs :: [Type])
+ Mu.Server: data HandlersT (chn :: ServiceChain snm) (inh :: *) (methods :: [Method snm mnm anm]) (m :: Type -> Type) (hs :: [Type])
- Mu.Server: data ServerT (w :: Type -> Type) (s :: Service snm mnm) (m :: Type -> Type) (hs :: [Type])
+ Mu.Server: data ServerT (chn :: ServiceChain snm) (s :: Package snm mnm anm) (m :: Type -> Type) (hs :: [[Type]])
- Mu.Server: type ServerIO w srv = ServerT w srv ServerErrorIO
+ Mu.Server: type ServerIO srv = ServerT '[] srv ServerErrorIO
Files
- mu-rpc.cabal +2/−2
- src/Mu/Rpc.hs +67/−41
- src/Mu/Rpc/Examples.hs +78/−44
- src/Mu/Server.hs +258/−34
mu-rpc.cabal view
@@ -1,5 +1,5 @@ name: mu-rpc-version: 0.2.0.0+version: 0.3.0.0 synopsis: Protocol-independent declaration of services and servers. description: Protocol-independent declaration of services and servers for mu-haskell.@@ -30,7 +30,7 @@ base >=4.12 && <5 , conduit , mtl- , mu-schema >=0.2.0+ , mu-schema >=0.3.0 , sop-core , template-haskell , text
src/Mu/Rpc.hs view
@@ -14,10 +14,11 @@ and protocol. -} module Mu.Rpc (- Service', Service(..)-, ServiceAnnotation, Package, FindPackageName-, Method(..), (:-->:)-, TypeRef(..), Argument(..), Return(..)+ Package', Package(..)+, Service', Service(..), Object+, ServiceAnnotation, Method', Method(..), ObjectField+, LookupService, LookupMethod+, TypeRef(..), Argument', Argument(..), Return(..) ) where import Data.Kind@@ -27,66 +28,91 @@ import Mu.Schema import Mu.Schema.Registry +-- | Packages whose names are given by type-level strings.+type Package' = Package Symbol Symbol Symbol -- | Services whose names are given by type-level strings.-type Service' = Service Symbol Symbol+type Service' = Service Symbol Symbol Symbol+-- | Methods whose names are given by type-level strings.+type Method' = Method Symbol Symbol Symbol+-- | Arguments whose names are given by type-level strings.+type Argument' = Argument Symbol Symbol -- | Annotations for services. At this moment, such -- annotations can be of any type. type ServiceAnnotation = Type +-- | A package is a set of services.+data Package serviceName methodName argName+ = Package (Maybe serviceName)+ [Service serviceName methodName argName]+ -- | A service is a set of methods.-data Service serviceName methodName- = Service serviceName [ServiceAnnotation] [Method methodName]+data Service serviceName methodName argName+ = Service serviceName+ [ServiceAnnotation]+ [Method serviceName methodName argName] --- | An annotation to define a package name.--- This is used by some handlers, like gRPC.-data Package (s :: Symbol)+-- | A method is defined by its name, arguments, and return type.+data Method serviceName methodName argName+ = Method methodName [ServiceAnnotation]+ [Argument serviceName argName]+ (Return serviceName) --- | Find the 'Package' for a service, to be found--- as part of the annotations.-type family FindPackageName (anns :: [ServiceAnnotation]) :: Symbol where- FindPackageName '[] = TypeError ('Text "Cannot find package name for the service")- FindPackageName (Package s ': rest) = s- FindPackageName (other ': rest) = FindPackageName rest+-- Synonyms for GraphQL+-- | An object is a set of fields, in GraphQL lingo.+type Object = 'Service+-- | A field in an object takes some input objects,+-- and returns a value or some other object,+-- in GraphQL lingo.+type ObjectField = 'Method --- | A method is defined by its name, arguments, and return type.-data Method methodName- = Method methodName [ServiceAnnotation] [Argument] Return+-- | Look up a service in a package definition using its name.+type family LookupService (ss :: [Service snm mnm anm]) (s :: snm) :: Service snm mnm anm where+ LookupService '[] s = TypeError ('Text "could not find method " ':<>: 'ShowType s)+ LookupService ('Service s anns ms ': ss) s = 'Service s anns ms+ LookupService (other ': ss) s = LookupService ss s -- | Look up a method in a service definition using its name.--- Useful to declare handlers like @HandlerIO (MyService :-->: "MyMethod")@.-type family (:-->:) (s :: Service snm mnm) (m :: mnm) :: Method mnm where- 'Service sname anns methods :-->: m = LookupMethod methods m--type family LookupMethod (s :: [Method mnm]) (m :: snm) :: Method snm where+type family LookupMethod (s :: [Method snm mnm anm]) (m :: mnm) :: Method snm mnm anm where LookupMethod '[] m = TypeError ('Text "could not find method " ':<>: 'ShowType m) LookupMethod ('Method m anns args r ': ms) m = 'Method m anns args r LookupMethod (other ': ms) m = LookupMethod ms m --- | Defines how to handle the type-data TypeRef where- ViaSchema :: Schema typeName fieldName -> typeName -> TypeRef+-- | Defines a reference to a type, either primitive or coming from the schema.+-- 'TypeRef's are used to define arguments and result types.+data TypeRef serviceName where+ -- | A primitive type.+ PrimitiveRef :: Type -> TypeRef serviceName+ -- | Chain with another service.+ ObjectRef :: serviceName -> TypeRef serviceName+ -- | Point to schema.+ SchemaRef :: Schema typeName fieldName -> typeName -> TypeRef serviceName -- | Registry subject, type to convert to, and preferred serialization version- ViaRegistry :: Registry -> Type -> Nat -> TypeRef+ RegistryRef :: Registry -> Type -> Nat -> TypeRef serviceName -- | To be used only during TH generation!- ViaTH :: TH.Type -> TypeRef+ THRef :: TH.Type -> TypeRef serviceName+ -- Combinators found in the gRPC and GraphQL languages.+ -- | Represents a list of values.+ ListRef :: TypeRef serviceName -> TypeRef serviceName+ -- | Represents a possibly-missing value.+ OptionalRef :: TypeRef serviceName -> TypeRef serviceName -- | Defines the way in which arguments are handled.-data Argument where+data Argument serviceName argName where -- | Use a single value.- ArgSingle :: TypeRef -> Argument+ ArgSingle :: Maybe argName -> [ServiceAnnotation]+ -> TypeRef serviceName -> Argument serviceName argName -- | Consume a stream of values.- ArgStream :: TypeRef -> Argument+ ArgStream :: Maybe argName -> [ServiceAnnotation]+ -> TypeRef serviceName -> Argument serviceName argName -- | Defines the different possibilities for returning -- information from a method.-data Return where+data Return serviceName where -- | Fire and forget.- RetNothing :: Return+ RetNothing :: Return serviceName -- | Return a single value.- RetSingle :: TypeRef -> Return- -- | Return a value or an error- -- (this can be found in Avro IDL).- RetThrows :: TypeRef -> TypeRef -> Return- -- | Return a stream of values- -- (this can be found in gRPC).- RetStream :: TypeRef -> Return+ RetSingle :: TypeRef serviceName -> Return serviceName+ -- | Return a stream of values.+ RetStream :: TypeRef serviceName -> Return serviceName+ -- | Return a value or an error.+ RetThrows :: TypeRef serviceName -> TypeRef serviceName -> Return serviceName
src/Mu/Rpc/Examples.hs view
@@ -9,10 +9,9 @@ {-# language PartialTypeSignatures #-} {-# language PolyKinds #-} {-# language ScopedTypeVariables #-}-{-# language StandaloneDeriving #-}+{-# language TypeApplications #-} {-# language TypeFamilies #-} {-# language TypeOperators #-}-{-# language ViewPatterns #-} {-# OPTIONS_GHC -fno-warn-partial-type-signatures #-} {-| Description : Examples for service and server definitions@@ -23,7 +22,6 @@ import Data.Conduit import Data.Conduit.Combinators as C-import Data.Functor.MaybeLike import qualified Data.Text as T import GHC.Generics @@ -36,54 +34,90 @@ type QuickstartSchema = '[ 'DRecord "HelloRequest"- '[ 'FieldDef "name" ('TPrimitive T.Text) ]+ '[ 'FieldDef "name" ('TPrimitive T.Text) ] , 'DRecord "HelloResponse"- '[ 'FieldDef "message" ('TPrimitive T.Text) ]+ '[ 'FieldDef "message" ('TPrimitive T.Text) ] , 'DRecord "HiRequest"- '[ 'FieldDef "number" ('TPrimitive Int) ]+ '[ 'FieldDef "number" ('TPrimitive Int) ] ] type QuickStartService- = 'Service "Greeter" '[Package "helloworld"]- '[ 'Method "SayHello" '[]- '[ 'ArgSingle ('ViaSchema QuickstartSchema "HelloRequest") ]- ('RetSingle ('ViaSchema QuickstartSchema "HelloResponse"))- , 'Method "SayHi" '[]- '[ 'ArgSingle ('ViaSchema QuickstartSchema "HiRequest")]- ('RetStream ('ViaSchema QuickstartSchema "HelloResponse"))- , 'Method "SayManyHellos" '[]- '[ 'ArgStream ('ViaSchema QuickstartSchema "HelloRequest")]- ('RetStream ('ViaSchema QuickstartSchema "HelloResponse")) ]+ = 'Package ('Just "helloworld")+ '[ 'Service "Greeter" '[]+ '[ 'Method "SayHello" '[]+ '[ 'ArgSingle 'Nothing '[] ('SchemaRef QuickstartSchema "HelloRequest") ]+ ('RetSingle ('SchemaRef QuickstartSchema "HelloResponse"))+ , 'Method "SayHi" '[]+ '[ 'ArgSingle 'Nothing '[] ('SchemaRef QuickstartSchema "HiRequest")]+ ('RetStream ('SchemaRef QuickstartSchema "HelloResponse"))+ , 'Method "SayManyHellos" '[]+ '[ 'ArgStream 'Nothing '[] ('SchemaRef QuickstartSchema "HelloRequest")]+ ('RetStream ('SchemaRef QuickstartSchema "HelloResponse")) ] ] -newtype HelloRequest f = HelloRequest { name :: f T.Text } deriving (Generic)-deriving instance Functor f => ToSchema f QuickstartSchema "HelloRequest" (HelloRequest f)-deriving instance Functor f => FromSchema f QuickstartSchema "HelloRequest" (HelloRequest f)+newtype HelloRequest = HelloRequest { name :: T.Text }+ deriving ( Show, Eq, Generic+ , ToSchema QuickstartSchema "HelloRequest"+ , FromSchema QuickstartSchema "HelloRequest" ) -newtype HelloResponse f = HelloResponse { message :: f T.Text } deriving (Generic)-deriving instance Functor f => ToSchema f QuickstartSchema "HelloResponse" (HelloResponse f)-deriving instance Functor f => FromSchema f QuickstartSchema "HelloResponse" (HelloResponse f)+newtype HelloResponse = HelloResponse { message :: T.Text }+ deriving ( Show, Eq, Generic+ , ToSchema QuickstartSchema "HelloResponse"+ , FromSchema QuickstartSchema "HelloResponse" ) -newtype HiRequest f = HiRequest { number :: f Int } deriving (Generic)-deriving instance Functor f => ToSchema f QuickstartSchema "HiRequest" (HiRequest f)-deriving instance Functor f => FromSchema f QuickstartSchema "HiRequest" (HiRequest f)+newtype HiRequest = HiRequest { number :: Int }+ deriving ( Show, Eq, Generic+ , ToSchema QuickstartSchema "HiRequest"+ , FromSchema QuickstartSchema "HiRequest" ) -quickstartServer :: forall m f.- (MonadServer m, Applicative f, MaybeLike f)- => ServerT f QuickStartService m _+quickstartServer :: forall m. (MonadServer m)+ => ServerT '[] QuickStartService m _ quickstartServer- = Server (sayHello :<|>: sayHi :<|>: sayManyHellos :<|>: H0)- where sayHello :: HelloRequest f -> m (HelloResponse f)- sayHello (HelloRequest nm)- = return (HelloResponse (("hi, " <>) <$> nm))- sayHi :: HiRequest f- -> ConduitT (HelloResponse f) Void m ()- -> m ()- sayHi (HiRequest (likeMaybe -> Just n)) sink- = runConduit $ C.replicate n (HelloResponse $ pure "hi!") .| sink- sayHi (HiRequest _) sink- = runConduit $ return () .| sink- sayManyHellos :: ConduitT () (HelloRequest f) m ()- -> ConduitT (HelloResponse f) Void m ()- -> m ()- sayManyHellos source sink- = runConduit $ source .| C.mapM sayHello .| sink+ -- = Server (sayHello :<|>: sayHi :<|>: sayManyHellos :<|>: H0)+ = singleService ( method @"SayHello" sayHello+ , method @"SayManyHellos" sayManyHellos+ , method @"SayHi" sayHi )+ where+ sayHello :: HelloRequest -> m HelloResponse+ sayHello (HelloRequest nm)+ = pure $ HelloResponse $ "hi, " <> nm+ sayHi :: HiRequest+ -> ConduitT HelloResponse Void m ()+ -> m ()+ sayHi (HiRequest n) sink+ = runConduit $ C.replicate n (HelloResponse "hi!") .| sink+ sayManyHellos :: ConduitT () HelloRequest m ()+ -> ConduitT HelloResponse Void m ()+ -> m ()+ sayManyHellos source sink+ = runConduit $ source .| C.mapM sayHello .| sink++-- From https://www.apollographql.com/docs/apollo-server/schema/schema/+type ApolloService+ = 'Package ('Just "apollo")+ '[ Object "Book" '[]+ '[ ObjectField "title" '[] '[] ('RetSingle ('PrimitiveRef String))+ , ObjectField "author" '[] '[] ('RetSingle ('ObjectRef "Author"))+ ]+ , Object "Author" '[]+ '[ ObjectField "name" '[] '[] ('RetSingle ('PrimitiveRef String))+ , ObjectField "books" '[] '[] ('RetSingle ('ListRef ('ObjectRef "Book")))+ ]+ ]++type ApolloBookAuthor = '[+ "Book" ':-> (String, Integer)+ , "Author" ':-> Integer+ ]++apolloServer :: forall m. (MonadServer m) => ServerT ApolloBookAuthor ApolloService m _+apolloServer+ = resolver+ ( object @"Author" ( field @"name" authorName+ , field @"books" authorBooks )+ , object @"Book" ( field @"author" (pure . snd)+ , field @"title" (pure . fst) ) )+ where+ authorName :: Integer -> m String+ authorName _ = pure "alex" -- this would run in the DB+ authorBooks :: Integer -> m [(String, Integer)]+ authorBooks _ = pure []
src/Mu/Server.hs view
@@ -3,13 +3,17 @@ {-# language ExistentialQuantification #-} {-# language FlexibleContexts #-} {-# language FlexibleInstances #-}+{-# language FunctionalDependencies #-} {-# language GADTs #-}-{-# language MultiParamTypeClasses #-}+{-# language PatternSynonyms #-} {-# language PolyKinds #-} {-# language RankNTypes #-}+{-# language ScopedTypeVariables #-}+{-# language TypeApplications #-} {-# language TypeFamilies #-} {-# language TypeOperators #-} {-# language UndecidableInstances #-}+{-# language ViewPatterns #-} {-| Description : Protocol-independent declaration of servers. @@ -17,16 +21,26 @@ of handlers (represented by 'HandlersT'), one for each operation in the corresponding Mu service declaration. -In general, you should declare a server as:+In general, you can declare a server by naming+each of the methods with their handlers: -> server :: MonadServer m => ServerT w MyService m _+> server :: MonadServer m => ServerT MyService m _+> server = singleService ( method @"m1" h1+> , method @"m2" h2+> , ... )++or by position:++> server :: MonadServer m => ServerT MyService m _ > server = Server (h1 :<|>: h2 :<|>: ... :<|>: H0) where each of @h1@, @h2@, ... handles each method in @MyService@ /in the order they were declared/.-The @_@ in the type allows GHC to fill in the boring-and long type you would need to write there otherwise. +In both cases, the @_@ in the type allows GHC to fill+in the boring and long type you would need to write+there otherwise.+ /Implementation note/: exceptions raised in handlers produce an error to be sent as response to the client. We recommend you to catch exceptions and return custom@@ -34,18 +48,26 @@ -} module Mu.Server ( -- * Servers and handlers- MonadServer, ServerT(..), HandlersT(..)+ MonadServer, ServiceChain, noContext+ -- ** Definitions by name+, singleService, method, resolver, object, field, NamedList(..)+ -- ** Definitions by position+, SingleServerT, pattern Server+, ServerT(..), ServicesT(..), HandlersT(.., (:<|>:)) -- ** Simple servers using only IO , ServerErrorIO, ServerIO -- * Errors which might be raised , serverError, ServerError(..), ServerErrorCode(..) -- ** Useful when you do not want to deal with errors , alwaysOk+ -- * For internal use+, Handles, FromRef, ToRef ) where import Control.Monad.Except import Data.Conduit import Data.Kind+import GHC.TypeLits import Mu.Rpc import Mu.Schema@@ -54,9 +76,11 @@ type MonadServer m = (MonadError ServerError m, MonadIO m) -- | Simplest monad which satisfies 'MonadServer'. type ServerErrorIO = ExceptT ServerError IO--- | Simple 'ServerT' which uses only 'IO' and errors.-type ServerIO w srv = ServerT w srv ServerErrorIO +-- | Simple 'ServerT' which uses only 'IO' and errors,+-- and whose service has no back-references.+type ServerIO srv = ServerT '[] srv ServerErrorIO+ -- | Stop the current handler, -- returning an error to the client. serverError :: (MonadError ServerError m)@@ -70,6 +94,11 @@ => IO a -> m a alwaysOk = liftIO +-- | To declare that the function doesn't use+-- its context.+noContext :: b -> a -> b+noContext = const+ -- | Errors raised in a handler. data ServerError = ServerError ServerErrorCode String@@ -87,11 +116,38 @@ | NotFound deriving (Eq, Show) +-- | Defines a mapping between outcome of+-- a service, and its representation as+-- Haskell type.+type ServiceChain snm = Mappings snm Type++-- | A server for a single service,+-- like most RPC ones.+type SingleServerT = ServerT '[]++-- | Definition of a complete server+-- for a set of services, with possible+-- references between them.+data ServerT (chn :: ServiceChain snm) (s :: Package snm mnm anm)+ (m :: Type -> Type) (hs :: [[Type]]) where+ Services :: ServicesT chn s m hs+ -> ServerT chn ('Package pname s) m hs++pattern Server :: (MappingRight chn sname ~ ())+ => HandlersT chn () methods m hs+ -> ServerT chn ('Package pname '[ 'Service sname sanns methods ]) m '[hs]+pattern Server svr = Services (svr :<&>: S0)++infixr 3 :<&>: -- | Definition of a complete server for a service.-data ServerT (w :: Type -> Type) (s :: Service snm mnm) (m :: Type -> Type) (hs :: [Type]) where- Server :: HandlersT w methods m hs -> ServerT w ('Service sname anns methods) m hs+data ServicesT (chn :: ServiceChain snm) (s :: [Service snm mnm anm])+ (m :: Type -> Type) (hs :: [[Type]]) where+ S0 :: ServicesT chn '[] m '[]+ (:<&>:) :: HandlersT chn (MappingRight chn sname) methods m hs+ -> ServicesT chn rest m hss+ -> ServicesT chn ('Service sname anns methods ': rest) m (hs ': hss) -infixr 5 :<|>:+infixr 4 :<||>: -- | 'HandlersT' is a sequence of handlers. -- Note that the handlers for your service -- must appear __in the same order__ as they@@ -111,36 +167,204 @@ -- * Output streams turn into an __additional argument__ -- of type @Conduit t Void m ()@. This stream should -- be connected to a source to get the elements.-data HandlersT (w :: Type -> Type) (methods :: [Method mnm]) (m :: Type -> Type) (hs :: [Type]) where- H0 :: HandlersT w '[] m '[]- (:<|>:) :: Handles w args ret m h => h -> HandlersT w ms m hs- -> HandlersT w ('Method name anns args ret ': ms) m (h ': hs)+data HandlersT (chn :: ServiceChain snm)+ (inh :: *) (methods :: [Method snm mnm anm])+ (m :: Type -> Type) (hs :: [Type]) where+ H0 :: HandlersT chn inh '[] m '[]+ (:<||>:) :: Handles chn args ret m h+ => (inh -> h) -> HandlersT chn inh ms m hs+ -> HandlersT chn inh ('Method name anns args ret ': ms) m (h ': hs) --- Define a relation for handling-class Handles (w :: Type -> Type) (args :: [Argument]) (ret :: Return)+infixr 4 :<|>:+pattern (:<|>:) :: (Handles chn args ret m h)+ => h -> HandlersT chn () ms m hs+ -> HandlersT chn () ('Method name anns args ret ': ms) m (h ': hs)+pattern x :<|>: xs <- (($ ()) -> x) :<||>: xs where+ x :<|>: xs = noContext x :<||>: xs++-- | Defines a relation for handling.+class Handles (chn :: ServiceChain snm)+ (args :: [Argument snm anm]) (ret :: Return snm) (m :: Type -> Type) (h :: Type)-class ToRef (w :: Type -> Type) (ref :: TypeRef) (t :: Type)-class FromRef (w :: Type -> Type) (ref :: TypeRef) (t :: Type)+-- | Defines whether a given type @t@+-- can be turned into the 'TypeRef' @ref@.+class ToRef (chn :: ServiceChain snm)+ (ref :: TypeRef snm) (t :: Type)+-- | Defines whether a given type @t@+-- can be obtained from the 'TypeRef' @ref@.+class FromRef (chn :: ServiceChain snm)+ (ref :: TypeRef snm) (t :: Type) -- Type references-instance ToSchema w sch sty t => ToRef w ('ViaSchema sch sty) t-instance ToRef w ('ViaRegistry subject t last) t-instance FromSchema w sch sty t => FromRef w ('ViaSchema sch sty) t-instance FromRef w ('ViaRegistry subject t last) t+instance t ~ s => ToRef chn ('PrimitiveRef t) s+instance ToSchema sch sty t => ToRef chn ('SchemaRef sch sty) t+instance MappingRight chn ref ~ t => ToRef chn ('ObjectRef ref) t+instance t ~ s => ToRef chn ('RegistryRef subject t last) s+instance (ToRef chn ref t, [t] ~ s) => ToRef chn ('ListRef ref) s+instance (ToRef chn ref t, Maybe t ~ s) => ToRef chn ('OptionalRef ref) s +instance t ~ s => FromRef chn ('PrimitiveRef t) s+instance FromSchema sch sty t => FromRef chn ('SchemaRef sch sty) t+instance MappingRight chn ref ~ t => FromRef chn ('ObjectRef ref) t+instance t ~ s => FromRef chn ('RegistryRef subject t last) s+instance (FromRef chn ref t, [t] ~ s) => FromRef chn ('ListRef ref) s+instance (FromRef chn ref t, Maybe t ~ s) => FromRef chn ('OptionalRef ref) s+ -- Arguments-instance (FromRef w ref t, Handles w args ret m h,+instance (FromRef chn ref t, Handles chn args ret m h, handler ~ (t -> h))- => Handles w ('ArgSingle ref ': args) ret m handler-instance (MonadError ServerError m, FromRef w ref t, Handles w args ret m h,+ => Handles chn ('ArgSingle aname anns ref ': args) ret m handler+instance (MonadError ServerError m, FromRef chn ref t, Handles chn args ret m h, handler ~ (ConduitT () t m () -> h))- => Handles w ('ArgStream ref ': args) ret m handler+ => Handles chn ('ArgStream aname anns ref ': args) ret m handler -- Result with exception instance (MonadError ServerError m, handler ~ m ())- => Handles w '[] 'RetNothing m handler-instance (MonadError ServerError m, ToRef w eref e, ToRef w vref v, handler ~ m (Either e v))- => Handles w '[] ('RetThrows eref vref) m handler-instance (MonadError ServerError m, ToRef w ref v, handler ~ m v)- => Handles w '[] ('RetSingle ref) m handler-instance (MonadError ServerError m, ToRef w ref v, handler ~ (ConduitT v Void m () -> m ()))- => Handles w '[] ('RetStream ref) m handler+ => Handles chn '[] 'RetNothing m handler+instance (MonadError ServerError m, ToRef chn eref e, ToRef chn vref v, handler ~ m (Either e v))+ => Handles chn '[] ('RetThrows eref vref) m handler+instance (MonadError ServerError m, ToRef chn ref v, handler ~ m v)+ => Handles chn '[] ('RetSingle ref) m handler+instance (MonadError ServerError m, ToRef chn ref v, handler ~ (ConduitT v Void m () -> m ()))+ => Handles chn '[] ('RetStream ref) m handler++-- SIMPLER WAY TO DECLARE SERVICES++-- | Declares the handler for a method in the service.+-- Intended to be used with @TypeApplications@:+--+-- > method @"myMethod" myHandler+method :: forall n p. p -> Named n (() -> p)+method f = Named (\() -> f)++-- | Declares the handler for a field in an object.+-- Intended to be used with @TypeApplications@:+--+-- > field @"myField" myHandler+field :: forall n h. h -> Named n h+field = Named++-- | Defines a server for a package with a single service.+-- Intended to be used with a tuple of 'method's:+--+-- > singleService (method @"m1" h1, method @"m2" h2)+singleService+ :: (ToNamedList p nl, ToHandlers chn () methods m hs nl, MappingRight chn sname ~ ())+ => p -> ServerT chn ('Package pname '[ 'Service sname sanns methods ]) m '[hs]+singleService nl = Server $ toHandlers $ toNamedList nl++-- | Defines the implementation of a single GraphQL object,+-- which translates as a single Mu service.+-- Intended to be used with @TypeApplications@+-- and a tuple of 'field's:+--+-- > object @"myObject" (field @"f1" h1, fielf @"f2" h2)+--+-- Note: for the root objects in GraphQL (query, mutation, subscription)+-- use 'method' instead of 'object'.+object+ :: forall sname p nl chn ms m hs.+ (ToNamedList p nl, ToHandlers chn (MappingRight chn sname) ms m hs nl)+ => p -> Named sname (HandlersT chn (MappingRight chn sname) ms m hs)+object nl = Named $ toHandlers $ toNamedList nl++-- | Combines the implementation of several GraphQL objects,+-- which means a whole Mu service for a GraphQL server.+-- Intented to be used with a tuple of 'objects':+--+-- > resolver (object @"o1" ..., object @"o2" ...)+resolver+ :: (ToNamedList p nl, ToServices chn ss m hs nl)+ => p -> ServerT chn ('Package pname ss) m hs+resolver nl = Services $ toServices $ toNamedList nl++-- | A value tagged with a type-level name.+data Named n h where+ Named :: forall n h. h -> Named n h++infixr 4 :|:+-- | Heterogeneous list in which each element+-- is tagged with a type-level name.+data NamedList (hs :: [(Symbol, *)]) where+ N0 :: NamedList '[]+ (:|:) :: Named n h -> NamedList hs+ -> NamedList ('(n, h) ': hs)++-- | Used to turn tuples into 'NamedList's.+class ToNamedList p nl | p -> nl where+ toNamedList :: p -> NamedList nl++instance ToNamedList (NamedList nl) nl where+ toNamedList = id+instance ToNamedList () '[] where+ toNamedList _ = N0+instance ToNamedList (Named n h) '[ '(n, h) ] where+ toNamedList n = n :|: N0+instance ToNamedList (Named n1 h1, Named n2 h2)+ '[ '(n1, h1), '(n2, h2) ] where+ toNamedList (n1, n2) = n1 :|: n2 :|: N0+instance ToNamedList (Named n1 h1, Named n2 h2, Named n3 h3)+ '[ '(n1, h1), '(n2, h2), '(n3, h3) ] where+ toNamedList (n1, n2, n3) = n1 :|: n2 :|: n3 :|: N0+instance ToNamedList (Named n1 h1, Named n2 h2, Named n3 h3, Named n4 h4)+ '[ '(n1, h1), '(n2, h2), '(n3, h3), '(n4, h4) ] where+ toNamedList (n1, n2, n3, n4) = n1 :|: n2 :|: n3 :|: n4 :|: N0+instance ToNamedList (Named n1 h1, Named n2 h2, Named n3 h3, Named n4 h4, Named n5 h5)+ '[ '(n1, h1), '(n2, h2), '(n3, h3), '(n4, h4), '(n5, h5) ] where+ toNamedList (n1, n2, n3, n4, n5) = n1 :|: n2 :|: n3 :|: n4 :|: n5 :|: N0+instance ToNamedList (Named n1 h1, Named n2 h2, Named n3 h3, Named n4 h4, Named n5 h5, Named n6 h6)+ '[ '(n1, h1), '(n2, h2), '(n3, h3), '(n4, h4), '(n5, h5), '(n6, h6) ] where+ toNamedList (n1, n2, n3, n4, n5, n6) = n1 :|: n2 :|: n3 :|: n4 :|: n5 :|: n6 :|: N0+instance ToNamedList (Named n1 h1, Named n2 h2, Named n3 h3, Named n4 h4, Named n5 h5, Named n6 h6, Named n7 h7)+ '[ '(n1, h1), '(n2, h2), '(n3, h3), '(n4, h4), '(n5, h5), '(n6, h6), '(n7, h7) ] where+ toNamedList (n1, n2, n3, n4, n5, n6, n7) = n1 :|: n2 :|: n3 :|: n4 :|: n5 :|: n6 :|: n7 :|: N0+instance ToNamedList (Named n1 h1, Named n2 h2, Named n3 h3, Named n4 h4, Named n5 h5, Named n6 h6, Named n7 h7, Named n8 h8)+ '[ '(n1, h1), '(n2, h2), '(n3, h3), '(n4, h4), '(n5, h5), '(n6, h6), '(n7, h7), '(n8, h8) ] where+ toNamedList (n1, n2, n3, n4, n5, n6, n7, n8) = n1 :|: n2 :|: n3 :|: n4 :|: n5 :|: n6 :|: n7 :|: n8 :|: N0+instance ToNamedList (Named n1 h1, Named n2 h2, Named n3 h3, Named n4 h4, Named n5 h5, Named n6 h6, Named n7 h7, Named n8 h8, Named n9 h9)+ '[ '(n1, h1), '(n2, h2), '(n3, h3), '(n4, h4), '(n5, h5), '(n6, h6), '(n7, h7), '(n8, h8), '(n9, h9) ] where+ toNamedList (n1, n2, n3, n4, n5, n6, n7, n8, n9) = n1 :|: n2 :|: n3 :|: n4 :|: n5 :|: n6 :|: n7 :|: n8 :|: n9 :|: N0++class ToHandlers chn inh ms m hs nl | chn inh ms m nl -> hs where+ toHandlers :: NamedList nl+ -> HandlersT chn inh ms m hs++instance ToHandlers chn inh '[] m '[] nl where+ toHandlers _ = H0+instance (FindHandler name inh h nl, Handles chn args ret m h, ToHandlers chn inh ms m hs nl)+ => ToHandlers chn inh ('Method name anns args ret ': ms) m (h ': hs) nl where+ toHandlers nl = findHandler (Proxy @name) nl :<||>: toHandlers nl++class FindHandler name inh h nl | name nl -> inh h where+ findHandler :: Proxy name -> NamedList nl -> inh -> h+instance (inh ~ h, h ~ TypeError ('Text "cannot find handler for " ':<>: 'ShowType name))+ => FindHandler name inh h '[] where+ findHandler = error "this should never be called"+instance {-# OVERLAPS #-} (inh ~ inh', h ~ h')+ => FindHandler name inh h ( '(name, inh' -> h') ': rest ) where+ findHandler _ (Named f :|: _) = f+instance {-# OVERLAPPABLE #-} FindHandler name inh h rest+ => FindHandler name inh h (thing ': rest) where+ findHandler p (_ :|: rest) = findHandler p rest++class ToServices chn ss m hs nl | chn ss m nl -> hs where+ toServices :: NamedList nl+ -> ServicesT chn ss m hs++instance ToServices chn '[] m '[] nl where+ toServices _ = S0+instance ( FindService name (HandlersT chn (MappingRight chn name) methods m h) nl+ , ToServices chn ss m hs nl)+ => ToServices chn ('Service name anns methods ': ss) m (h ': hs) nl where+ toServices nl = findService (Proxy @name) nl :<&>: toServices nl++class FindService name h nl | name nl -> h where+ findService :: Proxy name -> NamedList nl -> h+instance (h ~ TypeError ('Text "cannot find handler for " ':<>: 'ShowType name))+ => FindService name h '[] where+ findService = error "this should never be called"+instance {-# OVERLAPS #-} (h ~ h')+ => FindService name h ( '(name, h') ': rest ) where+ findService _ (Named f :|: _) = f+instance {-# OVERLAPPABLE #-} FindService name h rest+ => FindService name h (thing ': rest) where+ findService p (_ :|: rest) = findService p rest