module Ribosome.Host.Data.Request where

import Data.MessagePack (Object (ObjectArray))
import Exon (exon)

import Ribosome.Host.Class.Msgpack.Decode (MsgpackDecode)
import Ribosome.Host.Class.Msgpack.Encode (MsgpackEncode (toMsgpack))

newtype RpcMethod =
  RpcMethod { RpcMethod -> Text
unRpcMethod :: Text }
  deriving stock (RpcMethod -> RpcMethod -> Bool
(RpcMethod -> RpcMethod -> Bool)
-> (RpcMethod -> RpcMethod -> Bool) -> Eq RpcMethod
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RpcMethod -> RpcMethod -> Bool
$c/= :: RpcMethod -> RpcMethod -> Bool
== :: RpcMethod -> RpcMethod -> Bool
$c== :: RpcMethod -> RpcMethod -> Bool
Eq, Int -> RpcMethod -> ShowS
[RpcMethod] -> ShowS
RpcMethod -> String
(Int -> RpcMethod -> ShowS)
-> (RpcMethod -> String)
-> ([RpcMethod] -> ShowS)
-> Show RpcMethod
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [RpcMethod] -> ShowS
$cshowList :: [RpcMethod] -> ShowS
show :: RpcMethod -> String
$cshow :: RpcMethod -> String
showsPrec :: Int -> RpcMethod -> ShowS
$cshowsPrec :: Int -> RpcMethod -> ShowS
Show, (forall x. RpcMethod -> Rep RpcMethod x)
-> (forall x. Rep RpcMethod x -> RpcMethod) -> Generic RpcMethod
forall x. Rep RpcMethod x -> RpcMethod
forall x. RpcMethod -> Rep RpcMethod x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep RpcMethod x -> RpcMethod
$cfrom :: forall x. RpcMethod -> Rep RpcMethod x
Generic)
  deriving newtype (String -> RpcMethod
(String -> RpcMethod) -> IsString RpcMethod
forall a. (String -> a) -> IsString a
fromString :: String -> RpcMethod
$cfromString :: String -> RpcMethod
IsString, Eq RpcMethod
Eq RpcMethod
-> (RpcMethod -> RpcMethod -> Ordering)
-> (RpcMethod -> RpcMethod -> Bool)
-> (RpcMethod -> RpcMethod -> Bool)
-> (RpcMethod -> RpcMethod -> Bool)
-> (RpcMethod -> RpcMethod -> Bool)
-> (RpcMethod -> RpcMethod -> RpcMethod)
-> (RpcMethod -> RpcMethod -> RpcMethod)
-> Ord RpcMethod
RpcMethod -> RpcMethod -> Bool
RpcMethod -> RpcMethod -> Ordering
RpcMethod -> RpcMethod -> RpcMethod
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: RpcMethod -> RpcMethod -> RpcMethod
$cmin :: RpcMethod -> RpcMethod -> RpcMethod
max :: RpcMethod -> RpcMethod -> RpcMethod
$cmax :: RpcMethod -> RpcMethod -> RpcMethod
>= :: RpcMethod -> RpcMethod -> Bool
$c>= :: RpcMethod -> RpcMethod -> Bool
> :: RpcMethod -> RpcMethod -> Bool
$c> :: RpcMethod -> RpcMethod -> Bool
<= :: RpcMethod -> RpcMethod -> Bool
$c<= :: RpcMethod -> RpcMethod -> Bool
< :: RpcMethod -> RpcMethod -> Bool
$c< :: RpcMethod -> RpcMethod -> Bool
compare :: RpcMethod -> RpcMethod -> Ordering
$ccompare :: RpcMethod -> RpcMethod -> Ordering
Ord, Object -> Either DecodeError RpcMethod
(Object -> Either DecodeError RpcMethod) -> MsgpackDecode RpcMethod
forall a. (Object -> Either DecodeError a) -> MsgpackDecode a
fromMsgpack :: Object -> Either DecodeError RpcMethod
$cfromMsgpack :: Object -> Either DecodeError RpcMethod
MsgpackDecode, RpcMethod -> Object
(RpcMethod -> Object) -> MsgpackEncode RpcMethod
forall a. (a -> Object) -> MsgpackEncode a
toMsgpack :: RpcMethod -> Object
$ctoMsgpack :: RpcMethod -> Object
MsgpackEncode, NonEmpty RpcMethod -> RpcMethod
RpcMethod -> RpcMethod -> RpcMethod
(RpcMethod -> RpcMethod -> RpcMethod)
-> (NonEmpty RpcMethod -> RpcMethod)
-> (forall b. Integral b => b -> RpcMethod -> RpcMethod)
-> Semigroup RpcMethod
forall b. Integral b => b -> RpcMethod -> RpcMethod
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
stimes :: forall b. Integral b => b -> RpcMethod -> RpcMethod
$cstimes :: forall b. Integral b => b -> RpcMethod -> RpcMethod
sconcat :: NonEmpty RpcMethod -> RpcMethod
$csconcat :: NonEmpty RpcMethod -> RpcMethod
<> :: RpcMethod -> RpcMethod -> RpcMethod
$c<> :: RpcMethod -> RpcMethod -> RpcMethod
Semigroup, Semigroup RpcMethod
RpcMethod
Semigroup RpcMethod
-> RpcMethod
-> (RpcMethod -> RpcMethod -> RpcMethod)
-> ([RpcMethod] -> RpcMethod)
-> Monoid RpcMethod
[RpcMethod] -> RpcMethod
RpcMethod -> RpcMethod -> RpcMethod
forall a.
Semigroup a -> a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
mconcat :: [RpcMethod] -> RpcMethod
$cmconcat :: [RpcMethod] -> RpcMethod
mappend :: RpcMethod -> RpcMethod -> RpcMethod
$cmappend :: RpcMethod -> RpcMethod -> RpcMethod
mempty :: RpcMethod
$cmempty :: RpcMethod
Monoid)

