8 releases
0.3.2 | Sep 13, 2022 |
---|---|
0.3.1 | Apr 21, 2022 |
0.3.0 | Dec 14, 2021 |
0.2.2 | Nov 30, 2021 |
0.1.0 | Mar 19, 2020 |
#1046 in Encoding
213 downloads per month
125KB
3K
SLoC
rmp-futures - Async Rust MessagePack and MessagePack-RPC
Async encode/decode for msgpack and msgpack-rpc. Intended to allow
deterministic memory use, making the client responsible for allocation. Since
msgpack is a streamable format, the ability to serialize on the fly as the
writer becomes writable is exposed. Similarly, the reader can be written to
deal with individual encoded objects as they are encountered in the stream.
No memory allocations are performed in the library unless requested, such as
returning a string as a Rust String
or returning an entire object as a
dynamic rmpv::Value
.
Data types are compatible with rmp and rmpv crates where possible.
Theory of operation
Every time some data is read and a decision point is reached, such as reaching the start of a new item, the client gets a new object that represents the state of the stream and only offers operations that are valid at that point. So a client can have a static decoding sequence for an expected message with the storage requirements known up front.
The underlying reader or writer are moved into the decoder or encoder. It is only possible to get ownership back by performing a sequence of valid operations on the parser, each returning a new type with its own set of valid operations. This enforces at compile time that elements are read before processing the next element, and that encoded messsages are well-formed.
Recursive objects yield recursive types. Example data type progression for
reading an array containing one element: [true]
- R: Initial plain async reader
- MsgPackFuture: client wraps reader with MsgPackFuture::new() to indicate that this reader is at the start of a message
- ValueFuture::Array(ArrayFuture): decode() returns an enum
- ArrayFuture: client matches on the enum and destructures the inner ArrayFuture
- MsgPackFuture<ArrayFuture>: client calls next(), unwraps the MsgPackOption. Now we're at the start of a new msg that's an element of an array, as indicated by the data type
- ValueFuture::Boolean(true, ArrayFuture): message decoded as "true"
- ArrayFuture: destructure the Boolean, now the ArrayFuture is ready to read the next element
- MsgPackOption::End(R): ArrayFuture::next() returns an enum indicating end of the array
- R: destructuring the End of the array returns the original reader
Encode and Decode support dynamic write_value()
and into_value()
functions
that deal with heap-allocated messages. This is easier to use at the cost of
memory, but also allows easier transition from other libraries that use
rmpv::Value
such as rmp-rpc
.
TODO
- RpcMessage::Request should produce a handle to be used to send the message back. Currently the client has to save the id and use the correct one when starting the response message.
License
Licensed under either of
- Apache License, Version 2.0 http://www.apache.org/licenses/LICENSE-2.0
- MIT license http://opensource.org/licenses/MIT
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Dependencies
~3MB
~62K SLoC