msgpack_rpc_stream.lua 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. local mpack = vim.mpack
  2. local Response = {}
  3. Response.__index = Response
  4. function Response.new(msgpack_rpc_stream, request_id)
  5. return setmetatable({
  6. _msgpack_rpc_stream = msgpack_rpc_stream,
  7. _request_id = request_id,
  8. }, Response)
  9. end
  10. function Response:send(value, is_error)
  11. local data = self._msgpack_rpc_stream._session:reply(self._request_id)
  12. if is_error then
  13. data = data .. self._msgpack_rpc_stream._pack(value)
  14. data = data .. self._msgpack_rpc_stream._pack(mpack.NIL)
  15. else
  16. data = data .. self._msgpack_rpc_stream._pack(mpack.NIL)
  17. data = data .. self._msgpack_rpc_stream._pack(value)
  18. end
  19. self._msgpack_rpc_stream._stream:write(data)
  20. end
  21. --- @class test.MsgpackRpcStream
  22. --- @field private _stream test.Stream
  23. --- @field private __pack table
  24. local MsgpackRpcStream = {}
  25. MsgpackRpcStream.__index = MsgpackRpcStream
  26. function MsgpackRpcStream.new(stream)
  27. return setmetatable({
  28. _stream = stream,
  29. _pack = mpack.Packer(),
  30. _session = mpack.Session({
  31. unpack = mpack.Unpacker({
  32. ext = {
  33. -- Buffer
  34. [0] = function(_c, s)
  35. return mpack.decode(s)
  36. end,
  37. -- Window
  38. [1] = function(_c, s)
  39. return mpack.decode(s)
  40. end,
  41. -- Tabpage
  42. [2] = function(_c, s)
  43. return mpack.decode(s)
  44. end,
  45. },
  46. }),
  47. }),
  48. }, MsgpackRpcStream)
  49. end
  50. function MsgpackRpcStream:write(method, args, response_cb)
  51. local data
  52. if response_cb then
  53. assert(type(response_cb) == 'function')
  54. data = self._session:request(response_cb)
  55. else
  56. data = self._session:notify()
  57. end
  58. data = data .. self._pack(method) .. self._pack(args)
  59. self._stream:write(data)
  60. end
  61. function MsgpackRpcStream:read_start(request_cb, notification_cb, eof_cb)
  62. self._stream:read_start(function(data)
  63. if not data then
  64. return eof_cb()
  65. end
  66. local type, id_or_cb, method_or_error, args_or_result
  67. local pos = 1
  68. local len = #data
  69. while pos <= len do
  70. type, id_or_cb, method_or_error, args_or_result, pos = self._session:receive(data, pos)
  71. if type == 'request' or type == 'notification' then
  72. if type == 'request' then
  73. request_cb(method_or_error, args_or_result, Response.new(self, id_or_cb))
  74. else
  75. notification_cb(method_or_error, args_or_result)
  76. end
  77. elseif type == 'response' then
  78. if method_or_error == mpack.NIL then
  79. method_or_error = nil
  80. else
  81. args_or_result = nil
  82. end
  83. id_or_cb(method_or_error, args_or_result)
  84. end
  85. end
  86. end)
  87. end
  88. function MsgpackRpcStream:read_stop()
  89. self._stream:read_stop()
  90. end
  91. function MsgpackRpcStream:close(signal)
  92. self._stream:close(signal)
  93. end
  94. return MsgpackRpcStream