Skip to content

Commit

Permalink
Fix inconsistent naming between serde and non-serde functions (#671)
Browse files Browse the repository at this point in the history
* Fix inconsistent naming between serde and non-serde functions

* Updated references from old deprecated function

---------

Co-authored-by: Victor Koenders <[email protected]>
  • Loading branch information
VictorKoenders and Victor Koenders authored Oct 15, 2023
1 parent 08556ca commit 4977966
Show file tree
Hide file tree
Showing 9 changed files with 94 additions and 57 deletions.
58 changes: 29 additions & 29 deletions docs/migration_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,16 @@ bincode_2::config::legacy().with_variable_int_encoding()

If you want to be compatible with bincode 1, use the following table:

|Bincode 1|Bincode 2|
|---|---|
|version 1.0 - 1.2 with `bincode_1::DefaultOptions::new().serialize(T)`|`config::legacy()`|
|version 1.3+ with `bincode_1::DefaultOptions::new().serialize(T)`|`config::legacy().with_variable_int_encoding()`|
|No explicit `Options`, e.g. `bincode::serialize(T)`|`config::legacy()`|
| Bincode 1 | Bincode 2 |
| ---------------------------------------------------------------------- | ----------------------------------------------- |
| version 1.0 - 1.2 with `bincode_1::DefaultOptions::new().serialize(T)` | `config::legacy()` |
| version 1.3+ with `bincode_1::DefaultOptions::new().serialize(T)` | `config::legacy().with_variable_int_encoding()` |
| No explicit `Options`, e.g. `bincode::serialize(T)` | `config::legacy()` |

If you do not care about compatibility with bincode 1, we recommend using `config::standard()`

The following changes have been made:

- `.with_limit(n)` has been changed to `.with_limit::<n>()`.
- `.with_native_endian()` has been removed. Use `.with_big_endian()` or `with_little_endian()` instead.
- `.with_varint_encoding()` has been renamed to `.with_variable_int_encoding()`.
Expand All @@ -49,18 +50,17 @@ bincode = { version = "2.0.0-rc", features = ["serde"] }
# bincode = { version = "2.0.0-rc", default-features = false, features = ["std", "serde"] }
```


Then replace the following functions: (`Configuration` is `bincode::config::legacy()` by default)

|Bincode 1|Bincode 2|
|--|--|
|`bincode::deserialize(&[u8])`|`bincode::serde::decode_from_slice(&[u8], Configuration)`<br />`bincode::serde::decode_borrowed_from_slice(&[u8], Configuration)`|
|`bincode::deserialize_from(std::io::Read)`|`bincode::serde::decode_from_std_read(std::io::Read, Configuration)`|
|`bincode::deserialize_from_custom(BincodeRead)`|`bincode::serde::decode_from_reader(Reader, Configuration)`|
|||
|`bincode::serialize(T)`|`bincode::serde::encode_to_vec(T, Configuration)`<br />`bincode::serde::encode_into_slice(T, &mut [u8], Configuration)`|
|`bincode::serialize_into(std::io::Write, T)`|`bincode::serde::encode_into_std_write(T, std::io::Write, Configuration)`|
|`bincode::serialized_size(T)`|Currently not implemented|
| Bincode 1 | Bincode 2 |
| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `bincode::deserialize(&[u8])` | `bincode::serde::decode_from_slice(&[u8], Configuration)`<br />`bincode::serde::borrow_decode_from_slice(&[u8], Configuration)` |
| `bincode::deserialize_from(std::io::Read)` | `bincode::serde::decode_from_std_read(std::io::Read, Configuration)` |
| `bincode::deserialize_from_custom(BincodeRead)` | `bincode::serde::decode_from_reader(Reader, Configuration)` |
| | |
| `bincode::serialize(T)` | `bincode::serde::encode_to_vec(T, Configuration)`<br />`bincode::serde::encode_into_slice(T, &mut [u8], Configuration)` |
| `bincode::serialize_into(std::io::Write, T)` | `bincode::serde::encode_into_std_write(T, std::io::Write, Configuration)` |
| `bincode::serialized_size(T)` | Currently not implemented |

## Migrating to `bincode-derive`

Expand All @@ -79,31 +79,31 @@ bincode = "2.0.0-rc"

Replace or add the following attributes. You are able to use both `serde-derive` and `bincode-derive` side-by-side.

|serde-derive|bincode-derive|
|---|---|
|`#[derive(serde::Serialize)]`|`#[derive(bincode::Encode)]`|
|`#[derive(serde::Deserialize)]`|`#[derive(bincode::Decode)]`|
| serde-derive | bincode-derive |
| ------------------------------- | ---------------------------- |
| `#[derive(serde::Serialize)]` | `#[derive(bincode::Encode)]` |
| `#[derive(serde::Deserialize)]` | `#[derive(bincode::Decode)]` |

**note:** To implement these traits manually, see the documentation of [Encode](https://docs.rs/bincode/2.0.0-rc/bincode/enc/trait.Encode.html) and [Decode](https://docs.rs/bincode/2.0.0-rc/bincode/de/trait.Decode.html).

**note:** For more information on using `bincode-derive` with external libraries, see [below](#bincode-derive-and-libraries).

Then replace the following functions: (`Configuration` is `bincode::config::legacy()` by default)

|Bincode 1|Bincode 2|
|--|--|
|`bincode::deserialize(&[u8])`|`bincode::decode_from_slice(&bytes, Configuration)`<br />`bincode::decode_borrowed_from_slice(&[u8], Configuration)`|
|`bincode::deserialize_from(std::io::Read)`|`bincode::decode_from_std_read(std::io::Read, Configuration)`|
|`bincode::deserialize_from_custom(BincodeRead)`|`bincode::decode_from_reader(Reader, Configuration)`|
|||
|`bincode::serialize(T)`|`bincode::encode_to_vec(T, Configuration)`<br />`bincode::encode_into_slice(t: T, &mut [u8], Configuration)`|
|`bincode::serialize_into(std::io::Write, T)`|`bincode::encode_into_std_write(T, std::io::Write, Configuration)`|
|`bincode::serialized_size(T)`|Currently not implemented|

| Bincode 1 | Bincode 2 |
| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| `bincode::deserialize(&[u8])` | `bincode::decode_from_slice(&bytes, Configuration)`<br />`bincode::borrow_decode_from_slice(&[u8], Configuration)` |
| `bincode::deserialize_from(std::io::Read)` | `bincode::decode_from_std_read(std::io::Read, Configuration)` |
| `bincode::deserialize_from_custom(BincodeRead)` | `bincode::decode_from_reader(Reader, Configuration)` |
| | |
| `bincode::serialize(T)` | `bincode::encode_to_vec(T, Configuration)`<br />`bincode::encode_into_slice(t: T, &mut [u8], Configuration)` |
| `bincode::serialize_into(std::io::Write, T)` | `bincode::encode_into_std_write(T, std::io::Write, Configuration)` |
| `bincode::serialized_size(T)` | Currently not implemented |

### Bincode derive and libraries

Currently not many libraries support the traits `Encode` and `Decode`. There are a couple of options if you want to use `#[derive(bincode::Encode, bincode::Decode)]`:

- Enable the `serde` feature and add a `#[bincode(with_serde)]` above each field that implements `serde::Serialize/Deserialize` but not `Encode/Decode`
- Enable the `serde` feature and wrap your field in [bincode::serde::Compat](https://docs.rs/bincode/2.0.0-rc/bincode/serde/struct.Compat.html) or [bincode::serde::BorrowCompat](https://docs.rs/bincode/2.0.0-rc/bincode/serde/struct.BorrowCompat.html)
- Make a pull request to the library:
Expand Down
2 changes: 1 addition & 1 deletion src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ pub enum EncodeError {
/// The writer ran out of storage.
UnexpectedEnd,

/// The RefCell<T> is already borrowed
/// The `RefCell<T>` is already borrowed
RefCellAlreadyBorrowed {
/// The inner borrow error
inner: core::cell::BorrowError,
Expand Down
6 changes: 2 additions & 4 deletions src/features/impl_alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,7 @@ where
if unty::type_equal::<T, u8>() {
decoder.claim_container_read::<T>(len)?;
// optimize for reading u8 vecs
let mut vec = Vec::new();
vec.resize(len, 0u8);
let mut vec = alloc::vec![0u8; len];
decoder.reader().read(&mut vec)?;
// Safety: Vec<T> is Vec<u8>
Ok(unsafe { core::mem::transmute(vec) })
Expand Down Expand Up @@ -288,8 +287,7 @@ where
if unty::type_equal::<T, u8>() {
decoder.claim_container_read::<T>(len)?;
// optimize for reading u8 vecs
let mut vec = Vec::new();
vec.resize(len, 0u8);
let mut vec = alloc::vec![0u8; len];
decoder.reader().read(&mut vec)?;
// Safety: Vec<T> is Vec<u8>
Ok(unsafe { core::mem::transmute(vec) })
Expand Down
23 changes: 23 additions & 0 deletions src/features/serde/de_borrowed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,29 @@ use crate::{
use core::marker::PhantomData;
use serde::de::*;

/// Attempt to decode a given type `D` from the given slice. Returns the decoded output and the amount of bytes read.
///
/// See the [config](../config/index.html) module for more information on configurations.
pub fn borrow_decode_from_slice<'de, D, C>(
slice: &'de [u8],
config: C,
) -> Result<(D, usize), DecodeError>
where
D: Deserialize<'de>,
C: Config,
{
let reader = crate::de::read::SliceReader::new(slice);
let mut decoder = crate::de::DecoderImpl::new(reader, config);
let serde_decoder = SerdeDecoder {
de: &mut decoder,
pd: PhantomData,
};
let result = D::deserialize(serde_decoder)?;
let bytes_read = slice.len() - decoder.borrow_reader().slice.len();
Ok((result, bytes_read))
}

#[deprecated(note = "Use borrow_decode_from_slice instead")]
/// Decode a borrowed type from the given slice. Some parts of the decoded type are expected to be referring to the given slice
pub fn decode_borrowed_from_slice<'de, T, C>(slice: &'de [u8], config: C) -> Result<T, DecodeError>
where
Expand Down
23 changes: 15 additions & 8 deletions src/features/serde/de_owned.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,32 @@ use crate::{
};
use serde::de::*;

/// Decode an owned type from the given slice. Will return the decoded type `T` as well as the amount of bytes that were read.
/// Attempt to decode a given type `D` from the given slice. Returns the decoded output and the amount of bytes read.
///
/// Note that this does not work with borrowed types like `&str` or `&[u8]`. For that use [decode_borrowed_from_slice].
/// Note that this does not work with borrowed types like `&str` or `&[u8]`. For that use [borrow_decode_from_slice].
///
/// [decode_borrowed_from_slice]: fn.decode_borrowed_from_slice.html
pub fn decode_from_slice<T, C>(slice: &[u8], config: C) -> Result<(T, usize), DecodeError>
/// See the [config] module for more information on configurations.
///
/// [borrow_decode_from_slice]: fn.borrow_decode_from_slice.html
/// [config]: ../config/index.html
pub fn decode_from_slice<D, C>(slice: &[u8], config: C) -> Result<(D, usize), DecodeError>
where
T: DeserializeOwned,
D: DeserializeOwned,
C: Config,
{
let reader = crate::de::read::SliceReader::new(slice);
let mut decoder = crate::de::DecoderImpl::new(reader, config);
let serde_decoder = SerdeDecoder { de: &mut decoder };
let result = T::deserialize(serde_decoder)?;
let result = D::deserialize(serde_decoder)?;
let bytes_read = slice.len() - decoder.reader().slice.len();
Ok((result, bytes_read))
}

/// Decode an owned type from the given `std::io::Read`.
/// Decode type `D` from the given reader with the given `Config`. The reader can be any type that implements `std::io::Read`, e.g. `std::fs::File`.
///
/// See the [config] module for more information about config options.
///
/// [config]: ../config/index.html
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
pub fn decode_from_std_read<D: DeserializeOwned, C: Config, R: std::io::Read>(
Expand All @@ -41,7 +48,7 @@ pub fn decode_from_std_read<D: DeserializeOwned, C: Config, R: std::io::Read>(
///
/// See the [config] module for more information on configurations.
///
/// [config]: config/index.html
/// [config]: ../config/index.html
pub fn decode_from_reader<D: DeserializeOwned, R: Reader, C: Config>(
reader: R,
config: C,
Expand Down
2 changes: 1 addition & 1 deletion src/features/serde/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Support for serde integration. Enable this with the `serde` feature.
//!
//! To encode/decode type that implement serde's trait, you can use:
//! - [decode_borrowed_from_slice]
//! - [borrow_decode_from_slice]
//! - [decode_from_slice]
//! - [encode_into_slice]
//! - [encode_to_vec]
Expand Down
28 changes: 17 additions & 11 deletions src/features/serde/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,38 +8,44 @@ use crate::{
use alloc::vec::Vec;
use serde::ser::*;

/// Encode the given value into a `Vec<u8>` with the given `Config`. See the [config] module for more information.
///
/// [config]: ../config/index.html
#[cfg(feature = "alloc")]
/// Encode a `serde` `Serialize` type into a `Vec<u8>` with the bincode algorithm
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
pub fn encode_to_vec<T, C>(t: T, config: C) -> Result<Vec<u8>, EncodeError>
pub fn encode_to_vec<E, C>(val: E, config: C) -> Result<Vec<u8>, EncodeError>
where
T: Serialize,
E: Serialize,
C: Config,
{
let mut encoder = crate::enc::EncoderImpl::new(crate::VecWriter::default(), config);
let serializer = SerdeEncoder { enc: &mut encoder };
t.serialize(serializer)?;
val.serialize(serializer)?;
Ok(encoder.into_writer().collect())
}

/// Encode a `serde` `Serialize` type into a given byte slice with the bincode algorithm
pub fn encode_into_slice<T, C>(t: T, slice: &mut [u8], config: C) -> Result<usize, EncodeError>
/// Encode the given value into the given slice. Returns the amount of bytes that have been written.
///
/// See the [config] module for more information on configurations.
///
/// [config]: ../config/index.html
pub fn encode_into_slice<E, C>(val: E, dst: &mut [u8], config: C) -> Result<usize, EncodeError>
where
T: Serialize,
E: Serialize,
C: Config,
{
let mut encoder =
crate::enc::EncoderImpl::new(crate::enc::write::SliceWriter::new(slice), config);
crate::enc::EncoderImpl::new(crate::enc::write::SliceWriter::new(dst), config);
let serializer = SerdeEncoder { enc: &mut encoder };
t.serialize(serializer)?;
val.serialize(serializer)?;
Ok(encoder.into_writer().bytes_written())
}

/// Encode the given value into a custom [Writer].
///
/// See the [config] module for more information on configurations.
///
/// [config]: config/index.html
/// [config]: ../config/index.html
pub fn encode_into_writer<E: Serialize, W: Writer, C: Config>(
val: E,
writer: W,
Expand All @@ -54,7 +60,7 @@ pub fn encode_into_writer<E: Serialize, W: Writer, C: Config>(
/// Encode the given value into any type that implements `std::io::Write`, e.g. `std::fs::File`, with the given `Config`.
/// See the [config] module for more information.
///
/// [config]: config/index.html
/// [config]: ../config/index.html
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
#[cfg(feature = "std")]
pub fn encode_into_std_write<E: Serialize, C: Config, W: std::io::Write>(
Expand Down
4 changes: 3 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
//! |---|---|---
//! |You're working with [`fs::File`] or [`net::TcpStream`]|[`encode_into_std_write`]|[`decode_from_std_read`]|
//! |you're working with in-memory buffers|[`encode_to_vec`]|[`decode_from_slice`]|
//! |You want to use a custom [Reader](de::read::Reader) and [writer](enc::write::Writer)|[`encode_into_writer`]|[`decode_from_reader`]|
//! |You want to use a custom [Reader] and [Writer]|[`encode_into_writer`]|[`decode_from_reader`]|
//! |You're working with pre-allocated buffers or on embedded targets|[`encode_into_slice`]|[`decode_from_slice`]|
//!
//! **Note:** If you're using `serde`, use `bincode::serde::...` instead of `bincode::...`
Expand Down Expand Up @@ -134,6 +134,8 @@ pub fn encode_into_writer<E: enc::Encode, W: Writer, C: Config>(

/// Attempt to decode a given type `D` from the given slice. Returns the decoded output and the amount of bytes read.
///
/// Note that this does not work with borrowed types like `&str` or `&[u8]`. For that use [borrow_decode_from_slice].
///
/// See the [config] module for more information on configurations.
///
/// [config]: config/index.html
Expand Down
5 changes: 3 additions & 2 deletions tests/serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,16 @@ fn test_serialize_deserialize_borrowed_data() {

assert_eq!(result, expected);

let output: SerdeWithBorrowedData =
bincode::serde::decode_borrowed_from_slice(&result, bincode::config::standard()).unwrap();
let (output, len): (SerdeWithBorrowedData, usize) =
bincode::serde::borrow_decode_from_slice(&result, bincode::config::standard()).unwrap();
assert_eq!(
SerdeWithBorrowedData {
b: 0, // remember: b is skipped
..input
},
output
);
assert_eq!(len, 13);
}

#[derive(Serialize, Deserialize, PartialEq, Eq, Debug)]
Expand Down

0 comments on commit 4977966

Please sign in to comment.