mirror of https://git.sr.ht/~stygianentity/bincode
Added support for Cell and RefCell
This commit is contained in:
parent
07f49e878e
commit
1d6379e715
|
|
@ -1,3 +1,5 @@
|
||||||
|
use core::cell::{Cell, RefCell};
|
||||||
|
|
||||||
use super::{BorrowDecodable, BorrowDecode, Decodable, Decode};
|
use super::{BorrowDecodable, BorrowDecode, Decodable, Decode};
|
||||||
use crate::error::DecodeError;
|
use crate::error::DecodeError;
|
||||||
|
|
||||||
|
|
@ -175,6 +177,26 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'de, T> Decodable for Cell<T>
|
||||||
|
where
|
||||||
|
T: Decodable,
|
||||||
|
{
|
||||||
|
fn decode<D: Decode>(decoder: D) -> Result<Self, DecodeError> {
|
||||||
|
let t = T::decode(decoder)?;
|
||||||
|
Ok(Cell::new(t))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de, T> Decodable for RefCell<T>
|
||||||
|
where
|
||||||
|
T: Decodable,
|
||||||
|
{
|
||||||
|
fn decode<D: Decode>(decoder: D) -> Result<Self, DecodeError> {
|
||||||
|
let t = T::decode(decoder)?;
|
||||||
|
Ok(RefCell::new(t))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, 'de, T> Decode for &'a mut T
|
impl<'a, 'de, T> Decode for &'a mut T
|
||||||
where
|
where
|
||||||
T: Decode,
|
T: Decode,
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
use core::cell::{Cell, RefCell};
|
||||||
|
|
||||||
use super::{Encode, Encodeable};
|
use super::{Encode, Encodeable};
|
||||||
use crate::error::EncodeError;
|
use crate::error::EncodeError;
|
||||||
|
|
||||||
|
|
@ -169,6 +171,39 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> Encodeable for Cell<T>
|
||||||
|
where
|
||||||
|
T: Encodeable + Copy,
|
||||||
|
{
|
||||||
|
fn encode<E: Encode>(&self, encoder: E) -> Result<(), EncodeError> {
|
||||||
|
T::encode(&self.get(), encoder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Encodeable for RefCell<T>
|
||||||
|
where
|
||||||
|
T: Encodeable,
|
||||||
|
{
|
||||||
|
fn encode<E: Encode>(&self, encoder: E) -> Result<(), EncodeError> {
|
||||||
|
let borrow_guard = self
|
||||||
|
.try_borrow()
|
||||||
|
.map_err(|e| EncodeError::RefCellAlreadyBorrowed {
|
||||||
|
inner: e,
|
||||||
|
type_name: core::any::type_name::<RefCell<T>>(),
|
||||||
|
})?;
|
||||||
|
T::encode(&borrow_guard, encoder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T> Encodeable for &'a T
|
||||||
|
where
|
||||||
|
T: Encodeable,
|
||||||
|
{
|
||||||
|
fn encode<E: Encode>(&self, encoder: E) -> Result<(), EncodeError> {
|
||||||
|
T::encode(self, encoder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, T> Encode for &'a mut T
|
impl<'a, T> Encode for &'a mut T
|
||||||
where
|
where
|
||||||
T: Encode,
|
T: Encode,
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,14 @@ pub enum EncodeError {
|
||||||
/// The writer ran out of storage.
|
/// The writer ran out of storage.
|
||||||
UnexpectedEnd,
|
UnexpectedEnd,
|
||||||
|
|
||||||
|
/// The RefCell<T> is already borrowed
|
||||||
|
RefCellAlreadyBorrowed {
|
||||||
|
/// The inner borrow error
|
||||||
|
inner: core::cell::BorrowError,
|
||||||
|
/// the type name of the RefCell being encoded that is currently borrowed.
|
||||||
|
type_name: &'static str,
|
||||||
|
},
|
||||||
|
|
||||||
/// The targetted writer encountered an `std::io::Error`
|
/// The targetted writer encountered an `std::io::Error`
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
Io {
|
Io {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
|
use core::cell::Cell;
|
||||||
|
use std::cell::RefCell;
|
||||||
use utils::the_same;
|
use utils::the_same;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -63,12 +65,31 @@ fn test_numbers() {
|
||||||
241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
|
241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Option and Result
|
// Common types
|
||||||
the_same(Option::<u32>::None);
|
the_same(Option::<u32>::None);
|
||||||
the_same(Option::<u32>::Some(1234));
|
the_same(Option::<u32>::Some(1234));
|
||||||
|
|
||||||
the_same(Result::<u32, u8>::Ok(1555));
|
the_same(Result::<u32, u8>::Ok(1555));
|
||||||
the_same(Result::<u32, u8>::Err(15));
|
the_same(Result::<u32, u8>::Err(15));
|
||||||
|
|
||||||
|
the_same(Cell::<u32>::new(15));
|
||||||
|
the_same(RefCell::<u32>::new(15));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_refcell_already_borrowed() {
|
||||||
|
let cell = RefCell::new(5u32);
|
||||||
|
// first get a mutable reference to the cell
|
||||||
|
let _mutable_guard = cell.borrow_mut();
|
||||||
|
// now try to encode it
|
||||||
|
let mut slice = [0u8; 10];
|
||||||
|
let result = bincode::encode_into_slice(&cell, &mut slice)
|
||||||
|
.expect_err("Encoding a borrowed refcell should fail");
|
||||||
|
|
||||||
|
match result {
|
||||||
|
bincode::error::EncodeError::RefCellAlreadyBorrowed { .. } => {} // ok
|
||||||
|
x => panic!("Expected a RefCellAlreadyBorrowed error, found {:?}", x),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue