packages feed

Z-MessagePack 0.1.0.0 → 0.3.0.0

raw patch · 7 files changed

+611/−294 lines, 7 filesdep ~Z-Datadep ~Z-IOdep ~basePVP ok

version bump matches the API change (PVP)

Dependency ranges changed: Z-Data, Z-IO, base

API changes (from Hackage documentation)

- Z.Data.MessagePack: decodeChunks' :: (MessagePack a, Monad m) => m Bytes -> Bytes -> m (Either DecodeError a)
- Z.Data.MessagePack: infixl 9 <?>
- Z.Data.MessagePack.Base: decodeChunks' :: (MessagePack a, Monad m) => m Bytes -> Bytes -> m (Either DecodeError a)
- Z.Data.MessagePack.Base: infixl 9 <?>
- Z.Data.MessagePack.Base: instance (Z.Data.MessagePack.Base.MessagePack (f a), Z.Data.MessagePack.Base.MessagePack (g a), Z.Data.MessagePack.Base.MessagePack a) => Z.Data.MessagePack.Base.MessagePack (Data.Functor.Sum.Sum f g a)
- Z.Data.MessagePack.Base: instance (Z.Data.MessagePack.Base.MessagePack a, Z.Data.MessagePack.Base.MessagePack b) => Z.Data.MessagePack.Base.MessagePack (Data.Either.Either a b)
- Z.Data.MessagePack.Base: instance (Z.Data.MessagePack.Base.MessagePack a, Z.Data.MessagePack.Base.MessagePack b) => Z.Data.MessagePack.Base.MessagePack (a, b)
- Z.Data.MessagePack.Base: instance (Z.Data.MessagePack.Base.MessagePack a, Z.Data.MessagePack.Base.MessagePack b, Z.Data.MessagePack.Base.MessagePack c) => Z.Data.MessagePack.Base.MessagePack (a, b, c)
- Z.Data.MessagePack.Base: instance (Z.Data.MessagePack.Base.MessagePack a, Z.Data.MessagePack.Base.MessagePack b, Z.Data.MessagePack.Base.MessagePack c, Z.Data.MessagePack.Base.MessagePack d) => Z.Data.MessagePack.Base.MessagePack (a, b, c, d)
- Z.Data.MessagePack.Base: instance (Z.Data.MessagePack.Base.MessagePack a, Z.Data.MessagePack.Base.MessagePack b, Z.Data.MessagePack.Base.MessagePack c, Z.Data.MessagePack.Base.MessagePack d, Z.Data.MessagePack.Base.MessagePack e) => Z.Data.MessagePack.Base.MessagePack (a, b, c, d, e)
- Z.Data.MessagePack.Base: instance (Z.Data.MessagePack.Base.MessagePack a, Z.Data.MessagePack.Base.MessagePack b, Z.Data.MessagePack.Base.MessagePack c, Z.Data.MessagePack.Base.MessagePack d, Z.Data.MessagePack.Base.MessagePack e, Z.Data.MessagePack.Base.MessagePack f) => Z.Data.MessagePack.Base.MessagePack (a, b, c, d, e, f)
- Z.Data.MessagePack.Base: instance (Z.Data.MessagePack.Base.MessagePack a, Z.Data.MessagePack.Base.MessagePack b, Z.Data.MessagePack.Base.MessagePack c, Z.Data.MessagePack.Base.MessagePack d, Z.Data.MessagePack.Base.MessagePack e, Z.Data.MessagePack.Base.MessagePack f, Z.Data.MessagePack.Base.MessagePack g) => Z.Data.MessagePack.Base.MessagePack (a, b, c, d, e, f, g)
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Data.Time.Calendar.CalendarDiffDays.CalendarDiffDays
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Data.Time.Calendar.Days.Day
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Data.Time.Calendar.Week.DayOfWeek
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Data.Time.Clock.Internal.DiffTime.DiffTime
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Data.Time.Clock.Internal.NominalDiffTime.NominalDiffTime
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Data.Time.Clock.Internal.SystemTime.SystemTime
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Data.Time.Clock.Internal.UTCTime.UTCTime
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Data.Time.LocalTime.Internal.CalendarDiffTime.CalendarDiffTime
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Data.Time.LocalTime.Internal.LocalTime.LocalTime
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Data.Time.LocalTime.Internal.TimeOfDay.TimeOfDay
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Data.Time.LocalTime.Internal.ZonedTime.ZonedTime
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Data.Version.Version
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CBool
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CChar
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CClock
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CDouble
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CFloat
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CInt
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CIntMax
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CIntPtr
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CLLong
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CLong
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CPtrdiff
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CSChar
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CSUSeconds
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CShort
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CSigAtomic
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CSize
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CTime
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CUChar
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CUInt
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CUIntMax
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CUIntPtr
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CULLong
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CULong
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CUSeconds
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CUShort
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CWchar
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack GHC.IO.Exception.ExitCode
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack a => Z.Data.MessagePack.Base.MessagePack (Data.Functor.Identity.Identity a)
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack a => Z.Data.MessagePack.Base.MessagePack (Data.Monoid.First a)
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack a => Z.Data.MessagePack.Base.MessagePack (Data.Monoid.Last a)
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack a => Z.Data.MessagePack.Base.MessagePack (Data.Semigroup.First a)
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack a => Z.Data.MessagePack.Base.MessagePack (Data.Semigroup.Internal.Dual a)
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack a => Z.Data.MessagePack.Base.MessagePack (Data.Semigroup.Last a)
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack a => Z.Data.MessagePack.Base.MessagePack (Data.Semigroup.Max a)
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack a => Z.Data.MessagePack.Base.MessagePack (Data.Semigroup.Min a)
- Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack a => Z.Data.MessagePack.Base.MessagePack (Data.Semigroup.WrappedMonoid a)
- Z.Data.MessagePack.Base: instance forall k (f :: k -> *) (a :: k) (g :: k -> *). (Z.Data.MessagePack.Base.MessagePack (f a), Z.Data.MessagePack.Base.MessagePack (g a)) => Z.Data.MessagePack.Base.MessagePack (Data.Functor.Product.Product f g a)
- Z.Data.MessagePack.Base: instance forall k a (b :: k). Z.Data.MessagePack.Base.MessagePack a => Z.Data.MessagePack.Base.MessagePack (Data.Functor.Const.Const a b)
- Z.Data.MessagePack.Base: instance forall k b (a :: k). Z.Data.MessagePack.Base.MessagePack b => Z.Data.MessagePack.Base.MessagePack (Data.Tagged.Tagged a b)
- Z.Data.MessagePack.Base: instance forall k k1 (f :: k -> *) (g :: k1 -> k) (a :: k1). Z.Data.MessagePack.Base.MessagePack (f (g a)) => Z.Data.MessagePack.Base.MessagePack (Data.Functor.Compose.Compose f g a)
+ Z.Data.MessagePack: instance (Z.Data.MessagePack.Base.MessagePack (f a), Z.Data.MessagePack.Base.MessagePack (g a), Z.Data.MessagePack.Base.MessagePack a) => Z.Data.MessagePack.Base.MessagePack (Data.Functor.Sum.Sum f g a)
+ Z.Data.MessagePack: instance (Z.Data.MessagePack.Base.MessagePack a, Z.Data.MessagePack.Base.MessagePack b) => Z.Data.MessagePack.Base.MessagePack (Data.Either.Either a b)
+ Z.Data.MessagePack: instance (Z.Data.MessagePack.Base.MessagePack a, Z.Data.MessagePack.Base.MessagePack b) => Z.Data.MessagePack.Base.MessagePack (a, b)
+ Z.Data.MessagePack: instance (Z.Data.MessagePack.Base.MessagePack a, Z.Data.MessagePack.Base.MessagePack b, Z.Data.MessagePack.Base.MessagePack c) => Z.Data.MessagePack.Base.MessagePack (a, b, c)
+ Z.Data.MessagePack: instance (Z.Data.MessagePack.Base.MessagePack a, Z.Data.MessagePack.Base.MessagePack b, Z.Data.MessagePack.Base.MessagePack c, Z.Data.MessagePack.Base.MessagePack d) => Z.Data.MessagePack.Base.MessagePack (a, b, c, d)
+ Z.Data.MessagePack: instance (Z.Data.MessagePack.Base.MessagePack a, Z.Data.MessagePack.Base.MessagePack b, Z.Data.MessagePack.Base.MessagePack c, Z.Data.MessagePack.Base.MessagePack d, Z.Data.MessagePack.Base.MessagePack e) => Z.Data.MessagePack.Base.MessagePack (a, b, c, d, e)
+ Z.Data.MessagePack: instance (Z.Data.MessagePack.Base.MessagePack a, Z.Data.MessagePack.Base.MessagePack b, Z.Data.MessagePack.Base.MessagePack c, Z.Data.MessagePack.Base.MessagePack d, Z.Data.MessagePack.Base.MessagePack e, Z.Data.MessagePack.Base.MessagePack f) => Z.Data.MessagePack.Base.MessagePack (a, b, c, d, e, f)
+ Z.Data.MessagePack: instance (Z.Data.MessagePack.Base.MessagePack a, Z.Data.MessagePack.Base.MessagePack b, Z.Data.MessagePack.Base.MessagePack c, Z.Data.MessagePack.Base.MessagePack d, Z.Data.MessagePack.Base.MessagePack e, Z.Data.MessagePack.Base.MessagePack f, Z.Data.MessagePack.Base.MessagePack g) => Z.Data.MessagePack.Base.MessagePack (a, b, c, d, e, f, g)
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Data.Time.Calendar.CalendarDiffDays.CalendarDiffDays
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Data.Time.Calendar.Days.Day
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Data.Time.Calendar.Week.DayOfWeek
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Data.Time.Clock.Internal.DiffTime.DiffTime
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Data.Time.Clock.Internal.NominalDiffTime.NominalDiffTime
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Data.Time.Clock.Internal.SystemTime.SystemTime
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Data.Time.Clock.Internal.UTCTime.UTCTime
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Data.Time.LocalTime.Internal.CalendarDiffTime.CalendarDiffTime
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Data.Time.LocalTime.Internal.LocalTime.LocalTime
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Data.Time.LocalTime.Internal.TimeOfDay.TimeOfDay
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Data.Time.LocalTime.Internal.ZonedTime.ZonedTime
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Data.Version.Version
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CBool
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CChar
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CClock
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CDouble
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CFloat
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CInt
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CIntMax
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CIntPtr
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CLLong
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CLong
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CPtrdiff
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CSChar
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CSUSeconds
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CShort
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CSigAtomic
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CSize
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CTime
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CUChar
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CUInt
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CUIntMax
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CUIntPtr
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CULLong
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CULong
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CUSeconds
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CUShort
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack Foreign.C.Types.CWchar
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack GHC.IO.Exception.ExitCode
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack a => Z.Data.MessagePack.Base.MessagePack (Data.Functor.Identity.Identity a)
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack a => Z.Data.MessagePack.Base.MessagePack (Data.Monoid.First a)
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack a => Z.Data.MessagePack.Base.MessagePack (Data.Monoid.Last a)
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack a => Z.Data.MessagePack.Base.MessagePack (Data.Semigroup.First a)
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack a => Z.Data.MessagePack.Base.MessagePack (Data.Semigroup.Internal.Dual a)
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack a => Z.Data.MessagePack.Base.MessagePack (Data.Semigroup.Last a)
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack a => Z.Data.MessagePack.Base.MessagePack (Data.Semigroup.Max a)
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack a => Z.Data.MessagePack.Base.MessagePack (Data.Semigroup.Min a)
+ Z.Data.MessagePack: instance Z.Data.MessagePack.Base.MessagePack a => Z.Data.MessagePack.Base.MessagePack (Data.Semigroup.WrappedMonoid a)
+ Z.Data.MessagePack: instance forall k (f :: k -> *) (a :: k) (g :: k -> *). (Z.Data.MessagePack.Base.MessagePack (f a), Z.Data.MessagePack.Base.MessagePack (g a)) => Z.Data.MessagePack.Base.MessagePack (Data.Functor.Product.Product f g a)
+ Z.Data.MessagePack: instance forall k a (b :: k). Z.Data.MessagePack.Base.MessagePack a => Z.Data.MessagePack.Base.MessagePack (Data.Functor.Const.Const a b)
+ Z.Data.MessagePack: instance forall k b (a :: k). Z.Data.MessagePack.Base.MessagePack b => Z.Data.MessagePack.Base.MessagePack (Data.Tagged.Tagged a b)
+ Z.Data.MessagePack: instance forall k k1 (f :: k -> *) (g :: k1 -> k) (a :: k1). Z.Data.MessagePack.Base.MessagePack (f (g a)) => Z.Data.MessagePack.Base.MessagePack (Data.Functor.Compose.Compose f g a)
+ Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack GHC.Base.String
+ Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Z.Data.CBytes.CBytes
+ Z.Data.MessagePack.Base: instance Z.Data.MessagePack.Base.MessagePack Z.Data.Vector.Base.Bytes
+ Z.Data.MessagePack.Base: type ParseChunks (m :: Type -> Type) chunk err x = m chunk -> chunk -> m (chunk, Either err x)
+ Z.Data.MessagePack.Base: withBoundedScientific :: Text -> (Scientific -> Converter a) -> Value -> Converter a
+ Z.Data.MessagePack.Base: withSystemTime :: Text -> (SystemTime -> Converter a) -> Value -> Converter a
+ Z.IO.RPC.MessagePack: Client :: Counter -> Counter -> BufferedInput -> BufferedOutput -> Client
+ Z.IO.RPC.MessagePack: RPCException :: Value -> CallStack -> RPCException
+ Z.IO.RPC.MessagePack: [CallHandler] :: (MessagePack req, MessagePack res) => (req -> IO res) -> ServerHandler
+ Z.IO.RPC.MessagePack: [NotifyHandler] :: MessagePack req => (req -> IO ()) -> ServerHandler
+ Z.IO.RPC.MessagePack: [_clientBufferedInput] :: Client -> BufferedInput
+ Z.IO.RPC.MessagePack: [_clientBufferedOutput] :: Client -> BufferedOutput
+ Z.IO.RPC.MessagePack: [_clientPipelineReqNum] :: Client -> Counter
+ Z.IO.RPC.MessagePack: [_clientSeqRef] :: Client -> Counter
+ Z.IO.RPC.MessagePack: call :: (MessagePack req, MessagePack res) => Client -> Text -> req -> IO res
+ Z.IO.RPC.MessagePack: callPipeline :: HasCallStack => MessagePack req => Client -> Text -> req -> IO PipelineId
+ Z.IO.RPC.MessagePack: data Client
+ Z.IO.RPC.MessagePack: data RPCException
+ Z.IO.RPC.MessagePack: data ServerHandler
+ Z.IO.RPC.MessagePack: execPipeline :: HasCallStack => Client -> IO PipelineResult
+ Z.IO.RPC.MessagePack: fetchPipeline :: HasCallStack => MessagePack res => PipelineId -> PipelineResult -> IO res
+ Z.IO.RPC.MessagePack: instance GHC.Exception.Type.Exception Z.IO.RPC.MessagePack.RPCException
+ Z.IO.RPC.MessagePack: instance GHC.Show.Show Z.IO.RPC.MessagePack.RPCException
+ Z.IO.RPC.MessagePack: notify :: MessagePack req => Client -> Text -> req -> IO ()
+ Z.IO.RPC.MessagePack: notifyPipeline :: HasCallStack => MessagePack req => Client -> Text -> req -> IO ()
+ Z.IO.RPC.MessagePack: rpcClient :: (Input dev, Output dev) => dev -> IO Client
+ Z.IO.RPC.MessagePack: rpcClient' :: (Input i, Output o) => i -> o -> Int -> Int -> IO Client
+ Z.IO.RPC.MessagePack: serveRPC :: ServerLoop -> ServerService -> IO ()
+ Z.IO.RPC.MessagePack: serveRPC' :: ServerLoop -> Int -> Int -> ServerService -> IO ()
+ Z.IO.RPC.MessagePack: simpleRouter :: [(Text, ServerHandler)] -> ServerService
+ Z.IO.RPC.MessagePack: type PipelineId = Int
+ Z.IO.RPC.MessagePack: type PipelineResult = FlatIntMap Value
+ Z.IO.RPC.MessagePack: type ServerLoop = (UVStream -> IO ()) -> IO ()
+ Z.IO.RPC.MessagePack: type ServerService = Text -> Maybe ServerHandler

