mirror of https://git.sr.ht/~stygianentity/bincode
Started working on bincode_derive
This commit is contained in:
parent
a6435388a1
commit
bab0cf4bd1
11
Cargo.toml
11
Cargo.toml
|
|
@ -15,4 +15,13 @@ keywords = ["binary", "encode", "decode", "serialize", "deserialize"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "A binary serialization / deserialization strategy for transforming structs into bytes and vice versa!"
|
description = "A binary serialization / deserialization strategy for transforming structs into bytes and vice versa!"
|
||||||
|
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["std"]
|
||||||
|
std = []
|
||||||
|
alloc = []
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
bincode_derive = { path = "derive" }
|
||||||
|
# serde = { version = "1.0.130", optional = true }
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
target
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bincode_derive"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.29"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-xid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "1.0.76"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c6f107db402c2c2055242dbf4d2af0e69197202e9faacbef9571bbe47f5a1b84"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-xid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-xid"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
[package]
|
||||||
|
name = "bincode_derive"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
proc-macro = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
quote = "1.0.9"
|
||||||
|
|
||||||
|
[dependencies.syn]
|
||||||
|
version = "1.0.74"
|
||||||
|
default-features = false
|
||||||
|
features = ["parsing", "derive", "proc-macro", "printing"]
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
use crate::Result;
|
||||||
|
use proc_macro::TokenStream;
|
||||||
|
use syn::Ident;
|
||||||
|
|
||||||
|
pub struct DeriveEnum {}
|
||||||
|
|
||||||
|
impl DeriveEnum {
|
||||||
|
pub fn parse(_name: Ident, _en: syn::DataEnum) -> Result<Self> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_encodable(self) -> Result<TokenStream> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_decodable(self) -> Result<TokenStream> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
use crate::Result;
|
||||||
|
use proc_macro::TokenStream;
|
||||||
|
use quote::quote;
|
||||||
|
use syn::{spanned::Spanned, Ident};
|
||||||
|
|
||||||
|
pub struct DeriveStruct {
|
||||||
|
name: Ident,
|
||||||
|
fields: Vec<Ident>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DeriveStruct {
|
||||||
|
pub fn parse(name: Ident, str: syn::DataStruct) -> Result<Self> {
|
||||||
|
let fields = match str.fields {
|
||||||
|
syn::Fields::Named(fields) => fields
|
||||||
|
.named
|
||||||
|
.iter()
|
||||||
|
.map(|f| f.ident.clone().unwrap())
|
||||||
|
.collect(),
|
||||||
|
syn::Fields::Unnamed(fields) => fields
|
||||||
|
.unnamed
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, field)| Ident::new(&i.to_string(), field.ty.span()))
|
||||||
|
.collect(),
|
||||||
|
syn::Fields::Unit => Vec::new(),
|
||||||
|
};
|
||||||
|
Ok(Self { name, fields })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_encodable(self) -> Result<TokenStream> {
|
||||||
|
let DeriveStruct { name, fields } = self;
|
||||||
|
|
||||||
|
let fields = fields
|
||||||
|
.into_iter()
|
||||||
|
.map(|field| {
|
||||||
|
quote! {
|
||||||
|
bincode::enc::Encodeable::encode(&self. #field, &mut encoder)?;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let result = quote! {
|
||||||
|
impl bincode::enc::Encodeable for #name {
|
||||||
|
fn encode<E: bincode::enc::Encode>(&self, mut encoder: E) -> Result<(), bincode::error::Error> {
|
||||||
|
#(#fields)*
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Ok(result.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_decodable(self) -> Result<TokenStream> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
use proc_macro::TokenStream;
|
||||||
|
use quote::__private::Span;
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
pub enum Error {
|
||||||
|
UnionNotSupported,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Error {
|
||||||
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::UnionNotSupported => write!(fmt, "Unions are not supported"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Error {
|
||||||
|
pub fn into_token_stream(self) -> TokenStream {
|
||||||
|
self.into_token_stream_with_span(Span::call_site())
|
||||||
|
}
|
||||||
|
pub fn into_token_stream_with_span(self, span: Span) -> TokenStream {
|
||||||
|
syn::Error::new(span, self).into_compile_error().into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
extern crate proc_macro;
|
||||||
|
|
||||||
|
mod derive_enum;
|
||||||
|
mod derive_struct;
|
||||||
|
mod error;
|
||||||
|
|
||||||
|
use derive_enum::DeriveEnum;
|
||||||
|
use derive_struct::DeriveStruct;
|
||||||
|
use error::Error;
|
||||||
|
use proc_macro::TokenStream;
|
||||||
|
use syn::{parse_macro_input, DeriveInput};
|
||||||
|
|
||||||
|
type Result<T = ()> = std::result::Result<T, Error>;
|
||||||
|
|
||||||
|
#[proc_macro_derive(Encodable)]
|
||||||
|
pub fn derive_encodable(input: TokenStream) -> TokenStream {
|
||||||
|
let input = parse_macro_input!(input as DeriveInput);
|
||||||
|
derive_encodable_inner(input).unwrap_or_else(|e| e.into_token_stream())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn derive_encodable_inner(input: DeriveInput) -> Result<TokenStream> {
|
||||||
|
match input.data {
|
||||||
|
syn::Data::Struct(struct_definition) => {
|
||||||
|
DeriveStruct::parse(input.ident, struct_definition).and_then(|str| str.to_encodable())
|
||||||
|
}
|
||||||
|
syn::Data::Enum(enum_definition) => {
|
||||||
|
DeriveEnum::parse(input.ident, enum_definition).and_then(|str| str.to_encodable())
|
||||||
|
}
|
||||||
|
syn::Data::Union(_) => Err(Error::UnionNotSupported),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro_derive(Decodable)]
|
||||||
|
pub fn derive_decodable(input: TokenStream) -> TokenStream {
|
||||||
|
let input = parse_macro_input!(input as DeriveInput);
|
||||||
|
derive_decodable_inner(input).unwrap_or_else(|e| e.into_token_stream())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn derive_decodable_inner(input: DeriveInput) -> Result<TokenStream> {
|
||||||
|
match input.data {
|
||||||
|
syn::Data::Struct(struct_definition) => {
|
||||||
|
DeriveStruct::parse(input.ident, struct_definition).and_then(|str| str.to_decodable())
|
||||||
|
}
|
||||||
|
syn::Data::Enum(enum_definition) => {
|
||||||
|
DeriveEnum::parse(input.ident, enum_definition).and_then(|str| str.to_decodable())
|
||||||
|
}
|
||||||
|
syn::Data::Union(_) => Err(Error::UnionNotSupported),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# Serialization specification
|
# Serialization specification
|
||||||
|
|
||||||
*NOTE*: Serialization is done by `bincode_derive` by default. If you enable the `serde` flag, serialization is done by `serde-derive` instead. `serde-derive` has the same guarantees as `bincode_derive` for now.
|
*NOTE*: Serialization is done by `bincode_derive` by default. If you enable the `serde` flag, serialization with `serde-derive` is supported as well. `serde-derive` has the same guarantees as `bincode_derive` for now.
|
||||||
|
|
||||||
Related issue: https://github.com/serde-rs/serde/issues/1756#issuecomment-689682123
|
Related issue: https://github.com/serde-rs/serde/issues/1756#issuecomment-689682123
|
||||||
|
|
||||||
|
|
@ -51,7 +51,7 @@ Enums are encoded with their variant first, followed by optionally the variant f
|
||||||
Both named and unnamed fields are serialized with their values only, and therefor encode to the same value.
|
Both named and unnamed fields are serialized with their values only, and therefor encode to the same value.
|
||||||
|
|
||||||
```rs
|
```rs
|
||||||
#[derive(bincode::Serialize)]
|
#[derive(bincode::Encodable)]
|
||||||
pub enum SomeEnum {
|
pub enum SomeEnum {
|
||||||
A,
|
A,
|
||||||
B(u32),
|
B(u32),
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
use super::{Decode, Decodable};
|
use super::{Decodable, Decode};
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
|
|
||||||
impl Decodable for u32 {
|
impl Decodable for u32 {
|
||||||
fn decode<D: Decode>(mut decoder: D) -> Result<Self, Error> {
|
fn decode<D: Decode>(mut decoder: D) -> Result<Self, Error> {
|
||||||
decoder.decode_u32()
|
decoder.decode_u32()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,6 @@ use read::Reader;
|
||||||
mod impls;
|
mod impls;
|
||||||
pub mod read;
|
pub mod read;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub trait Decodable: Sized {
|
pub trait Decodable: Sized {
|
||||||
fn decode<D: Decode>(decoder: D) -> Result<Self, Error>;
|
fn decode<D: Decode>(decoder: D) -> Result<Self, Error>;
|
||||||
}
|
}
|
||||||
|
|
@ -44,5 +42,3 @@ impl<'a, 'de, R: Reader<'de>, C: Config> Decode for &'a mut Decoder<R, C> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ impl<'storage> SliceReader<'storage> {
|
||||||
|
|
||||||
impl<'storage> Reader<'storage> for SliceReader<'storage> {
|
impl<'storage> Reader<'storage> for SliceReader<'storage> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn read<'a>(&'a mut self, bytes: &mut [u8]) -> Result<(), Error> {
|
fn read(&mut self, bytes: &mut [u8]) -> Result<(), Error> {
|
||||||
if bytes.len() > self.slice.len() {
|
if bytes.len() > self.slice.len() {
|
||||||
return Err(Error::UnexpectedEnd);
|
return Err(Error::UnexpectedEnd);
|
||||||
}
|
}
|
||||||
|
|
@ -48,4 +48,4 @@ impl<'storage> Reader<'storage> for SliceReader<'storage> {
|
||||||
{
|
{
|
||||||
Ok(visitor(self.get_byte_slice(length)?))
|
Ok(visitor(self.get_byte_slice(length)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,20 @@
|
||||||
use super::{Encode, Encodeable};
|
use super::{Encode, Encodeable};
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
|
|
||||||
|
impl Encodeable for u8 {
|
||||||
|
fn encode<E: Encode>(&self, mut encoder: E) -> Result<(), Error> {
|
||||||
|
encoder.encode_u8(*self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Encodeable for u32 {
|
impl Encodeable for u32 {
|
||||||
fn encode<E: Encode>(&self, mut encoder: E) -> Result<(), Error> {
|
fn encode<E: Encode>(&self, mut encoder: E) -> Result<(), Error> {
|
||||||
encoder.encode_u32(*self)
|
encoder.encode_u32(*self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Encodeable for i32 {
|
||||||
|
fn encode<E: Encode>(&self, mut encoder: E) -> Result<(), Error> {
|
||||||
|
encoder.encode_i32(*self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,13 +9,28 @@ use write::Writer;
|
||||||
mod impls;
|
mod impls;
|
||||||
pub mod write;
|
pub mod write;
|
||||||
|
|
||||||
|
|
||||||
pub trait Encodeable {
|
pub trait Encodeable {
|
||||||
fn encode<E: Encode>(&self, encoder: E) -> Result<(), Error>;
|
fn encode<E: Encode>(&self, encoder: E) -> Result<(), Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Encode {
|
pub trait Encode {
|
||||||
|
fn encode_u8(&mut self, val: u8) -> Result<(), Error>;
|
||||||
fn encode_u32(&mut self, val: u32) -> Result<(), Error>;
|
fn encode_u32(&mut self, val: u32) -> Result<(), Error>;
|
||||||
|
fn encode_i32(&mut self, val: i32) -> Result<(), Error>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T> Encode for &'a mut T
|
||||||
|
where
|
||||||
|
T: Encode,
|
||||||
|
{
|
||||||
|
fn encode_u8(&mut self, val: u8) -> Result<(), Error> {
|
||||||
|
T::encode_u8(self, val)
|
||||||
|
}
|
||||||
|
fn encode_u32(&mut self, val: u32) -> Result<(), Error> {
|
||||||
|
T::encode_u32(self, val)
|
||||||
|
}
|
||||||
|
fn encode_i32(&mut self, val: i32) -> Result<(), Error> {
|
||||||
|
T::encode_i32(self, val)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Encoder<W: Writer, C: Config> {
|
pub struct Encoder<W: Writer, C: Config> {
|
||||||
|
|
@ -30,9 +45,17 @@ impl<W: Writer, C: Config> Encoder<W, C> {
|
||||||
config: PhantomData,
|
config: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn into_writer(self) -> W {
|
||||||
|
self.writer
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, W: Writer, C: Config> Encode for &'a mut Encoder<W, C> {
|
impl<'a, W: Writer, C: Config> Encode for &'a mut Encoder<W, C> {
|
||||||
|
fn encode_u8(&mut self, val: u8) -> Result<(), Error> {
|
||||||
|
self.writer.write(&[val])
|
||||||
|
}
|
||||||
|
|
||||||
fn encode_u32(&mut self, val: u32) -> Result<(), Error> {
|
fn encode_u32(&mut self, val: u32) -> Result<(), Error> {
|
||||||
let bytes = match C::ENDIAN {
|
let bytes = match C::ENDIAN {
|
||||||
Endian::Little => val.to_le_bytes(),
|
Endian::Little => val.to_le_bytes(),
|
||||||
|
|
@ -41,4 +64,13 @@ impl<'a, W: Writer, C: Config> Encode for &'a mut Encoder<W, C> {
|
||||||
|
|
||||||
self.writer.write(&bytes)
|
self.writer.write(&bytes)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
fn encode_i32(&mut self, val: i32) -> Result<(), Error> {
|
||||||
|
let bytes = match C::ENDIAN {
|
||||||
|
Endian::Little => val.to_le_bytes(),
|
||||||
|
Endian::Big => val.to_be_bytes(),
|
||||||
|
};
|
||||||
|
|
||||||
|
self.writer.write(&bytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,25 +6,31 @@ pub trait Writer {
|
||||||
|
|
||||||
pub struct SliceWriter<'storage> {
|
pub struct SliceWriter<'storage> {
|
||||||
slice: &'storage mut [u8],
|
slice: &'storage mut [u8],
|
||||||
|
idx: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'storage> SliceWriter<'storage> {
|
impl<'storage> SliceWriter<'storage> {
|
||||||
pub(crate) fn new(bytes: &'storage mut [u8]) -> SliceWriter<'storage> {
|
pub(crate) fn new(bytes: &'storage mut [u8]) -> SliceWriter<'storage> {
|
||||||
SliceWriter {
|
SliceWriter {
|
||||||
slice: bytes,
|
slice: bytes,
|
||||||
|
idx: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn bytes_written(&self) -> usize {
|
||||||
|
self.idx
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'storage> Writer for SliceWriter<'storage> {
|
impl<'storage> Writer for SliceWriter<'storage> {
|
||||||
fn write(&mut self, bytes: &[u8]) -> Result<(), Error> {
|
fn write(&mut self, bytes: &[u8]) -> Result<(), Error> {
|
||||||
if bytes.len() > self.slice.len() {
|
let remaining = &mut self.slice[self.idx..];
|
||||||
|
if bytes.len() > remaining.len() {
|
||||||
return Err(Error::UnexpectedEnd);
|
return Err(Error::UnexpectedEnd);
|
||||||
}
|
}
|
||||||
let data = core::mem::take(&mut self.slice);
|
self.idx += bytes.len();
|
||||||
let (write_slice, remaining) = data.split_at_mut(bytes.len());
|
let write_slice = &mut remaining[..bytes.len()];
|
||||||
write_slice.copy_from_slice(bytes);
|
write_slice.copy_from_slice(bytes);
|
||||||
self.slice = remaining;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{error::Error, enc::write::Writer};
|
use crate::{enc::write::Writer, error::Error};
|
||||||
|
|
||||||
pub trait IntEncoding {
|
pub trait IntEncoding {
|
||||||
fn encode_u32<W: Writer>(writer: &mut W, val: u32) -> Result<(), Error>;
|
fn encode_u32<W: Writer>(writer: &mut W, val: u32) -> Result<(), Error>;
|
||||||
|
|
|
||||||
12
src/lib.rs
12
src/lib.rs
|
|
@ -17,15 +17,21 @@ extern crate std;
|
||||||
|
|
||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod de;
|
pub mod de;
|
||||||
pub mod error;
|
|
||||||
pub mod enc;
|
pub mod enc;
|
||||||
|
pub mod error;
|
||||||
|
|
||||||
|
pub use bincode_derive::{Decodable, Encodable};
|
||||||
|
|
||||||
pub(crate) mod int_encoding;
|
pub(crate) mod int_encoding;
|
||||||
|
|
||||||
pub fn encode_into_slice<E: enc::Encodeable>(val: E, dst: &mut [u8]) -> Result<(), error::Error> {
|
pub fn encode_into_slice<E: enc::Encodeable>(
|
||||||
|
val: E,
|
||||||
|
dst: &mut [u8],
|
||||||
|
) -> Result<usize, error::Error> {
|
||||||
let writer = enc::write::SliceWriter::new(dst);
|
let writer = enc::write::SliceWriter::new(dst);
|
||||||
let mut encoder = enc::Encoder::<_, config::Default>::new(writer);
|
let mut encoder = enc::Encoder::<_, config::Default>::new(writer);
|
||||||
val.encode(&mut encoder)
|
val.encode(&mut encoder)?;
|
||||||
|
Ok(encoder.into_writer().bytes_written())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn decode<D: de::Decodable>(src: &mut [u8]) -> Result<D, error::Error> {
|
pub fn decode<D: de::Decodable>(src: &mut [u8]) -> Result<D, error::Error> {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
#[derive(bincode::Encodable, PartialEq, Debug)]
|
||||||
|
pub struct Test {
|
||||||
|
a: i32,
|
||||||
|
b: u32,
|
||||||
|
c: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_encodable() {
|
||||||
|
let start = Test {
|
||||||
|
a: 5i32,
|
||||||
|
b: 10u32,
|
||||||
|
c: 20u8,
|
||||||
|
};
|
||||||
|
let mut slice = [0u8; 1024];
|
||||||
|
let bytes_written = bincode::encode_into_slice(start, &mut slice).unwrap();
|
||||||
|
assert_eq!(bytes_written, 9);
|
||||||
|
assert_eq!(&slice[..bytes_written], &[5, 0, 0, 0, 10, 0, 0, 0, 20]);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue