Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

efficient compact untagged streaming format using unaligned bitstreams

Notifications You must be signed in to change notification settings

noocene/mincodec

Open more actions menu

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

29 Commits
29 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mincodec

Documentation

Highly spatially efficient serialization format supporting #[no_std] and making zero allocations.

comparison

All sizes listed in bits

Type Value mincodec CBOR bincode MessagePack Postcard
Option<bool> Some(true) 2 8 16 8 16
Option<bool> Some(false) 2 8 16 8 16
Option<bool> None 1 8 8 8 8
String "hello" 48 48 104 48 48
Vec<bool> [true, false, true] 11 32 88 32 32
(bool, u8) (false, 3) 9 24 16 24 16
CustomOption<bool> Some(true) 2 56 40 24 16
() () 0 8 0 8 0
[String; 0] [] 0 8 0 8 0
[bool; 2] [true, false] 2 24 16 24 16
Bit High 1 40 32 24 8
OneVariant Variant 0 64 32 24 8
pub enum CustomOption<T> {
    Some(T),
    None,
}

pub enum Bit {
    High,
    Low,
}

pub enum OneVariant {
    Variant,
}

features

  • True frameless design (no headers/prefixing/etc. in multi-item streams)
  • Perfect incremental deserialization (intermediate buffers are filled per-bit as data becomes available), no cycles are wasted re-deserializing data
  • #![no_std] support using core-futures-io
  • Compatibility with both tokio and async_std using compatibility adapters from core-futures-io
  • Bit-level serialization using bitbuf facilitates the extreme spatial efficiency displayed above
  • Efficient size prefixing for DSTs using bitbuf-vlq
  • Asynchronicity permits deserialization of data as it becomes available over transport, spreading the time cost of deserialization or serialization over the transport's bandwidth domain
  • Asynchronicity permits dependency of serialized/deserialized types on futures, the dual of transport-side asynchronicity
  • serde-style derive macro for straightforward implementation with support for generic parametrization

async_std TcpStream example

use async_std::net::{TcpStream, TcpListener};
use core_futures_io::FuturesCompat;
use futures::{executor::block_on, StreamExt};
use mincodec::{AsyncWriter, MinCodec, AsyncReader};
use std::thread::spawn;

#[derive(MinCodec, Debug)]
enum Permission {
    Read,
    Write,
    Invite { remaining: u32 },
}

#[derive(MinCodec, Debug)]
struct Capability {
    permission: Permission,
    domain: String,
}

#[derive(MinCodec, Debug)]
struct User {
    name: String,
    capabilities: Vec<Capability>,
}

#[derive(MinCodec, Debug)]
enum Action<T> {
    Create(T),
    Remove { index: u32 },
}

#[derive(MinCodec, Debug)]
struct Post {
    content: String,
    date: u64,
}

#[derive(MinCodec, Debug)]
struct Data {
    user: User,
    action: Action<Post>,
}

fn main() {
    let thread = spawn(|| block_on(async {
        let listener = TcpListener::bind("127.0.0.1:8080").await.expect("could not bind listener");
        let mut incoming = listener.incoming();

        if let Some(stream) = incoming.next().await {
            let stream = stream.expect("listener-side connection error");
            println!("received: {:?}", AsyncReader::<_, Data>::new(FuturesCompat::new(stream)).await.expect("error reading data and deserializing"));
        }
    }));
    block_on(async {
        let stream = TcpStream::connect("127.0.0.1:8080")
            .await
            .expect("could not connect");
            
        AsyncWriter::new(
            FuturesCompat::new(stream),
            Data {
                action: Action::Create(Post {
                    content: "Hello there!".to_owned(),
                    date: 1230192809,
                }),
                user: User {
                    name: "J. Doe".to_owned(),
                    capabilities: vec![
                        Capability {
                            permission: Permission::Write,
                            domain: "posts".to_owned(),
                        },
                        Capability {
                            permission: Permission::Read,
                            domain: "posts".to_owned(),
                        },
                    ],
                },
            },
        )
        .await
        .expect("could not serialize and transmit");
    });
    thread.join().unwrap();
}

About

efficient compact untagged streaming format using unaligned bitstreams

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

Morty Proxy This is a proxified and sanitized view of the page, visit original site.