Expand description
An asynchronous, alloc-free, serialization framework written in 100% safe™ Rust.
§EXPERIMENTAL
diny
currently requires the nightly Rust toolchain >= 1.56.0 for GAT support.diny
is still in active design–the API is incomplete and prone to change without notice and without backward compatibility.- no_std support is largely ceremonial at this point as the futures-io traits currently require std.
That being said, it is ready for experimentation and design feedback.
§Usage
Add a dependency on diny
and a serializer format in Cargo.toml
:
[dependencies]
diny = { version = "0.2", features = ["derive"] }
diny_test = "0.2"
Enable GAT support in your project’s module file (e.g. main.rs, lib.rs):
#![feature(generic_associated_types)]
Derive AsyncSerialization support for the desired data types, or derive just AsyncSerialize or AsyncDeserialize to limit the support to one-way transfers.
The Serialize and Deserialize objects returned from the serializer and deserializer methods implement sinks and streams (respectively) and are the simplest way to serialize and deserialize objects that implement AsyncSerialization.
use futures::{executor::block_on, SinkExt, StreamExt};
#[derive(diny::AsyncSerialization)]
pub struct Point {
x: i32,
y: i32,
}
let point = Point { x: 1, y: 2 };
// A format can be any implementation of
// diny::backend::{FormatSerialize + FormatDeserialize}.
let format = diny_test::format();
// A writer can be any implementation of futures::io::AsyncWrite.
// This example is using a Vec for simplicity.
let writer = vec!();
// A sink is constructible for any implementor of diny::AsyncSerialize
let mut sink = diny::serializer(format, writer).into_sink();
block_on(sink.send(point)).unwrap();
// Sinks can be destructed back into the inner serializer
let diny::Serializer { format, writer } = sink.try_into_inner().unwrap();
// A reader can be any implementation of futures::io::AsyncBufRead.
// This example is using a utility module to convert the bytes
// written to the vec into an async reader.
let reader = diny::util::AsyncSliceReader::from(&writer[..]);
// A stream is constructible for any implementor of diny::AsyncDeserialize
let mut stream = diny::deserializer(format, reader).into_stream();
let _: Point = block_on(stream.next()).unwrap();
The Serializer and Deserializer objects expose serialize
and
deserialize
methods respecively, which can be used to interleave
different serializable objects over
the same channel. This has the added benefit of serializing by
reference instead of by value.
let point = Point { x: 1, y: 2 };
let slope: i32 = 3;
let mut serializer = diny::serializer(format, writer);
block_on(async {
serializer.serialize(&point).await?;
serializer.serialize(&slope).await?;
serializer.flush().await
}).unwrap();
let mut deserializer = diny::deserializer(format, reader);
block_on(async {
deserializer.deserialize::<Point>().await?;
deserializer.deserialize::<i32>().await
}).unwrap();
The AsyncSerialize and AsyncDeserialize traits can be used directly without building an intermediate Serializer or Deserializer object.
use futures::io::AsyncWriteExt;
use diny::{AsyncDeserialize, AsyncSerialize};
let point = Point { x: 1, y: 2 };
let write = point.serialize(&format, &mut writer);
block_on(write).unwrap();
block_on(writer.flush()).unwrap();
let read = Point::deserialize(&format, &mut reader);
block_on(read).unwrap();
Additionally, an object’s underlying Encoder and Decoder can be easily incorporated into custom futures. See the Serialize and Deserialize implementations for an example of how to embed them.
An example of using the async-compat
crate to interoperate with the
tokio
runtime is provided in the examples directory.
§Features
By default, diny
builds with (and currently requires) Rust’s standard library. Importantly,
the derive
proc macros are not built by default, and need to be enabled to
become available.
Feature | Description | Default |
---|---|---|
derive | Support for deriving AsyncSerialize and AsyncDeserialize traits | ☐ |
unsafe_speed | Permit using unsafe code to improve performance | ☐ |
std | Support for Rust’s standard library | ☑ |
alloc | Support for memory allocation without full std support | ☐ |
test | Build the diny_test formatter and re-export it to diny::test | ☐ |
Modules§
- backend
- Types and traits implemented by backend formatters
- buffer
- Helper modules for implementing buffered serialization primitives
- deserializer
- Types used to support deserialization streams
- io
- Re-export of io related structures
- serializer
- Types used to suport serialization sinks
- util
- Helper modules that may be externally useful
Macros§
- decode_
chain - Starts decoding by calling the
$dec
expression, and converts the result to a PollDecodeStatus - decode_
poll_ chain - Continues decoding by first polling the
$dec
expression, and then calling the$chain
closure with any resulting data, and finally converts the result to a PollDecodeStatus - decode_
poll_ fini - Finalizes decoding by polling the
$dec
expression, converts the final data by calling the$fini
closure, and finally converts the result to a PollDecodeStatus - encode_
chain - Starts encoding by calling the
$enc
expression, and converts the result to a PollEncodeStatus - encode_
poll_ chain - Continues encoding by first polling the
$enc
expression, and then calling the$chain
expression, and finally converts the result to a PollEncodeStatus - encode_
poll_ fini - Finalizes encoding by polling the
$enc
expression, and converts the result to a PollEncodeStatus
Structs§
- Deserialize
- Implements the Stream trait
- Deserializer
- A wrapper type around a specific format and reader
- Serialize
- Implements the Sink trait
- Serializer
- A wrapper type around a specific format and writer
Traits§
- Async
Deserialize - Deserialize a data structure asynchronously.
- Async
Serialization - Marker trait to denote that both AsyncSerialize and AsyncDeserialize are implemented for the type.
- Async
Serialize - Serialize a data structure asynchronously.
Functions§
- deserializer
- Creates a new Deserializer from the specified format and reader
- serializer
- Creates a new Serializer from the specified format and writer
Derive Macros§
- Async
Deserialize - Generate only async deserialization code
- Async
Serialization - Generate both async serialization and deserialization code
- Async
Serialize - Generate only async serialization code