{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-} {- | Module : Neovim.RPC.Classes Description : Data types and classes for the RPC components Copyright : (c) Sebastian Witte License : Apache-2.0 Maintainer : woozletoff@gmail.com Stability : experimental Portability : GHC Import this module qualified as @MsgpackRPC@ -} module Neovim.RPC.Classes ( Message (..), ) where import Neovim.Classes import Neovim.Plugin.Classes (FunctionName (..), NeovimEventId (..)) import qualified Neovim.Plugin.IPC.Classes as IPC import Control.Applicative import Control.Monad.Error.Class import Data.Data (Typeable) import Data.MessagePack (Object (..)) import Prettyprinter (hardline, nest, viaShow) import Prelude {- | See https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md for details about the msgpack rpc specification. -} data Message = -- | Request in the sense of the msgpack rpc specification -- -- Parameters -- * Message identifier that has to be put in the response to this request -- * Function name -- * Function arguments Request IPC.Request | -- | Response in the sense of the msgpack rpc specifcation -- -- Parameters -- * Mesage identifier which matches a request -- * 'Either' an error 'Object' or a result 'Object' Response !Int64 (Either Object Object) | -- | Notification in the sense of the msgpack rpc specification Notification IPC.Notification deriving (Eq, Ord, Show, Typeable, Generic) instance NFData Message instance IPC.Message Message instance NvimObject Message where toObject = \case Request (IPC.Request (F m) i ps) -> ObjectArray $ (0 :: Int64) +: i +: m +: ps +: [] Response i (Left e) -> ObjectArray $ (1 :: Int64) +: i +: e +: () +: [] Response i (Right r) -> ObjectArray $ (1 :: Int64) +: i +: () +: r +: [] Notification (IPC.Notification (NeovimEventId eventId) ps) -> ObjectArray $ (2 :: Int64) +: eventId +: ps +: [] fromObject = \case ObjectArray [ObjectInt 0, i, m, ps] -> do r <- IPC.Request <$> fmap F (fromObject m) <*> fromObject i <*> fromObject ps return $ Request r ObjectArray [ObjectInt 1, i, e, r] -> let eer = case e of ObjectNil -> Right r _ -> Left e in Response <$> fromObject i <*> pure eer ObjectArray [ObjectInt 2, m, ps] -> do n <- IPC.Notification <$> fmap NeovimEventId (fromObject m) <*> fromObject ps return $ Notification n o -> throwError $ "Not a known/valid msgpack-rpc message:" <+> viaShow o instance Pretty Message where pretty = \case Request request -> pretty request Response i ret -> nest 2 $ "Response" <+> "#" <> pretty i <> hardline <> either viaShow viaShow ret Notification notification -> pretty notification