newtype RequestId =
  RequestId { RequestId -> Int64
unRequestId :: Int64 }
  deriving stock (RequestId -> RequestId -> Bool
(RequestId -> RequestId -> Bool)
-> (RequestId -> RequestId -> Bool) -> Eq RequestId
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RequestId -> RequestId -> Bool
$c/= :: RequestId -> RequestId -> Bool
== :: RequestId -> RequestId -> Bool
$c== :: RequestId -> RequestId -> Bool
Eq, Int -> RequestId -> ShowS
[RequestId] -> ShowS
RequestId -> String
(Int -> RequestId -> ShowS)
-> (RequestId -> String)
-> ([RequestId] -> ShowS)
-> Show RequestId
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [RequestId] -> ShowS
$cshowList :: [RequestId] -> ShowS
show :: RequestId -> String
$cshow :: RequestId -> String
showsPrec :: Int -> RequestId -> ShowS
$cshowsPrec :: Int -> RequestId -> ShowS
Show, (forall x. RequestId -> Rep RequestId x)
-> (forall x. Rep RequestId x -> RequestId) -> Generic RequestId
forall x. Rep RequestId x -> RequestId
forall x. RequestId -> Rep RequestId x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep RequestId x -> RequestId
$cfrom :: forall x. RequestId -> Rep RequestId x
Generic)
  deriving newtype (Integer -> RequestId
RequestId -> RequestId
RequestId -> RequestId -> RequestId
(RequestId -> RequestId -> RequestId)
-> (RequestId -> RequestId -> RequestId)
-> (RequestId -> RequestId -> RequestId)
-> (RequestId -> RequestId)
-> (RequestId -> RequestId)
-> (RequestId -> RequestId)
-> (Integer -> RequestId)
-> Num RequestId
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> RequestId
$cfromInteger :: Integer -> RequestId
signum :: RequestId -> RequestId
$csignum :: RequestId -> RequestId
abs :: RequestId -> RequestId
$cabs :: RequestId -> RequestId
negate :: RequestId -> RequestId
$cnegate :: RequestId -> RequestId
* :: RequestId -> RequestId -> RequestId
$c* :: RequestId -> RequestId -> RequestId
- :: RequestId -> RequestId -> RequestId
$c- :: RequestId -> RequestId -> RequestId
+ :: RequestId -> RequestId -> RequestId
$c+ :: RequestId -> RequestId -> RequestId
Num, Num RequestId
Ord RequestId
Num RequestId
-> Ord RequestId -> (RequestId -> Rational) -> Real RequestId
RequestId -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
toRational :: RequestId -> Rational
$ctoRational :: RequestId -> Rational
Real, Int -> RequestId
RequestId -> Int
RequestId -> [RequestId]
RequestId -> RequestId
RequestId -> RequestId -> [RequestId]
RequestId -> RequestId -> RequestId -> [RequestId]
(RequestId -> RequestId)
-> (RequestId -> RequestId)
-> (Int -> RequestId)
-> (RequestId -> Int)
-> (RequestId -> [RequestId])
-> (RequestId -> RequestId -> [RequestId])
-> (RequestId -> RequestId -> [RequestId])
-> (RequestId -> RequestId -> RequestId -> [RequestId])
-> Enum RequestId
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: RequestId -> RequestId -> RequestId -> [RequestId]
$cenumFromThenTo :: RequestId -> RequestId -> RequestId -> [RequestId]
enumFromTo :: RequestId -> RequestId -> [RequestId]
$cenumFromTo :: RequestId -> RequestId -> [RequestId]
enumFromThen :: RequestId -> RequestId -> [RequestId]
$cenumFromThen :: RequestId -> RequestId -> [RequestId]
enumFrom :: RequestId -> [RequestId]
$cenumFrom :: RequestId -> [RequestId]
fromEnum :: RequestId -> Int
$cfromEnum :: RequestId -> Int
toEnum :: Int -> RequestId
$ctoEnum :: Int -> RequestId
pred :: RequestId -> RequestId
$cpred :: RequestId -> RequestId
succ :: RequestId -> RequestId
$csucc :: RequestId -> RequestId
Enum, Enum RequestId
Real RequestId
Real RequestId
-> Enum RequestId
-> (RequestId -> RequestId -> RequestId)
-> (RequestId -> RequestId -> RequestId)
-> (RequestId -> RequestId -> RequestId)
-> (RequestId -> RequestId -> RequestId)
-> (RequestId -> RequestId -> (RequestId, RequestId))
-> (RequestId -> RequestId -> (RequestId, RequestId))
-> (RequestId -> Integer)
-> Integral RequestId
RequestId -> Integer
RequestId -> RequestId -> (RequestId, RequestId)
RequestId -> RequestId -> RequestId
forall a.
Real a
-> Enum a
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
toInteger :: RequestId -> Integer
$ctoInteger :: RequestId -> Integer
divMod :: RequestId -> RequestId -> (RequestId, RequestId)
$cdivMod :: RequestId -> RequestId -> (RequestId, RequestId)
quotRem :: RequestId -> RequestId -> (RequestId, RequestId)
$cquotRem :: RequestId -> RequestId -> (RequestId, RequestId)
mod :: RequestId -> RequestId -> RequestId
$cmod :: RequestId -> RequestId -> RequestId
div :: RequestId -> RequestId -> RequestId
$cdiv :: RequestId -> RequestId -> RequestId
rem :: RequestId -> RequestId -> RequestId
$crem :: RequestId -> RequestId -> RequestId
quot :: RequestId -> RequestId -> RequestId
$cquot :: RequestId -> RequestId -> RequestId
Integral, Eq RequestId
Eq RequestId
-> (RequestId -> RequestId -> Ordering)
-> (RequestId -> RequestId -> Bool)
-> (RequestId -> RequestId -> Bool)
-> (RequestId -> RequestId -> Bool)
-> (RequestId -> RequestId -> Bool)
-> (RequestId -> RequestId -> RequestId)
-> (RequestId -> RequestId -> RequestId)
-> Ord RequestId
RequestId -> RequestId -> Bool
RequestId -> RequestId -> Ordering
RequestId -> RequestId -> RequestId
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: RequestId -> RequestId -> RequestId
$cmin :: RequestId -> RequestId -> RequestId
max :: RequestId -> RequestId -> RequestId
$cmax :: RequestId -> RequestId -> RequestId
>= :: RequestId -> RequestId -> Bool
$c>= :: RequestId -> RequestId -> Bool
> :: RequestId -> RequestId -> Bool
$c> :: RequestId -> RequestId -> Bool
<= :: RequestId -> RequestId -> Bool
$c<= :: RequestId -> RequestId -> Bool
< :: RequestId -> RequestId -> Bool
$c< :: RequestId -> RequestId -> Bool
compare :: RequestId -> RequestId -> Ordering
$ccompare :: RequestId -> RequestId -> Ordering
Ord, Object -> Either DecodeError RequestId
(Object -> Either DecodeError RequestId) -> MsgpackDecode RequestId
forall a. (Object -> Either DecodeError a) -> MsgpackDecode a
fromMsgpack :: Object -> Either DecodeError RequestId
$cfromMsgpack :: Object -> Either DecodeError RequestId
MsgpackDecode, RequestId -> Object
(RequestId -> Object) -> MsgpackEncode RequestId
forall a. (a -> Object) -> MsgpackEncode a
toMsgpack :: RequestId -> Object
$ctoMsgpack :: RequestId -> Object
MsgpackEncode)

