mirror of https://git.sr.ht/~stygianentity/bincode
parent
f3c21f2245
commit
a5e57d51d8
|
|
@ -20,10 +20,10 @@ impl DeriveEnum {
|
||||||
|
|
||||||
pub fn generate_encode(self, generator: &mut Generator) -> Result<()> {
|
pub fn generate_encode(self, generator: &mut Generator) -> Result<()> {
|
||||||
generator
|
generator
|
||||||
.impl_for("bincode::enc::Encode")?
|
.impl_for("bincode::Encode")?
|
||||||
.modify_generic_constraints(|generics, where_constraints| {
|
.modify_generic_constraints(|generics, where_constraints| {
|
||||||
for g in generics.iter_generics() {
|
for g in generics.iter_generics() {
|
||||||
where_constraints.push_constraint(g, "bincode::enc::Encode").unwrap();
|
where_constraints.push_constraint(g, "bincode::Encode").unwrap();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.generate_fn("encode")
|
.generate_fn("encode")
|
||||||
|
|
@ -70,13 +70,13 @@ impl DeriveEnum {
|
||||||
// Note that the fields are available as locals because of the match destructuring above
|
// Note that the fields are available as locals because of the match destructuring above
|
||||||
// {
|
// {
|
||||||
// encoder.encode_u32(n)?;
|
// encoder.encode_u32(n)?;
|
||||||
// bincode::enc::Encode::encode(a, encoder)?;
|
// bincode::Encode::encode(a, encoder)?;
|
||||||
// bincode::enc::Encode::encode(b, encoder)?;
|
// bincode::Encode::encode(b, encoder)?;
|
||||||
// bincode::enc::Encode::encode(c, encoder)?;
|
// bincode::Encode::encode(c, encoder)?;
|
||||||
// }
|
// }
|
||||||
match_body.group(Delimiter::Brace, |body| {
|
match_body.group(Delimiter::Brace, |body| {
|
||||||
// variant index
|
// variant index
|
||||||
body.push_parsed("<u32 as bincode::enc::Encode>::encode")?;
|
body.push_parsed("<u32 as bincode::Encode>::encode")?;
|
||||||
body.group(Delimiter::Parenthesis, |args| {
|
body.group(Delimiter::Parenthesis, |args| {
|
||||||
args.punct('&');
|
args.punct('&');
|
||||||
args.group(Delimiter::Parenthesis, |num| {
|
args.group(Delimiter::Parenthesis, |num| {
|
||||||
|
|
@ -93,12 +93,12 @@ impl DeriveEnum {
|
||||||
for field_name in variant.fields.names() {
|
for field_name in variant.fields.names() {
|
||||||
if field_name.attributes().has_attribute(FieldAttribute::WithSerde)? {
|
if field_name.attributes().has_attribute(FieldAttribute::WithSerde)? {
|
||||||
body.push_parsed(format!(
|
body.push_parsed(format!(
|
||||||
"bincode::enc::Encode::encode(&bincode::serde::Compat({}), encoder)?;",
|
"bincode::Encode::encode(&bincode::serde::Compat({}), encoder)?;",
|
||||||
field_name.to_string_with_prefix(TUPLE_FIELD_PREFIX),
|
field_name.to_string_with_prefix(TUPLE_FIELD_PREFIX),
|
||||||
))?;
|
))?;
|
||||||
} else {
|
} else {
|
||||||
body.push_parsed(format!(
|
body.push_parsed(format!(
|
||||||
"bincode::enc::Encode::encode({}, encoder)?;",
|
"bincode::Encode::encode({}, encoder)?;",
|
||||||
field_name.to_string_with_prefix(TUPLE_FIELD_PREFIX),
|
field_name.to_string_with_prefix(TUPLE_FIELD_PREFIX),
|
||||||
))
|
))
|
||||||
?;
|
?;
|
||||||
|
|
@ -269,7 +269,7 @@ impl DeriveEnum {
|
||||||
|
|
||||||
let enum_name = generator.target_name().to_string();
|
let enum_name = generator.target_name().to_string();
|
||||||
|
|
||||||
generator.impl_for_with_lifetimes("bincode::de::BorrowDecode", &["__de"])?
|
generator.impl_for_with_lifetimes("bincode::BorrowDecode", &["__de"])?
|
||||||
.modify_generic_constraints(|generics, where_constraints| {
|
.modify_generic_constraints(|generics, where_constraints| {
|
||||||
for g in generics.iter_generics() {
|
for g in generics.iter_generics() {
|
||||||
where_constraints.push_constraint(g, "bincode::enc::BorrowDecode").unwrap();
|
where_constraints.push_constraint(g, "bincode::enc::BorrowDecode").unwrap();
|
||||||
|
|
@ -318,7 +318,7 @@ impl DeriveEnum {
|
||||||
variant_body
|
variant_body
|
||||||
.push_parsed("<bincode::serde::BorrowCompat<_> as bincode::BorrowDecode>::borrow_decode(decoder)?.0,")?;
|
.push_parsed("<bincode::serde::BorrowCompat<_> as bincode::BorrowDecode>::borrow_decode(decoder)?.0,")?;
|
||||||
} else {
|
} else {
|
||||||
variant_body.push_parsed("bincode::de::BorrowDecode::borrow_decode(decoder)?,")?;
|
variant_body.push_parsed("bincode::BorrowDecode::borrow_decode(decoder)?,")?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,11 @@ impl DeriveStruct {
|
||||||
let DeriveStruct { fields } = self;
|
let DeriveStruct { fields } = self;
|
||||||
|
|
||||||
generator
|
generator
|
||||||
.impl_for("bincode::enc::Encode")?
|
.impl_for("bincode::Encode")?
|
||||||
.modify_generic_constraints(|generics, where_constraints| {
|
.modify_generic_constraints(|generics, where_constraints| {
|
||||||
for g in generics.iter_generics() {
|
for g in generics.iter_generics() {
|
||||||
where_constraints
|
where_constraints
|
||||||
.push_constraint(g, "bincode::enc::Encode")
|
.push_constraint(g, "bincode::Encode")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -37,7 +37,7 @@ impl DeriveStruct {
|
||||||
))?;
|
))?;
|
||||||
} else {
|
} else {
|
||||||
fn_body.push_parsed(format!(
|
fn_body.push_parsed(format!(
|
||||||
"bincode::enc::Encode::encode(&self.{}, encoder)?;",
|
"bincode::Encode::encode(&self.{}, encoder)?;",
|
||||||
field
|
field
|
||||||
))?;
|
))?;
|
||||||
}
|
}
|
||||||
|
|
@ -56,7 +56,7 @@ impl DeriveStruct {
|
||||||
.impl_for("bincode::Decode")?
|
.impl_for("bincode::Decode")?
|
||||||
.modify_generic_constraints(|generics, where_constraints| {
|
.modify_generic_constraints(|generics, where_constraints| {
|
||||||
for g in generics.iter_generics() {
|
for g in generics.iter_generics() {
|
||||||
where_constraints.push_constraint(g, "bincode::de::Decode").unwrap();
|
where_constraints.push_constraint(g, "bincode::Decode").unwrap();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.generate_fn("decode")
|
.generate_fn("decode")
|
||||||
|
|
@ -104,10 +104,10 @@ impl DeriveStruct {
|
||||||
let DeriveStruct { fields } = self;
|
let DeriveStruct { fields } = self;
|
||||||
|
|
||||||
generator
|
generator
|
||||||
.impl_for_with_lifetimes("bincode::de::BorrowDecode", &["__de"])?
|
.impl_for_with_lifetimes("bincode::BorrowDecode", &["__de"])?
|
||||||
.modify_generic_constraints(|generics, where_constraints| {
|
.modify_generic_constraints(|generics, where_constraints| {
|
||||||
for g in generics.iter_generics() {
|
for g in generics.iter_generics() {
|
||||||
where_constraints.push_constraint(g, "bincode::de::BorrowDecode").unwrap();
|
where_constraints.push_constraint(g, "bincode::BorrowDecode").unwrap();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.generate_fn("borrow_decode")
|
.generate_fn("borrow_decode")
|
||||||
|
|
@ -124,13 +124,13 @@ impl DeriveStruct {
|
||||||
if field.attributes().has_attribute(FieldAttribute::WithSerde)? {
|
if field.attributes().has_attribute(FieldAttribute::WithSerde)? {
|
||||||
struct_body
|
struct_body
|
||||||
.push_parsed(format!(
|
.push_parsed(format!(
|
||||||
"{}: (<bincode::serde::BorrowCompat<_> as bincode::de::BorrowDecode>::borrow_decode(decoder)?).0,",
|
"{}: (<bincode::serde::BorrowCompat<_> as bincode::BorrowDecode>::borrow_decode(decoder)?).0,",
|
||||||
field
|
field
|
||||||
))?;
|
))?;
|
||||||
} else {
|
} else {
|
||||||
struct_body
|
struct_body
|
||||||
.push_parsed(format!(
|
.push_parsed(format!(
|
||||||
"{}: bincode::de::BorrowDecode::borrow_decode(decoder)?,",
|
"{}: bincode::BorrowDecode::borrow_decode(decoder)?,",
|
||||||
field
|
field
|
||||||
))?;
|
))?;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
26
docs/spec.md
26
docs/spec.md
|
|
@ -42,7 +42,7 @@ Encoding an unsigned integer v (of any type excepting u8/i8) works as follows:
|
||||||
|
|
||||||
`usize` is being encoded/decoded as a `u64` and `isize` is being encoded/decoded as a `i64`.
|
`usize` is being encoded/decoded as a `u64` and `isize` is being encoded/decoded as a `i64`.
|
||||||
|
|
||||||
See the documentation of [VarintEncoding](https://docs.rs/bincode/latest/bincode/config/struct.VarintEncoding.html) for more information.
|
See the documentation of [VarintEncoding](https://docs.rs/bincode/2.0.0-beta/bincode/config/struct.Configuration.html#method.with_variable_int_encoding) for more information.
|
||||||
|
|
||||||
### FixintEncoding
|
### FixintEncoding
|
||||||
|
|
||||||
|
|
@ -50,7 +50,7 @@ See the documentation of [VarintEncoding](https://docs.rs/bincode/latest/bincode
|
||||||
- Enum discriminants are encoded as u32
|
- Enum discriminants are encoded as u32
|
||||||
- Lengths and usize are encoded as u64
|
- Lengths and usize are encoded as u64
|
||||||
|
|
||||||
See the documentation of [FixintEncoding](https://docs.rs/bincode/latest/bincode/config/struct.FixintEncoding.html) for more information.
|
See the documentation of [FixintEncoding](https://docs.rs/bincode/2.0.0-beta/bincode/config/struct.Configuration.html#method.with_fixed_int_encoding) for more information.
|
||||||
|
|
||||||
## Enums
|
## Enums
|
||||||
|
|
||||||
|
|
@ -94,7 +94,7 @@ assert_eq!(encoded.as_slice(), &[
|
||||||
|
|
||||||
Collections are encoded with their length value first, following by each entry of the collection. The length value is based on your `IntEncoding`.
|
Collections are encoded with their length value first, following by each entry of the collection. The length value is based on your `IntEncoding`.
|
||||||
|
|
||||||
**note**: fixed array length do not have their `len` encoded. See [Arrays](#arrays)
|
**note**: fixed array length may not have their `len` encoded. See [Arrays](#arrays)
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use bincode::config::Configuration;
|
use bincode::config::Configuration;
|
||||||
|
|
@ -133,7 +133,10 @@ assert_eq!(encoded.as_slice(), &[
|
||||||
|
|
||||||
# Arrays
|
# Arrays
|
||||||
|
|
||||||
Arrays are encoded *with* a length by default.
|
Array length is encoded based on the `.write_fixed_array_length` and `.skip_fixed_array_length()` config. When an array length is written, it will be encoded as a `u64`.
|
||||||
|
|
||||||
|
Note that `&[T]` is encoded as a [Collection](#collections).
|
||||||
|
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use bincode::config::Configuration;
|
use bincode::config::Configuration;
|
||||||
|
|
@ -144,6 +147,12 @@ assert_eq!(encoded.as_slice(), &[
|
||||||
5, 0, 0, 0, 0, 0, 0, 0, // The length, as a u64
|
5, 0, 0, 0, 0, 0, 0, 0, // The length, as a u64
|
||||||
10, 20, 30, 40, 50, // the bytes
|
10, 20, 30, 40, 50, // the bytes
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
let encoded = bincode::encode_to_vec(arr, Configuration::legacy().skip_fixed_array_length()).unwrap();
|
||||||
|
assert_eq!(encoded.as_slice(), &[
|
||||||
|
// no length
|
||||||
|
10, 20, 30, 40, 50, // the bytes
|
||||||
|
]);
|
||||||
```
|
```
|
||||||
|
|
||||||
This applies to any type `T` that implements `Encode`/`Decode`
|
This applies to any type `T` that implements `Encode`/`Decode`
|
||||||
|
|
@ -168,11 +177,18 @@ let arr: [Foo; 2] = [
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
let encoded = bincode::encode_to_vec(arr, Configuration::legacy()).unwrap();
|
let encoded = bincode::encode_to_vec(&arr, Configuration::legacy()).unwrap();
|
||||||
assert_eq!(encoded.as_slice(), &[
|
assert_eq!(encoded.as_slice(), &[
|
||||||
2, 0, 0, 0, 0, 0, 0, 0, // Length of the array
|
2, 0, 0, 0, 0, 0, 0, 0, // Length of the array
|
||||||
10, 20, // First Foo
|
10, 20, // First Foo
|
||||||
30, 40, // Second Foo
|
30, 40, // Second Foo
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
let encoded = bincode::encode_to_vec(&arr, Configuration::legacy().skip_fixed_array_length()).unwrap();
|
||||||
|
assert_eq!(encoded.as_slice(), &[
|
||||||
|
// no length
|
||||||
|
10, 20, // First Foo
|
||||||
|
30, 40, // Second Foo
|
||||||
|
]);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
//! .write_fixed_array_length();
|
//! .write_fixed_array_length();
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! See [Config] for more information on the configuration options.
|
//! See [Configuration] for more information on the configuration options.
|
||||||
|
|
||||||
pub(crate) use self::internal::*;
|
pub(crate) use self::internal::*;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,54 @@ pub use self::decoder::DecoderImpl;
|
||||||
/// Whenever you implement `Decode` for your type, the base trait `BorrowDecode` is automatically implemented.
|
/// Whenever you implement `Decode` for your type, the base trait `BorrowDecode` is automatically implemented.
|
||||||
///
|
///
|
||||||
/// This trait will be automatically implemented if you enable the `derive` feature and add `#[derive(bincode::Decode)]` to your type. Note that if the type contains any lifetimes, `BorrowDecode` will be implemented instead.
|
/// This trait will be automatically implemented if you enable the `derive` feature and add `#[derive(bincode::Decode)]` to your type. Note that if the type contains any lifetimes, `BorrowDecode` will be implemented instead.
|
||||||
|
///
|
||||||
|
/// # Implementing this trait manually
|
||||||
|
///
|
||||||
|
/// If you want to implement this trait for your type, the easiest way is to add a `#[derive(bincode::Decode)]`, build and check your `target/` folder. This should generate a `<Struct name>_Decode.rs` file.
|
||||||
|
///
|
||||||
|
/// For this struct:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// struct Entity {
|
||||||
|
/// pub x: f32,
|
||||||
|
/// pub y: f32,
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// It will look something like:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # struct Entity {
|
||||||
|
/// # pub x: f32,
|
||||||
|
/// # pub y: f32,
|
||||||
|
/// # }
|
||||||
|
/// impl bincode::Decode for Entity {
|
||||||
|
/// fn decode<D: bincode::de::Decoder>(
|
||||||
|
/// decoder: &mut D,
|
||||||
|
/// ) -> core::result::Result<Self, bincode::error::DecodeError> {
|
||||||
|
/// Ok(Self {
|
||||||
|
/// x: bincode::Decode::decode(decoder)?,
|
||||||
|
/// y: bincode::Decode::decode(decoder)?,
|
||||||
|
/// })
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// From here you can add/remove fields, or add custom logic.
|
||||||
|
///
|
||||||
|
/// To get specific integer types, you can use:
|
||||||
|
/// ```
|
||||||
|
/// # struct Foo;
|
||||||
|
/// # impl bincode::Decode for Foo {
|
||||||
|
/// # fn decode<D: bincode::de::Decoder>(
|
||||||
|
/// # decoder: &mut D,
|
||||||
|
/// # ) -> core::result::Result<Self, bincode::error::DecodeError> {
|
||||||
|
/// let x: u8 = bincode::Decode::decode(decoder)?;
|
||||||
|
/// let x = <u8 as bincode::Decode>::decode(decoder)?;
|
||||||
|
/// # Ok(Foo)
|
||||||
|
/// # }
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
pub trait Decode: for<'de> BorrowDecode<'de> {
|
pub trait Decode: for<'de> BorrowDecode<'de> {
|
||||||
/// Attempt to decode this type with the given [Decode].
|
/// Attempt to decode this type with the given [Decode].
|
||||||
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError>;
|
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError>;
|
||||||
|
|
@ -55,7 +103,7 @@ pub trait Decoder: Sealed {
|
||||||
/// Returns a mutable reference to the reader
|
/// Returns a mutable reference to the reader
|
||||||
fn reader(&mut self) -> &mut Self::R;
|
fn reader(&mut self) -> &mut Self::R;
|
||||||
|
|
||||||
/// Returns a mutable reference to the config
|
/// Returns a reference to the config
|
||||||
fn config(&self) -> &Self::C;
|
fn config(&self) -> &Self::C;
|
||||||
|
|
||||||
/// Claim that `n` bytes are going to be read from the decoder.
|
/// Claim that `n` bytes are going to be read from the decoder.
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,40 @@ pub use self::encoder::EncoderImpl;
|
||||||
/// Any source that can be encoded. This trait should be implemented for all types that you want to be able to use with any of the `encode_with` methods.
|
/// Any source that can be encoded. This trait should be implemented for all types that you want to be able to use with any of the `encode_with` methods.
|
||||||
///
|
///
|
||||||
/// This trait will be automatically implemented if you enable the `derive` feature and add `#[derive(bincode::Encode)]` to your trait.
|
/// This trait will be automatically implemented if you enable the `derive` feature and add `#[derive(bincode::Encode)]` to your trait.
|
||||||
|
///
|
||||||
|
/// # Implementing this trait manually
|
||||||
|
///
|
||||||
|
/// If you want to implement this trait for your type, the easiest way is to add a `#[derive(bincode::Encode)]`, build and check your `target/` folder. This should generate a `<Struct name>_Encode.rs` file.
|
||||||
|
///
|
||||||
|
/// For this struct:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// struct Entity {
|
||||||
|
/// pub x: f32,
|
||||||
|
/// pub y: f32,
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
/// It will look something like:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # struct Entity {
|
||||||
|
/// # pub x: f32,
|
||||||
|
/// # pub y: f32,
|
||||||
|
/// # }
|
||||||
|
/// impl bincode::Encode for Entity {
|
||||||
|
/// fn encode<E: bincode::enc::Encoder>(
|
||||||
|
/// &self,
|
||||||
|
/// encoder: &mut E,
|
||||||
|
/// ) -> core::result::Result<(), bincode::error::EncodeError> {
|
||||||
|
/// bincode::Encode::encode(&self.x, encoder)?;
|
||||||
|
/// bincode::Encode::encode(&self.y, encoder)?;
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// From here you can add/remove fields, or add custom logic.
|
||||||
|
|
||||||
pub trait Encode {
|
pub trait Encode {
|
||||||
/// Encode a given type.
|
/// Encode a given type.
|
||||||
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError>;
|
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError>;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue