#serialization #cbor #future #codec #framing #async-io

futures_cbor_codec

A codec for framing an AsyncRead/AsyncWrite with cbor for all types that are serializable with serde

8 releases

0.3.1 Jun 11, 2021
0.3.0 Feb 18, 2021
0.2.0 Dec 28, 2019
0.1.5 Nov 16, 2019
0.1.2 Aug 15, 2019

#941 in Asynchronous

35 downloads per month

Apache-2.0/MIT

23KB
363 lines

futures_cbor_codec

standard-readme compliant Build Status Docs crates.io

A codec for framing AsyncRead/AsyncWrite from the futures lib with serde-cbor

This rust crate integrates the serde-cbor into a codec (Decoder and Encoder) of future-codec. This allows turning an AsyncRead/AsyncWrite into a stream and sink of rust objects that implement Serialize/Deserialize from serde.

This is a fork from tokio-serde-cbor. It turned out to work unchanged for futures-codec. All the credit for this functionality should go to @vorner.

Table of Contents

Install

With cargo add: cargo add futures_cbor_codec

With cargo yaml:

dependencies:

   futures_cbor_codec: ^0.2

With raw Cargo.toml

[dependencies]

    futures_cbor_codec = "0.2"

Upgrade

Please check out the changelog when upgrading.

Dependencies

This crate has few dependiencies. Cargo will automatically handle it's dependencies for you.

There are no optional features.

Usage

This crate provides a codec for framing information as CBOR encoded messages. It allows encoding and decoding arbitrary serde ready types. It can be used by plugging the codec into the connection's framed method to get stream and sink of the desired items.

The encoded and decoded items are independent (you may want to encode references and decode owned data, or the protocol might be asymetric). If you want just one direction, you can use Decoder or Encoder. If you want both, you better use Codec.

Note that this is useful if the CBOR itself defines the frames. If the messages are delimited in some other way (eg. length-prefix encoding) and CBOR is only the payload, you'd use a codec for the other framing and use .map on the received stream and sink to convert the messages.

Please have a look in the examples directory of the repository.

This crate works on WASM.

Basic example

#![feature(async_await)]


use
{
   futures_ringbuf    :: { *                                      } ,
   futures            :: { SinkExt, StreamExt, executor::block_on } ,
   asynchronous_codec :: { Framed                                 } ,
   futures_cbor_codec :: { Codec                                  } ,
   std                :: { collections::HashMap                   } ,
};


// We create some test data to serialize. This works because Serde implements
// Serialize and Deserialize for HashMap, so the codec can frame this type.
//
type TestData = HashMap<String, usize>;


/// Something to test with. It doesn't really matter what it is.
//
fn test_data() -> TestData
{
   let mut data = HashMap::new();

   data.insert( "hello".to_string(), 42 );
   data.insert( "world".to_string(), 0  );

   data
}


// In a real life scenario the sending and receiving end usually are in different processes.
// We could simulate that somewhat by putting them in separate async blocks and spawning those,
// but since we only send in one direction, I chose to keep it simple.
//
// Obviously in production code you should do some real error handling rather than using
// `expect`. However for this example, almost any error would fatal, so we might as well.
//
fn main()
{
   let program = async
   {
      let mock = RingBuffer::new(32);

      // Type annotations are needed unfortunately.
      //
      let (mut writer, mut reader) = Framed::new( mock , Codec::<TestData, TestData>::new() ).split();

      writer.send( test_data() ).await.expect( "send message1" );
      writer.send( test_data() ).await.expect( "send message2" );
      writer.close().await.expect( "close sender" );


      while let Some(msg) = reader.next().await.transpose().expect( "receive message" )
      {
         println!( "Received: {:#?}", msg );
      }
   };

   block_on( program );
}

API

Api documentation can be found on docs.rs.

Contributing

Please check out the contribution guidelines.

Testing

cargo test

On wasm, after installing wasm-pack:

wasm-pack test --firefox --headless

or

wasm-pack test --chrome --headless

Code of conduct

Any of the behaviors described in point 4 "Unacceptable Behavior" of the Citizens Code of Conduct are not welcome here and might get you banned. If anyone, including maintainers and moderators of the project, fail to respect these/your limits, you are entitled to call them out.

License

Licensed under either of

Dependencies

~1.3–2MB
~38K SLoC