-- |The payload of an RPC request.
data Request =
  Request {
    -- |The method, which is either the Neovim API function name or the internal identifier of a Ribosome handler.
    Request -> RpcMethod
method :: RpcMethod,
    -- |The arguments.
    Request -> [Object]
arguments :: [Object]
  }
  deriving stock (Request -> Request -> Bool
(Request -> Request -> Bool)
-> (Request -> Request -> Bool) -> Eq Request
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Request -> Request -> Bool
$c/= :: Request -> Request -> Bool
== :: Request -> Request -> Bool
$c== :: Request -> Request -> Bool
Eq, Int -> Request -> ShowS
[Request] -> ShowS
Request -> String
(Int -> Request -> ShowS)
-> (Request -> String) -> ([Request] -> ShowS) -> Show Request
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Request] -> ShowS
$cshowList :: [Request] -> ShowS
show :: Request -> String
$cshow :: Request -> String
showsPrec :: Int -> Request -> ShowS
$cshowsPrec :: Int -> Request -> ShowS
Show, (forall x. Request -> Rep Request x)
-> (forall x. Rep Request x -> Request) -> Generic Request
forall x. Rep Request x -> Request
forall x. Request -> Rep Request x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Request x -> Request
$cfrom :: forall x. Request -> Rep Request x
Generic)