Files

CHANGELOG.md view
@@ -1,5 +1,8 @@ # Revision history for Z-Redis -## 0.1.0.0 -- YYYY-mm-dd+## 0.3.0.0 -- 2021-02-25 -* First version. Released on an unsuspecting world.+* Add `Z.IO.RPC.MessagePack` module.+* Move some instances to `Z.Data.MessagePack` to make package buildable under constrained memory.+* Remove `decodeChunks'`.+* Change `Data.Version.Version`'s instance to use array.
Z-MessagePack.cabal view
@@ -1,6 +1,6 @@ cabal-version:              >=1.10 name:                       Z-MessagePack-version:                    0.1.0.0+version:                    0.3.0.0 synopsis:                   MessagePack description:                MessagePack binary serialization format. license:                    BSD3@@ -20,10 +20,11 @@                             Z.Data.MessagePack.Base                             Z.Data.MessagePack.Builder                             Z.Data.MessagePack.Value+                            Z.IO.RPC.MessagePack      -- other-modules:     -- other-extensions:-    build-depends:            base                      >=4.14 && <4.15+    build-depends:            base                      >= 4.12 && <5                             , deepseq                   >= 1.4 && < 1.5                             , primitive                 >= 0.7.1 && < 0.7.2                             , QuickCheck                >= 2.10@@ -34,8 +35,8 @@                             , integer-gmp               == 1.*                             , tagged                    == 0.8.*                             , time                      >= 1.9 && < 2.0-                            , Z-Data                    == 0.4.*-                            , Z-IO                      == 0.4.*+                            , Z-Data                    == 0.6.*+                            , Z-IO                      == 0.6.*      -- hs-source-dirs:     default-language:    Haskell2010@@ -52,6 +53,7 @@                             ExistentialQuantification                             FlexibleContexts                             FlexibleInstances+                            GADTs                             GeneralizedNewtypeDeriving                              KindSignatures                             MagicHash
Z/Data/MessagePack.hs view
@@ -1,3 +1,5 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}+ {-| Module      : Z.Data.MessagePack Description : Fast MessagePack serialization/deserialization@@ -7,7 +9,7 @@ Stability   : experimental Portability : non-portable -This module provides an interface similar to 'Z.Data.JSON', to work with MessagePack binary format.+This module provides an interface similar to "Z.Data.JSON", to work with MessagePack binary format.    * @Maybe a@ convert to 'Nil' in 'Nothing' case, and @a@ in 'Just' case.   * Use 'Int64'(signed) or 'Word64'(unsigned) type to marshall int type format, smaller types will sliently truncate when overflow.@@ -43,7 +45,7 @@     deriving (Show, Generic)     deriving anyclass (MessagePack.MessagePack) -> MessagePack.encode Person{ name="Alice", age=16 }+> MessagePack.encode Person{ name=\"Alice\", age=16 } > [130,164,110,97,109,101,165,65,108,105,99,101,163,97,103,101,16] @ @@ -56,8 +58,7 @@ >  2kvs   4bytes                            5bytes                                  3bytes  -This property makes it suitable for passing data across language boundary, e.g. from a static typed language to a dynamic one,-at the cost of a lower space efficiency(i.e. type tag and field label).+This property makes it suitable for passing data across language boundary, e.g. from a static typed language to a dynamic one, at the cost of a lower space efficiency(i.e. type tag and field label).  -} @@ -66,7 +67,7 @@     MessagePack(..), Value(..), defaultSettings, Settings(..), JSON.snakeCase, JSON.trainCase     -- * Encode & Decode   , readMessagePackFile, writeMessagePackFile-  , decode, decode', decodeChunks, decodeChunks', encode, encodeChunks+  , decode, decode', decodeChunks, encode, encodeChunks   , DecodeError, ParseError     -- * parse into MessagePack Value   , parseValue, parseValue', parseValueChunks, parseValueChunks'@@ -82,16 +83,260 @@   , (.=), object, (.!), object', KVItem   ) where -import Z.Data.MessagePack.Base-import qualified Z.Data.JSON    as JSON-import Z.Data.CBytes            (CBytes)-import Z.IO+import           Data.Char+import           Data.Functor.Compose+import           Data.Functor.Const+import           Data.Functor.Identity+import           Data.Functor.Product+import           Data.Functor.Sum+import qualified Data.Monoid                    as Monoid+import           Data.Proxy                     (Proxy (..))+import           Data.Scientific                (Scientific, toBoundedInteger)+import qualified Data.Semigroup                 as Semigroup+import           Data.Tagged                    (Tagged (..))+import           Data.Time                      (Day, DiffTime, LocalTime, NominalDiffTime,+                                                TimeOfDay, UTCTime, ZonedTime)+import           Data.Time.Calendar             (CalendarDiffDays (..), DayOfWeek (..))+import           Data.Time.LocalTime            (CalendarDiffTime (..))+import           Data.Time.Clock.System         (SystemTime (..), utcToSystemTime, systemToUTCTime)+import           Data.Version                   (Version(versionBranch), makeVersion)+import           Foreign.C.Types+import           System.Exit                    (ExitCode(..))+import qualified Z.Data.Builder                 as B+import           Z.Data.MessagePack.Base+import qualified Z.Data.MessagePack.Builder     as MB+import qualified Z.Data.JSON                    as JSON+import qualified Z.Data.Parser                  as P+import qualified Z.Data.Text                    as T+import           Z.Data.CBytes            (CBytes)+import           Z.IO import qualified Z.IO.FileSystem as FS  -- | Decode a 'MessagePack' instance from file. readMessagePackFile :: (HasCallStack, MessagePack a) => CBytes -> IO a-readMessagePackFile p = unwrap . decode' =<< FS.readFile p+readMessagePackFile p = unwrap "EPARSE" . decode' =<< FS.readFile p  -- | Encode a 'MessagePack' instance to file. writeMessagePackFile :: (HasCallStack, MessagePack a) => CBytes -> a -> IO () writeMessagePackFile p x = FS.writeFile p (encode x)++--------------------------------------------------------------------------------++instance MessagePack ExitCode where+    {-# INLINE fromValue #-}+    fromValue (Str "ExitSuccess") = return ExitSuccess+    fromValue (Int x) = return (ExitFailure (fromIntegral x))+    fromValue _ =  fail' "converting ExitCode failed, expected a string or number"++    {-# INLINE toValue #-}+    toValue ExitSuccess     = Str "ExitSuccess"+    toValue (ExitFailure n) = Int (fromIntegral n)++    {-# INLINE encodeMessagePack #-}+    encodeMessagePack ExitSuccess     = MB.str "ExitSuccess"+    encodeMessagePack (ExitFailure n) = B.int n++-- | Only round trip 'versionBranch' as MessagePack array.+instance MessagePack Version where+    {-# INLINE fromValue #-}+    fromValue v = makeVersion <$> fromValue v+    {-# INLINE toValue #-}+    toValue = toValue . versionBranch+    {-# INLINE encodeMessagePack #-}+    encodeMessagePack = encodeMessagePack . versionBranch++--------------------------------------------------------------------------------++-- | MessagePack extension type @Ext 0xFF@+instance MessagePack UTCTime where+    {-# INLINE fromValue #-}+    fromValue = withSystemTime "UTCTime" $ pure . systemToUTCTime+    {-# INLINE toValue #-}+    toValue t = let (MkSystemTime s ns) = utcToSystemTime t in MB.timestampValue s (fromIntegral ns)+    {-# INLINE encodeMessagePack #-}+    encodeMessagePack t = let (MkSystemTime s ns) = utcToSystemTime t in MB.timestamp s (fromIntegral ns)++-- | MessagePack extension type @Ext 0xFF@+instance MessagePack SystemTime where+    {-# INLINE fromValue #-}+    fromValue = withSystemTime "UTCTime" $ pure+    {-# INLINE toValue #-}+    toValue (MkSystemTime s ns) = MB.timestampValue s (fromIntegral ns)+    {-# INLINE encodeMessagePack #-}+    encodeMessagePack (MkSystemTime s ns) = MB.timestamp s (fromIntegral ns)++-- | @YYYY-MM-DDTHH:MM:SS.SSSZ@+instance MessagePack ZonedTime where+    {-# INLINE fromValue #-}+    fromValue = withStr "ZonedTime" $ \ t ->+        case P.parse' (P.zonedTime <* P.endOfInput) (T.getUTF8Bytes t) of+            Left err -> fail' $ "could not parse date as ZonedTime: " <> T.toText err+            Right r  -> return r+    {-# INLINE toValue #-}+    toValue t = Str (B.unsafeBuildText (B.zonedTime t))+    {-# INLINE encodeMessagePack #-}+    encodeMessagePack t = MB.str (B.unsafeBuildText (B.zonedTime t))++-- | @YYYY-MM-DD@+instance MessagePack Day where+    {-# INLINE fromValue #-}+    fromValue = withStr "Day" $ \ t ->+        case P.parse' (P.day <* P.endOfInput) (T.getUTF8Bytes t) of+            Left err -> fail' $ "could not parse date as Day: " <> T.toText err+            Right r  -> return r+    {-# INLINE toValue #-}+    toValue t = Str (B.unsafeBuildText (B.day t))+    {-# INLINE encodeMessagePack #-}+    encodeMessagePack t = MB.str (B.unsafeBuildText (B.day t))++-- | @YYYY-MM-DDTHH:MM:SS.SSSZ@+instance MessagePack LocalTime where+    {-# INLINE fromValue #-}+    fromValue = withStr "LocalTime" $ \ t ->+        case P.parse' (P.localTime <* P.endOfInput) (T.getUTF8Bytes t) of+            Left err -> fail' $ "could not parse date as LocalTime: " <> T.toText err+            Right r  -> return r+    {-# INLINE toValue #-}+    toValue t = Str (B.unsafeBuildText (B.localTime t))+    {-# INLINE encodeMessagePack #-}+    encodeMessagePack t = MB.str (B.unsafeBuildText (B.localTime t))++-- | @HH:MM:SS.SSS@+instance MessagePack TimeOfDay where+    {-# INLINE fromValue #-}+    fromValue = withStr "TimeOfDay" $ \ t ->+        case P.parse' (P.timeOfDay <* P.endOfInput) (T.getUTF8Bytes t) of+            Left err -> fail' $ "could not parse time as TimeOfDay: " <> T.toText err+            Right r  -> return r+    {-# INLINE toValue #-}+    toValue t = Str (B.unsafeBuildText (B.timeOfDay t))+    {-# INLINE encodeMessagePack #-}+    encodeMessagePack t = MB.str (B.unsafeBuildText (B.timeOfDay t))++-- | This instance includes a bounds check to prevent maliciously+-- large inputs to fill up the memory of the target system. You can+-- newtype 'NominalDiffTime' and provide your own instance using+-- 'withScientific' if you want to allow larger inputs.+instance MessagePack NominalDiffTime where+    {-# INLINE fromValue #-}+    fromValue = withBoundedScientific "NominalDiffTime" $ pure . realToFrac+    {-# INLINE toValue #-}+    toValue = toValue @Scientific . realToFrac+    {-# INLINE encodeMessagePack #-}+    encodeMessagePack = encodeMessagePack @Scientific . realToFrac++-- | This instance includes a bounds check to prevent maliciously+-- large inputs to fill up the memory of the target system. You can+-- newtype 'DiffTime' and provide your own instance using+-- 'withScientific' if you want to allow larger inputs.+instance MessagePack DiffTime where+    {-# INLINE fromValue #-}+    fromValue = withBoundedScientific "DiffTime" $ pure . realToFrac+    {-# INLINE toValue #-}+    toValue = toValue @Scientific . realToFrac+    {-# INLINE encodeMessagePack #-}+    encodeMessagePack = encodeMessagePack @Scientific . realToFrac++instance MessagePack CalendarDiffTime where+    {-# INLINE fromValue #-}+    fromValue = withFlatMapR "CalendarDiffTime" $ \ v ->+        CalendarDiffTime <$> v .: "months" <*> v .: "time"+    {-# INLINE toValue #-}+    toValue (CalendarDiffTime m nt) = object [ "months" .= m , "time" .= nt ]+    {-# INLINE encodeMessagePack #-}+    encodeMessagePack (CalendarDiffTime m nt) = object' ("months" .! m <> "time" .! nt)++instance MessagePack CalendarDiffDays where+    {-# INLINE fromValue #-}+    fromValue = withFlatMapR "CalendarDiffDays" $ \ v ->+        CalendarDiffDays <$> v .: "months" <*> v .: "days"+    {-# INLINE toValue #-}+    toValue (CalendarDiffDays m d) = object ["months" .= m, "days" .= d]+    {-# INLINE encodeMessagePack #-}+    encodeMessagePack (CalendarDiffDays m d) = object' ("months" .! m <> "days" .! d)++instance MessagePack DayOfWeek where+    {-# INLINE fromValue #-}+    fromValue (Str "monday"   ) = pure Monday+    fromValue (Str "tuesday"  ) = pure Tuesday+    fromValue (Str "wednesday") = pure Wednesday+    fromValue (Str "thursday" ) = pure Thursday+    fromValue (Str "friday"   ) = pure Friday+    fromValue (Str "saturday" ) = pure Saturday+    fromValue (Str "sunday"   ) = pure Sunday+    fromValue (Str _   )        = fail' "converting DayOfWeek failed, value should be one of weekdays"+    fromValue v                 = typeMismatch "DayOfWeek" "String" v+    {-# INLINE toValue #-}+    toValue Monday    = Str "monday"+    toValue Tuesday   = Str "tuesday"+    toValue Wednesday = Str "wednesday"+    toValue Thursday  = Str "thursday"+    toValue Friday    = Str "friday"+    toValue Saturday  = Str "saturday"+    toValue Sunday    = Str "sunday"+    {-# INLINE encodeMessagePack #-}+    encodeMessagePack Monday    = MB.str "monday"+    encodeMessagePack Tuesday   = MB.str "tuesday"+    encodeMessagePack Wednesday = MB.str "wednesday"+    encodeMessagePack Thursday  = MB.str "thursday"+    encodeMessagePack Friday    = MB.str "friday"+    encodeMessagePack Saturday  = MB.str "saturday"+    encodeMessagePack Sunday    = MB.str "sunday"+++--------------------------------------------------------------------------------++deriving newtype instance MessagePack (f (g a)) => MessagePack (Compose f g a)+deriving newtype instance MessagePack a => MessagePack (Semigroup.Min a)+deriving newtype instance MessagePack a => MessagePack (Semigroup.Max a)+deriving newtype instance MessagePack a => MessagePack (Semigroup.First a)+deriving newtype instance MessagePack a => MessagePack (Semigroup.Last a)+deriving newtype instance MessagePack a => MessagePack (Semigroup.WrappedMonoid a)+deriving newtype instance MessagePack a => MessagePack (Semigroup.Dual a)+deriving newtype instance MessagePack a => MessagePack (Monoid.First a)+deriving newtype instance MessagePack a => MessagePack (Monoid.Last a)+deriving newtype instance MessagePack a => MessagePack (Identity a)+deriving newtype instance MessagePack a => MessagePack (Const a b)+deriving newtype instance MessagePack b => MessagePack (Tagged a b)++--------------------------------------------------------------------------------++deriving newtype instance MessagePack CChar+deriving newtype instance MessagePack CSChar+deriving newtype instance MessagePack CUChar+deriving newtype instance MessagePack CShort+deriving newtype instance MessagePack CUShort+deriving newtype instance MessagePack CInt+deriving newtype instance MessagePack CUInt+deriving newtype instance MessagePack CLong+deriving newtype instance MessagePack CULong+deriving newtype instance MessagePack CPtrdiff+deriving newtype instance MessagePack CSize+deriving newtype instance MessagePack CWchar+deriving newtype instance MessagePack CSigAtomic+deriving newtype instance MessagePack CLLong+deriving newtype instance MessagePack CULLong+deriving newtype instance MessagePack CBool+deriving newtype instance MessagePack CIntPtr+deriving newtype instance MessagePack CUIntPtr+deriving newtype instance MessagePack CIntMax+deriving newtype instance MessagePack CUIntMax+deriving newtype instance MessagePack CClock+deriving newtype instance MessagePack CTime+deriving newtype instance MessagePack CUSeconds+deriving newtype instance MessagePack CSUSeconds+deriving newtype instance MessagePack CFloat+deriving newtype instance MessagePack CDouble++--------------------------------------------------------------------------------++deriving anyclass instance (MessagePack (f a), MessagePack (g a), MessagePack a) => MessagePack (Sum f g a)+deriving anyclass instance (MessagePack a, MessagePack b) => MessagePack (Either a b)+deriving anyclass instance (MessagePack (f a), MessagePack (g a)) => MessagePack (Product f g a)++deriving anyclass instance (MessagePack a, MessagePack b) => MessagePack (a, b)+deriving anyclass instance (MessagePack a, MessagePack b, MessagePack c) => MessagePack (a, b, c)+deriving anyclass instance (MessagePack a, MessagePack b, MessagePack c, MessagePack d) => MessagePack (a, b, c, d)+deriving anyclass instance (MessagePack a, MessagePack b, MessagePack c, MessagePack d, MessagePack e) => MessagePack (a, b, c, d, e)+deriving anyclass instance (MessagePack a, MessagePack b, MessagePack c, MessagePack d, MessagePack e, MessagePack f) => MessagePack (a, b, c, d, e, f)+deriving anyclass instance (MessagePack a, MessagePack b, MessagePack c, MessagePack d, MessagePack e, MessagePack f, MessagePack g) => MessagePack (a, b, c, d, e, f, g)
Z/Data/MessagePack/Base.hs view
@@ -7,7 +7,7 @@ Stability   : experimental Portability : non-portable -This module provides 'Converter' to convert 'Value' to haskell data types, and various tools to help user define 'MessagePack' instance.+This module provides various tools to help user define 'MessagePack' instance, please import `Z.Data.MessagePack` to get more instances.  -} @@ -15,8 +15,8 @@   ( -- * MessagePack Class     MessagePack(..), Value(..), defaultSettings, Settings(..)     -- * Encode & Decode-  , decode, decode', decodeChunks, decodeChunks', encode, encodeChunks-  , DecodeError, P.ParseError+  , decode, decode', decodeChunks, encode, encodeChunks+  , DecodeError, P.ParseError, P.ParseChunks     -- * parse into MessagePack Value   , MV.parseValue, MV.parseValue', MV.parseValueChunks, MV.parseValueChunks'   -- * Generic FromValue, ToValue & EncodeMessagePack@@ -26,6 +26,7 @@   , PathElement(..), ConvertError(..)   , typeMismatch, fromNil, withBool   , withStr, withBin, withArray, withKeyValues, withFlatMap, withFlatMapR+  , withBoundedScientific, withSystemTime   , (.:), (.:?), (.:!), convertField, convertFieldMaybe, convertFieldMaybe'   -- * Helper for manually writing instance.   , (.=), object, (.!), object', KVItem@@ -81,6 +82,7 @@ import           Text.ParserCombinators.ReadP   (readP_to_S) import qualified Z.Data.Array                   as A import qualified Z.Data.Builder                 as B+import qualified Z.Data.CBytes                  as CBytes import           Z.Data.Generics.Utils import           Z.Data.JSON.Converter import qualified Z.Data.MessagePack.Builder     as MB@@ -155,18 +157,6 @@                 Left cErr -> pure (bs', Left (Right cErr))                 Right r   -> pure (bs', Right r) --- | Decode MessagePack doc chunks, trailing bytes are not allowed.-decodeChunks' :: (MessagePack a, Monad m) => m V.Bytes -> V.Bytes -> m (Either DecodeError a)-{-# INLINE decodeChunks' #-}-decodeChunks' mb bs = do-    mr <- P.parseChunks (MV.value <* P.endOfInput) mb bs-    case mr of-        (_, Left pErr) -> pure (Left (Left pErr))-        (_, Right v) ->-            case convertValue v of-                Left cErr -> pure (Left (Right cErr))-                Right r   -> pure (Right r)- -- | Directly encode data to MessagePack bytes. encode :: MessagePack a => a -> V.Bytes {-# INLINE encode #-}@@ -996,6 +986,24 @@     {-# INLINE encodeMessagePack #-}     encodeMessagePack = MB.array encodeMessagePack +-- | This is an INCOHERENT instance, write 'Bytes' as Bin.+instance {-# INCOHERENT #-} MessagePack V.Bytes where+    {-# INLINE fromValue #-}+    fromValue = withBin "Z.Data.Vector.Bytes" pure+    {-# INLINE toValue #-}+    toValue = Bin+    {-# INLINE encodeMessagePack #-}+    encodeMessagePack = MB.bin++-- | Write 'CBytes' as Bin not Str.+instance MessagePack CBytes.CBytes where+    {-# INLINE fromValue #-}+    fromValue = withBin "Z.Data.CBytes" (pure . CBytes.fromBytes)+    {-# INLINE toValue #-}+    toValue = Bin . CBytes.toBytes+    {-# INLINE encodeMessagePack #-}+    encodeMessagePack = MB.bin . CBytes.toBytes+ instance MessagePack a => MessagePack (V.Vector a) where     {-# INLINE fromValue #-}     fromValue = withArray "Z.Data.Vector.Vector"@@ -1024,6 +1032,15 @@     {-# INLINE encodeMessagePack #-}     encodeMessagePack = MB.array' encodeMessagePack +-- | This is an INCOHERENT instance, encode 'String' with 'Str'.+instance {-# INCOHERENT #-} MessagePack String where+    {-# INLINE fromValue #-}+    fromValue = withStr "String" (pure . T.unpack)+    {-# INLINE toValue #-}+    toValue = Str . T.pack+    {-# INLINE encodeMessagePack #-}+    encodeMessagePack = MB.str . T.pack+ instance MessagePack a => MessagePack (NonEmpty a) where     {-# INLINE fromValue #-}     fromValue = withArray "NonEmpty" $ \ vs -> do@@ -1071,16 +1088,16 @@     instance MessagePack typ where \         {-# INLINE fromValue #-}; \             fromValue (Int x) = pure $! fromIntegral x; \-            fromValue v = typeMismatch "##typ##" "Int" v; \+            fromValue v = typeMismatch " typ " "Int" v; \         {-# INLINE toValue #-}; toValue = Int . fromIntegral; \         {-# INLINE encodeMessagePack #-}; encodeMessagePack = MB.int . fromIntegral;-INT_MessagePack_INSTANCE(Int   )-INT_MessagePack_INSTANCE(Int8  )-INT_MessagePack_INSTANCE(Int16 )-INT_MessagePack_INSTANCE(Int32 )-INT_MessagePack_INSTANCE(Int64 )-INT_MessagePack_INSTANCE(Word  )-INT_MessagePack_INSTANCE(Word8 )+INT_MessagePack_INSTANCE(Int)+INT_MessagePack_INSTANCE(Int8)+INT_MessagePack_INSTANCE(Int16)+INT_MessagePack_INSTANCE(Int32)+INT_MessagePack_INSTANCE(Int64)+INT_MessagePack_INSTANCE(Word)+INT_MessagePack_INSTANCE(Word8) INT_MessagePack_INSTANCE(Word16) INT_MessagePack_INSTANCE(Word32) INT_MessagePack_INSTANCE(Word64)@@ -1152,32 +1169,6 @@     {-# INLINE encodeMessagePack #-}     encodeMessagePack () = MB.arrayHeader 0 -instance MessagePack ExitCode where-    {-# INLINE fromValue #-}-    fromValue (Str "ExitSuccess") = return ExitSuccess-    fromValue (Int x) = return (ExitFailure (fromIntegral x))-    fromValue _ =  fail' "converting ExitCode failed, expected a string or number"--    {-# INLINE toValue #-}-    toValue ExitSuccess     = Str "ExitSuccess"-    toValue (ExitFailure n) = Int (fromIntegral n)--    {-# INLINE encodeMessagePack #-}-    encodeMessagePack ExitSuccess     = MB.str "ExitSuccess"-    encodeMessagePack (ExitFailure n) = B.int n--instance MessagePack Version where-    {-# INLINE fromValue #-}-    fromValue = withStr "Version" (go . readP_to_S parseVersion . T.unpack)-      where-        go [(v,[])] = pure v-        go (_ : xs) = go xs-        go _        = fail "converting Version failed"-    {-# INLINE toValue #-}-    toValue = Str . T.pack . show-    {-# INLINE encodeMessagePack #-}-    encodeMessagePack = MB.str' . show- instance MessagePack a => MessagePack (Maybe a) where     {-# INLINE fromValue #-}     fromValue Nil = pure Nothing@@ -1213,198 +1204,3 @@     toValue = toValue @Scientific . realToFrac     {-# INLINE encodeMessagePack #-}     encodeMessagePack = encodeMessagePack @Scientific . realToFrac-------------------------------------------------------------------------------------- | MessagePack extension type @Ext 0xFF@-instance MessagePack UTCTime where-    {-# INLINE fromValue #-}-    fromValue = withSystemTime "UTCTime" $ pure . systemToUTCTime-    {-# INLINE toValue #-}-    toValue t = let (MkSystemTime s ns) = utcToSystemTime t in MB.timestampValue s (fromIntegral ns)-    {-# INLINE encodeMessagePack #-}-    encodeMessagePack t = let (MkSystemTime s ns) = utcToSystemTime t in MB.timestamp s (fromIntegral ns)---- | MessagePack extension type @Ext 0xFF@-instance MessagePack SystemTime where-    {-# INLINE fromValue #-}-    fromValue = withSystemTime "UTCTime" $ pure-    {-# INLINE toValue #-}-    toValue (MkSystemTime s ns) = MB.timestampValue s (fromIntegral ns)-    {-# INLINE encodeMessagePack #-}-    encodeMessagePack (MkSystemTime s ns) = MB.timestamp s (fromIntegral ns)---- | @YYYY-MM-DDTHH:MM:SS.SSSZ@-instance MessagePack ZonedTime where-    {-# INLINE fromValue #-}-    fromValue = withStr "ZonedTime" $ \ t ->-        case P.parse' (P.zonedTime <* P.endOfInput) (T.getUTF8Bytes t) of-            Left err -> fail' $ "could not parse date as ZonedTime: " <> T.toText err-            Right r  -> return r-    {-# INLINE toValue #-}-    toValue t = Str (B.unsafeBuildText (B.zonedTime t))-    {-# INLINE encodeMessagePack #-}-    encodeMessagePack t = MB.str (B.unsafeBuildText (B.zonedTime t))---- | @YYYY-MM-DD@-instance MessagePack Day where-    {-# INLINE fromValue #-}-    fromValue = withStr "Day" $ \ t ->-        case P.parse' (P.day <* P.endOfInput) (T.getUTF8Bytes t) of-            Left err -> fail' $ "could not parse date as Day: " <> T.toText err-            Right r  -> return r-    {-# INLINE toValue #-}-    toValue t = Str (B.unsafeBuildText (B.day t))-    {-# INLINE encodeMessagePack #-}-    encodeMessagePack t = MB.str (B.unsafeBuildText (B.day t))---- | @YYYY-MM-DDTHH:MM:SS.SSSZ@-instance MessagePack LocalTime where-    {-# INLINE fromValue #-}-    fromValue = withStr "LocalTime" $ \ t ->-        case P.parse' (P.localTime <* P.endOfInput) (T.getUTF8Bytes t) of-            Left err -> fail' $ "could not parse date as LocalTime: " <> T.toText err-            Right r  -> return r-    {-# INLINE toValue #-}-    toValue t = Str (B.unsafeBuildText (B.localTime t))-    {-# INLINE encodeMessagePack #-}-    encodeMessagePack t = MB.str (B.unsafeBuildText (B.localTime t))---- | @HH:MM:SS.SSS@-instance MessagePack TimeOfDay where-    {-# INLINE fromValue #-}-    fromValue = withStr "TimeOfDay" $ \ t ->-        case P.parse' (P.timeOfDay <* P.endOfInput) (T.getUTF8Bytes t) of-            Left err -> fail' $ "could not parse time as TimeOfDay: " <> T.toText err-            Right r  -> return r-    {-# INLINE toValue #-}-    toValue t = Str (B.unsafeBuildText (B.timeOfDay t))-    {-# INLINE encodeMessagePack #-}-    encodeMessagePack t = MB.str (B.unsafeBuildText (B.timeOfDay t))---- | This instance includes a bounds check to prevent maliciously--- large inputs to fill up the memory of the target system. You can--- newtype 'NominalDiffTime' and provide your own instance using--- 'withScientific' if you want to allow larger inputs.-instance MessagePack NominalDiffTime where-    {-# INLINE fromValue #-}-    fromValue = withBoundedScientific "NominalDiffTime" $ pure . realToFrac-    {-# INLINE toValue #-}-    toValue = toValue @Scientific . realToFrac-    {-# INLINE encodeMessagePack #-}-    encodeMessagePack = encodeMessagePack @Scientific . realToFrac---- | This instance includes a bounds check to prevent maliciously--- large inputs to fill up the memory of the target system. You can--- newtype 'DiffTime' and provide your own instance using--- 'withScientific' if you want to allow larger inputs.-instance MessagePack DiffTime where-    {-# INLINE fromValue #-}-    fromValue = withBoundedScientific "DiffTime" $ pure . realToFrac-    {-# INLINE toValue #-}-    toValue = toValue @Scientific . realToFrac-    {-# INLINE encodeMessagePack #-}-    encodeMessagePack = encodeMessagePack @Scientific . realToFrac--instance MessagePack CalendarDiffTime where-    {-# INLINE fromValue #-}-    fromValue = withFlatMapR "CalendarDiffTime" $ \ v ->-        CalendarDiffTime <$> v .: "months" <*> v .: "time"-    {-# INLINE toValue #-}-    toValue (CalendarDiffTime m nt) = object [ "months" .= m , "time" .= nt ]-    {-# INLINE encodeMessagePack #-}-    encodeMessagePack (CalendarDiffTime m nt) = object' ("months" .! m <> "time" .! nt)--instance MessagePack CalendarDiffDays where-    {-# INLINE fromValue #-}-    fromValue = withFlatMapR "CalendarDiffDays" $ \ v ->-        CalendarDiffDays <$> v .: "months" <*> v .: "days"-    {-# INLINE toValue #-}-    toValue (CalendarDiffDays m d) = object ["months" .= m, "days" .= d]-    {-# INLINE encodeMessagePack #-}-    encodeMessagePack (CalendarDiffDays m d) = object' ("months" .! m <> "days" .! d)--instance MessagePack DayOfWeek where-    {-# INLINE fromValue #-}-    fromValue (Str "monday"   ) = pure Monday-    fromValue (Str "tuesday"  ) = pure Tuesday-    fromValue (Str "wednesday") = pure Wednesday-    fromValue (Str "thursday" ) = pure Thursday-    fromValue (Str "friday"   ) = pure Friday-    fromValue (Str "saturday" ) = pure Saturday-    fromValue (Str "sunday"   ) = pure Sunday-    fromValue (Str _   )        = fail' "converting DayOfWeek failed, value should be one of weekdays"-    fromValue v                 = typeMismatch "DayOfWeek" "String" v-    {-# INLINE toValue #-}-    toValue Monday    = Str "monday"-    toValue Tuesday   = Str "tuesday"-    toValue Wednesday = Str "wednesday"-    toValue Thursday  = Str "thursday"-    toValue Friday    = Str "friday"-    toValue Saturday  = Str "saturday"-    toValue Sunday    = Str "sunday"-    {-# INLINE encodeMessagePack #-}-    encodeMessagePack Monday    = MB.str "monday"-    encodeMessagePack Tuesday   = MB.str "tuesday"-    encodeMessagePack Wednesday = MB.str "wednesday"-    encodeMessagePack Thursday  = MB.str "thursday"-    encodeMessagePack Friday    = MB.str "friday"-    encodeMessagePack Saturday  = MB.str "saturday"-    encodeMessagePack Sunday    = MB.str "sunday"------------------------------------------------------------------------------------deriving newtype instance MessagePack (f (g a)) => MessagePack (Compose f g a)-deriving newtype instance MessagePack a => MessagePack (Semigroup.Min a)-deriving newtype instance MessagePack a => MessagePack (Semigroup.Max a)-deriving newtype instance MessagePack a => MessagePack (Semigroup.First a)-deriving newtype instance MessagePack a => MessagePack (Semigroup.Last a)-deriving newtype instance MessagePack a => MessagePack (Semigroup.WrappedMonoid a)-deriving newtype instance MessagePack a => MessagePack (Semigroup.Dual a)-deriving newtype instance MessagePack a => MessagePack (Monoid.First a)-deriving newtype instance MessagePack a => MessagePack (Monoid.Last a)-deriving newtype instance MessagePack a => MessagePack (Identity a)-deriving newtype instance MessagePack a => MessagePack (Const a b)-deriving newtype instance MessagePack b => MessagePack (Tagged a b)------------------------------------------------------------------------------------deriving newtype instance MessagePack CChar-deriving newtype instance MessagePack CSChar-deriving newtype instance MessagePack CUChar-deriving newtype instance MessagePack CShort-deriving newtype instance MessagePack CUShort-deriving newtype instance MessagePack CInt-deriving newtype instance MessagePack CUInt-deriving newtype instance MessagePack CLong-deriving newtype instance MessagePack CULong-deriving newtype instance MessagePack CPtrdiff-deriving newtype instance MessagePack CSize-deriving newtype instance MessagePack CWchar-deriving newtype instance MessagePack CSigAtomic-deriving newtype instance MessagePack CLLong-deriving newtype instance MessagePack CULLong-deriving newtype instance MessagePack CBool-deriving newtype instance MessagePack CIntPtr-deriving newtype instance MessagePack CUIntPtr-deriving newtype instance MessagePack CIntMax-deriving newtype instance MessagePack CUIntMax-deriving newtype instance MessagePack CClock-deriving newtype instance MessagePack CTime-deriving newtype instance MessagePack CUSeconds-deriving newtype instance MessagePack CSUSeconds-deriving newtype instance MessagePack CFloat-deriving newtype instance MessagePack CDouble------------------------------------------------------------------------------------deriving anyclass instance (MessagePack (f a), MessagePack (g a), MessagePack a) => MessagePack (Sum f g a)-deriving anyclass instance (MessagePack a, MessagePack b) => MessagePack (Either a b)-deriving anyclass instance (MessagePack (f a), MessagePack (g a)) => MessagePack (Product f g a)--deriving anyclass instance (MessagePack a, MessagePack b) => MessagePack (a, b)-deriving anyclass instance (MessagePack a, MessagePack b, MessagePack c) => MessagePack (a, b, c)-deriving anyclass instance (MessagePack a, MessagePack b, MessagePack c, MessagePack d) => MessagePack (a, b, c, d)-deriving anyclass instance (MessagePack a, MessagePack b, MessagePack c, MessagePack d, MessagePack e) => MessagePack (a, b, c, d, e)-deriving anyclass instance (MessagePack a, MessagePack b, MessagePack c, MessagePack d, MessagePack e, MessagePack f) => MessagePack (a, b, c, d, e, f)-deriving anyclass instance (MessagePack a, MessagePack b, MessagePack c, MessagePack d, MessagePack e, MessagePack f, MessagePack g) => MessagePack (a, b, c, d, e, f, g)
Z/Data/MessagePack/Builder.hs view
@@ -5,7 +5,7 @@           , (c) Dong Han 2020 License   : BSD3 -'Builder's to encode in MessagePack format.+'Builder's to encode Haskell data types in MessagePack format.  -} @@ -51,24 +51,23 @@ int :: Int64 -> B.Builder () {-# INLINE int #-} int n-    | -0x20 <= n && n < 0x80         =  B.word8 (fromIntegral n)-    | 0     <= n && n < 0x100        =  B.word8 0xCC >> B.word8 (fromIntegral n)-    | 0     <= n && n < 0x10000      =  B.word8 0xCD >> B.encodePrimBE @Word16 (fromIntegral n)-    | 0     <= n && n < 0x100000000  =  B.word8 0xCE >> B.encodePrimBE @Word32 (fromIntegral n)-    | 0     <= n                     =  B.word8 0xCF >> B.encodePrimBE @Word64 (fromIntegral n)-    | -0x80 <= n                     =  B.word8 0xD0 >> B.word8 (fromIntegral n)-    | -0x8000 <= n                   =  B.word8 0xD1 >> B.encodePrimBE @Word16 (fromIntegral n)-    | -0x80000000 <= n               =  B.word8 0xD2 >> B.encodePrimBE @Word32 (fromIntegral n)-    | otherwise                      =  B.word8 0xD3 >> B.encodePrimBE @Word64 (fromIntegral n)+    | -0x20 <= n && n < 0x80         =  B.encodePrim (fromIntegral n :: Word8)+    | 0     <= n && n < 0x100        =  B.encodePrim (0xCC :: Word8, fromIntegral n :: Word8)+    | 0     <= n && n < 0x10000      =  B.encodePrim (0xCD :: Word8, BE (fromIntegral n :: Word16))+    | 0     <= n && n < 0x100000000  =  B.encodePrim (0xCE :: Word8, BE (fromIntegral n :: Word32))+    | 0     <= n                     =  B.encodePrim (0xCF :: Word8, BE (fromIntegral n :: Word64))+    | -0x80 <= n                     =  B.encodePrim (0xD0 :: Word8, fromIntegral n :: Word8)+    | -0x8000 <= n                   =  B.encodePrim (0xD1 :: Word8, BE (fromIntegral n :: Word16))+    | -0x80000000 <= n               =  B.encodePrim (0xD2 :: Word8, BE (fromIntegral n :: Word32))+    | otherwise                      =  B.encodePrim (0xD3 :: Word8, BE (fromIntegral n :: Word64))  float :: Float -> B.Builder () {-# INLINE float #-}-float f = B.word8 0xCA >> B.encodePrimBE f+float f = B.encodePrim (0xCA :: Word8, BE f)  double :: Double -> B.Builder () {-# INLINE double #-}-double d = B.word8 0xCB >> B.encodePrimBE d-+double d = B.encodePrim (0xCB :: Word8, BE d)  -- | Construct a scientific value, see 'scientific'. scientificValue :: Integer -> Int64 -> Value@@ -93,7 +92,7 @@ --  +--------+--------+--------+-----------------------------------------+---------------------------------------+ -- scientific :: Integer -> Int64 -> B.Builder ()-{-# INLINE scientific #-}+{-# INLINABLE scientific #-} scientific 0 _ = B.encodePrim @(Word8, Word8, Word8, Word8) (0xD5, 0x00, 0x00, 0x00) scientific c e = do     case (I# (word2Int# siz#)) + intSiz e of@@ -102,9 +101,9 @@         4 -> B.word8 0xD6         8 -> B.word8 0xD7         16 -> B.word8 0xD8-        siz' | siz' < 0x100   -> B.word8 0xC7 >> B.word8 (fromIntegral siz')-             | siz' < 0x10000 -> B.word8 0xC8 >> B.encodePrimBE @Word16 (fromIntegral siz')-             | otherwise      -> B.word8 0xC9 >> B.encodePrimBE @Word32 (fromIntegral siz')+        siz' | siz' < 0x100   -> B.encodePrim (0xC7 :: Word8, fromIntegral siz' :: Word8)+             | siz' < 0x10000 -> B.encodePrim (0xC8 :: Word8, BE (fromIntegral siz' :: Word16))+             | otherwise      -> B.encodePrim (0xC9 :: Word8, BE (fromIntegral siz' :: Word32))     B.word8 (if c > 0 then 0x00 else 0x01)     int e     B.writeN (I# (word2Int# siz#)) $ \ (MutablePrimArray mba#) (I# off#) ->@@ -126,12 +125,13 @@ -- | Construct a timestamp(seconds, nanoseconds) value. timestampValue :: Int64 -> Int32 -> Value {-# INLINE timestampValue #-}-timestampValue s ns = Ext 0xFF (B.build $ B.encodePrimBE ns >> B.encodePrimBE s)+timestampValue s ns = Ext 0xFF (B.build $ B.encodePrim (BE ns, BE s))  -- | Write a timestamp(seconds, nanoseconds) in ext 0xFF format, e.g. timestamp :: Int64 -> Int32 -> B.Builder () {-# INLINE timestamp #-}-timestamp s ns = B.encodePrim @(Word8, Word8, Word8, (BE Int32), (BE Int64)) (0xC7, 0x0C, 0xFF, (BE ns), (BE s))+timestamp s ns = B.encodePrim+    (0xC7 :: Word8, 0x0C :: Word8, 0xFF :: Word8, (BE ns :: BE Int32), (BE s :: BE Int64))  str' :: String -> B.Builder () {-# INLINE str' #-}@@ -143,18 +143,18 @@     let bs = T.getUTF8Bytes t     case V.length bs of         len | len <= 31      ->  B.word8 (0xA0 .|. fromIntegral len)-            | len < 0x100    ->  B.word8 0xD9 >> B.word8 (fromIntegral len)-            | len < 0x10000  ->  B.word8 0xDA >> B.encodePrimBE @Word16 (fromIntegral len)-            | otherwise      ->  B.word8 0xDB >> B.encodePrimBE @Word32 (fromIntegral len)+            | len < 0x100    ->  B.encodePrim (0xD9 :: Word8, fromIntegral len :: Word8)+            | len < 0x10000  ->  B.encodePrim (0xDA :: Word8, BE (fromIntegral len :: Word16))+            | otherwise      ->  B.encodePrim (0xDB :: Word8, BE (fromIntegral len :: Word32))     B.bytes bs  bin :: V.Bytes -> B.Builder () {-# INLINE bin #-} bin bs = do     case V.length bs of-        len | len < 0x100    ->  B.word8 0xC4 >> B.word8 (fromIntegral len)-            | len < 0x10000  ->  B.word8 0xC5 >> B.encodePrimBE @Word16 (fromIntegral len)-            | otherwise      ->  B.word8 0xC6 >> B.encodePrimBE @Word32 (fromIntegral len)+        len | len < 0x100    ->  B.encodePrim (0xC4 :: Word8, fromIntegral len :: Word8)+            | len < 0x10000  ->  B.encodePrim (0xC5 :: Word8, BE (fromIntegral len :: Word16))+            | otherwise      ->  B.encodePrim (0xC6 :: Word8, BE (fromIntegral len :: Word32))     B.bytes bs  array :: V.Vec v a => (a -> B.Builder ()) -> v a -> B.Builder ()@@ -173,8 +173,8 @@ {-# INLINE arrayHeader #-} arrayHeader len     | len <= 15      =  B.word8 (0x90 .|. fromIntegral len)-    | len < 0x10000  =  B.word8 0xDC >> B.encodePrimBE @Word16 (fromIntegral len)-    | otherwise      =  B.word8 0xDD >> B.encodePrimBE @Word32 (fromIntegral len)+    | len < 0x10000  =  B.encodePrim (0xDC :: Word8, BE (fromIntegral len :: Word16))+    | otherwise      =  B.encodePrim (0xDD :: Word8, BE (fromIntegral len :: Word32))  map :: (a -> B.Builder ()) -> (b -> B.Builder ()) -> V.Vector (a, b) -> B.Builder () {-# INLINE map #-}@@ -192,8 +192,8 @@ {-# INLINE mapHeader #-} mapHeader len     | len <= 15      =  B.word8 (0x80 .|. fromIntegral len)-    | len < 0x10000  =  B.word8 0xDE >> B.encodePrimBE @Word16 (fromIntegral len)-    | otherwise      =  B.word8 0xDF >> B.encodePrimBE @Word32 (fromIntegral len)+    | len < 0x10000  =  B.encodePrim (0xDE :: Word8, BE (fromIntegral len :: Word16))+    | otherwise      =  B.encodePrim (0xDF :: Word8, BE (fromIntegral len :: Word32))  ext :: Word8 -> V.Bytes -> B.Builder () {-# INLINABLE ext #-}@@ -204,8 +204,8 @@         4  -> B.word8 0xD6         8  -> B.word8 0xD7         16 -> B.word8 0xD8-        len | len < 0x100   -> B.word8 0xC7 >> B.word8 (fromIntegral len)-            | len < 0x10000 -> B.word8 0xC8 >> B.encodePrimBE @Word16 (fromIntegral len)-            | otherwise     -> B.word8 0xC9 >> B.encodePrimBE @Word32 (fromIntegral len)+        len | len < 0x100   -> B.encodePrim (0xC7 :: Word8, fromIntegral len :: Word8)+            | len < 0x10000 -> B.encodePrim (0xC8 :: Word8, BE (fromIntegral len :: Word16))+            | otherwise     -> B.encodePrim (0xC9 :: Word8, BE (fromIntegral len :: Word32))     B.word8 typ     B.bytes dat
Z/Data/MessagePack/Value.hs view
@@ -8,7 +8,7 @@ module Z.Data.MessagePack.Value(   -- * MessagePack Value     Value(..)-    -- * parse into Message Value+    -- * parse into MessagePack Value   , parseValue   , parseValue'   , parseValueChunks@@ -29,7 +29,6 @@ import qualified Z.Data.Text                as T import qualified Z.Data.Parser              as P import qualified Z.Data.Vector              as V-  -- | Representation of MessagePack data. data Value
+ Z/IO/RPC/MessagePack.hs view
@@ -0,0 +1,272 @@+{-|+Module      : Z.Data.MessagePack+Description : Fast MessagePack serialization/deserialization+Copyright   : (c) Dong Han, 2019+License     : BSD+Maintainer  : winterland1989@gmail.com+Stability   : experimental+Portability : non-portable++This module provides <https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md MessagePack-RPC> implementation.++@+-- server+import Z.IO.RPC.MessagePack+import Z.IO.Network+import Z.IO+import qualified Z.Data.Text as T++serveRPC (startTCPServer defaultTCPServerConfig) . simpleRouter $+ [ ("foo", CallHandler $ \\ (req :: Int) -> do+     return (req + 1))+ , ("bar", NotifyHandler $ \\ (req :: T.Text) -> do+     printStd (req <> "world"))+ ]++-- client+import Z.IO.RPC.MessagePack+import Z.IO.Network+import Z.IO+import qualified Z.Data.Text as T++withResource (initTCPClient defaultTCPClientConfig) $ \\ uvs -> do+    c <- rpcClient uvs+    call \@Int \@Int c "foo" 1+    call \@T.Text \@T.Text c "bar" "hello"+@++-}++module Z.IO.RPC.MessagePack where++import           Control.Monad+import           Data.Bits+import           Z.Data.PrimRef.PrimIORef+import qualified Z.Data.MessagePack.Builder as MB+import qualified Z.Data.MessagePack.Value   as MV+import           Z.Data.MessagePack         (MessagePack)+import qualified Z.Data.MessagePack         as MP+import qualified Z.Data.Parser              as P+import qualified Z.Data.Text                as T+import qualified Z.Data.Vector.FlatIntMap   as FIM+import qualified Z.Data.Vector.FlatMap      as FM+import qualified Z.Data.Vector              as V+import           Z.IO+import           Z.IO.Network++data Client = Client+    { _clientSeqRef :: Counter+    , _clientPipelineReqNum :: Counter+    , _clientBufferedInput :: BufferedInput+    , _clientBufferedOutput :: BufferedOutput+    }++-- | Open a RPC client from input/output device.+rpcClient :: (Input dev, Output dev) => dev -> IO Client+rpcClient uvs = rpcClient' uvs uvs V.defaultChunkSize V.defaultChunkSize++-- | Open a RPC client with more control.+rpcClient' :: (Input i, Output o)+              => i+              -> o+              -> Int          -- ^ recv buffer size+              -> Int          -- ^ send buffer size+              -> IO Client+rpcClient' i o recvBufSiz sendBufSiz = do+    seqRef <- newCounter 0+    reqNum <- newCounter 0+    bi <- newBufferedInput' recvBufSiz i+    bo <- newBufferedOutput' sendBufSiz o+    return (Client seqRef reqNum bi bo)++-- | Send a single RPC call and get result.+call:: (MessagePack req, MessagePack res) => Client -> T.Text -> req -> IO res+call cli name req = do+    msgid <- callPipeline cli name req+    fetchPipeline msgid =<< execPipeline cli++-- | Send a single notification RPC call without getting result.+notify :: MessagePack req => Client -> T.Text -> req -> IO ()+notify c@(Client _ _ _ bo) name req = notifyPipeline c name req >> flushBuffer bo++type PipelineId = Int+type PipelineResult = FIM.FlatIntMap MV.Value++-- | Make a call inside a pipeline, which will be sent in batch when `execPipeline`.+--+-- @+--  ...+--  fooId <- callPipeline client "foo" $ ...+--  barId <- callPipeline client "bar" $ ...+--  notifyPipeline client "qux" $ ...+--+--  r <- execPipeline client+--+--  fooResult <- fetchPipeline fooId r+--  barResult <- fetchPipeline barId r+-- @+--+callPipeline :: HasCallStack => MessagePack req => Client -> T.Text -> req -> IO PipelineId+callPipeline (Client seqRef reqNum _ bo) name req = do+    msgid <- readPrimIORef seqRef+    writePrimIORef seqRef (msgid+1)+    modifyPrimIORef reqNum (+1)+    let !msgid' = msgid .&. 0xFFFFFFFF  -- shrink to unsiged 32bits+    writeBuilder bo $ do+        MB.arrayHeader 4+        MB.int 0                        -- type request+        MB.int (fromIntegral msgid')    -- msgid+        MB.str name                     -- method name+        MP.encodeMessagePack req        -- param+    return msgid'++-- | Make a notify inside a pipeline, which will be sent in batch when `execPipeline`.+--+-- Notify calls doesn't affect execution's result.+notifyPipeline :: HasCallStack => MessagePack req => Client -> T.Text -> req -> IO ()+notifyPipeline (Client _ _ _ bo) name req = do+    writeBuilder bo $ do+        MB.arrayHeader 3+        MB.int 2                        -- type notification+        MB.str name                     -- method name+        MP.encodeMessagePack req        -- param++-- | Exception thrown when remote endpoint return errors.+data RPCException = RPCException MV.Value CallStack deriving Show+instance Exception RPCException++-- | Sent request in batch and get result in a map identified by 'PipelineId'.+execPipeline :: HasCallStack => Client -> IO PipelineResult+execPipeline (Client _ reqNum bi bo) = do+    flushBuffer bo+    n <- readPrimIORef reqNum+    writePrimIORef reqNum 0+    FIM.packN n <$> replicateM n (do+        (msgid, err, v) <- readParser (do+            tag <- P.anyWord8+            when (tag /= 0x94) (P.fail' $ "wrong response tag: " <> T.toText tag)+            !typ <- MV.value+            !seq <- MV.value+            !err <- MV.value+            !v <- MV.value+            case typ of+                MV.Int 1 -> case seq of+                    MV.Int msgid | msgid >= 0 && msgid <= 0xFFFFFFFF ->+                        return (msgid, err, v)+                    _ -> P.fail' $ "wrong msgid: " <> T.toText seq+                _ -> P.fail' $ "wrong response type: " <> T.toText typ+            ) bi+        when (err /= MV.Nil) $ throwIO (RPCException err callStack)+        return (V.IPair (fromIntegral msgid) v))++-- | Use the `PipelineId` returned when `callPipeline` to fetch call's result.+fetchPipeline :: HasCallStack => MessagePack res => PipelineId -> PipelineResult -> IO res+fetchPipeline msgid r = do+    unwrap "EPARSE" . MP.convertValue =<<+        unwrap' "ENOMSG" ("missing message in response: " <> T.toText msgid)+            (FIM.lookup msgid r)++--------------------------------------------------------------------------------++type ServerLoop = (UVStream -> IO ()) -> IO ()+type ServerService = T.Text -> Maybe ServerHandler+data ServerHandler where+    CallHandler :: (MessagePack req, MessagePack res) => (req -> IO res) -> ServerHandler+    NotifyHandler :: MessagePack req => (req -> IO ()) -> ServerHandler++-- | Simple router using `FlatMap`, lookup name in /O(log(N))/.+--+-- @+-- import Z.IO.PRC.MessagePack+-- import Z.IO.Network+-- import Z.IO+--+-- serveRPC (startTCPServer defaultTCPServerConfig) . simpleRouter $+--  [ ("foo", CallHandler $ \\ req -> do+--      ... )+--  , ("bar", CallHandler $ \\ req -> do+--      ... )+--  ]+--+-- @+simpleRouter :: [(T.Text, ServerHandler)] -> ServerService+simpleRouter handles name = FM.lookup name handleMap+  where+    handleMap = FM.packR handles++-- | Serve a RPC service.+serveRPC :: ServerLoop -> ServerService -> IO ()+serveRPC serve = serveRPC' serve V.defaultChunkSize V.defaultChunkSize++-- | Serve a RPC service with more control.+serveRPC' :: ServerLoop+          -> Int          -- ^ recv buffer size+          -> Int          -- ^ send buffer size+          -> ServerService -> IO ()+serveRPC' serve recvBufSiz sendBufSiz handle = serve $ \ uvs -> do+    bi <- newBufferedInput' recvBufSiz uvs+    bo <- newBufferedOutput' sendBufSiz uvs+    loop bi bo+  where+    loop bi bo = do+        req <- pull (sourceParserFromBuffered (do+            tag <- P.anyWord8+            case tag of+                -- notify+                0x93 -> do+                    !typ <- MV.value+                    !name <- MV.value+                    !v <- MV.value+                    case typ of+                        MV.Int 2 -> case name of+                            MV.Str name' -> return (Left (name', v))+                            _ -> P.fail' $ "wrong RPC name: " <> T.toText name+                        _ -> P.fail' $ "wrong notification type: " <> T.toText typ+                -- call+                0x94 -> do+                    !typ <- MV.value+                    !seq <- MV.value+                    !name <- MV.value+                    !v <- MV.value+                    case typ of+                        MV.Int 0 -> case seq of+                            MV.Int msgid | msgid >= 0 && msgid <= 0xFFFFFFFF -> case name of+                                MV.Str name' -> return (Right (msgid, name', v))+                                _ -> P.fail' $ "wrong RPC name: " <> T.toText name+                            _ -> P.fail' $ "wrong msgid: " <> T.toText seq+                        _ -> P.fail' $ "wrong request type: " <> T.toText typ+                _ -> P.fail' $ "wrong request tag: " <> T.toText tag+            ) bi)+        case req of+            Just (Left (name, v)) -> do+                case handle name of+                    Just (NotifyHandler f) -> do+                        f =<< unwrap "EPARSE" (MP.convertValue v)+                    _ -> throwOtherError "ENOTFOUND" "notification method not found"+                loop bi bo+            Just (Right (msgid, name, v)) -> do+                case handle name of+                    Just (CallHandler f) -> do+                        res <- try (f =<< unwrap "EPARSE" (MP.convertValue v))+                        writeBuilder bo $ do+                            MB.arrayHeader 4+                            MB.int 1                        -- type response+                            MB.int (fromIntegral msgid)     -- msgid+                            case res of+                                Left e -> do+                                    MB.str (T.pack $ show (e :: SomeException))+                                    MB.nil+                                Right res -> do+                                    MB.nil+                                    MP.encodeMessagePack res+                        flushBuffer bo+                    _ -> do+                        writeBuilder bo $ do+                            MB.arrayHeader 4+                            MB.int 1                        -- type response+                            MB.int (fromIntegral msgid)     -- msgid+                            MB.str $ "request method: " <> name <> " not found"+                            MB.nil+                        flushBuffer bo+                loop bi bo+            _ -> return ()