{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-} {- | 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 (..)) import qualified Neovim.Plugin.IPC.Classes as IPC import Control.Applicative import Control.Monad.Error.Class import Data.Data (Typeable) import Data.Int (Int64) import Data.MessagePack (Object (..)) import Data.Text.Prettyprint.Doc (Pretty (..), 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 IPC.Request -- ^ 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 | Response !Int64 (Either Object Object) -- ^ Response in the sense of the msgpack rpc specifcation -- -- Parameters -- * Mesage identifier which matches a request -- * 'Either' an error 'Object' or a result 'Object' | Notification IPC.Notification -- ^ Notification in the sense of the msgpack rpc specification 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 (F m) ps) -> ObjectArray $ (2 :: Int64) +: m +: 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 F (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