instance MsgpackEncode Request where
  toMsgpack :: Request -> Object
toMsgpack (Request RpcMethod
m [Object]
p) =
    [Object] -> Object
ObjectArray [RpcMethod -> Object
forall a. MsgpackEncode a => a -> Object
toMsgpack RpcMethod
m, [Object] -> Object
forall a. MsgpackEncode a => a -> Object
toMsgpack [Object]
p]

-- |An RPC request, which is a payload combined with a request ID.
data TrackedRequest =
  TrackedRequest {
    -- |The ID is used to associate the response with the sender.
    TrackedRequest -> RequestId
id :: RequestId,
    -- |The payload.
    TrackedRequest -> Request
request :: Request
  }
  deriving stock (TrackedRequest -> TrackedRequest -> Bool
(TrackedRequest -> TrackedRequest -> Bool)
-> (TrackedRequest -> TrackedRequest -> Bool) -> Eq TrackedRequest
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TrackedRequest -> TrackedRequest -> Bool
$c/= :: TrackedRequest -> TrackedRequest -> Bool
== :: TrackedRequest -> TrackedRequest -> Bool
$c== :: TrackedRequest -> TrackedRequest -> Bool
Eq, Int -> TrackedRequest -> ShowS
[TrackedRequest] -> ShowS
TrackedRequest -> String
(Int -> TrackedRequest -> ShowS)
-> (TrackedRequest -> String)
-> ([TrackedRequest] -> ShowS)
-> Show TrackedRequest
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TrackedRequest] -> ShowS
$cshowList :: [TrackedRequest] -> ShowS
show :: TrackedRequest -> String
$cshow :: TrackedRequest -> String
showsPrec :: Int -> TrackedRequest -> ShowS
$cshowsPrec :: Int -> TrackedRequest -> ShowS
Show)

formatReq :: Request -> Text
formatReq :: Request -> Text
formatReq (Request (RpcMethod Text
method) [Object]
args) =
  [exon|#{method} #{show args}|]

formatTrackedReq :: TrackedRequest -> Text
formatTrackedReq :: TrackedRequest -> Text
formatTrackedReq (TrackedRequest (RequestId Int64
i) Request
req) =
  [exon|<#{show i}> #{formatReq req}|]