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 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
|
||||
where
|
||||
T: Decode,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
use core::cell::{Cell, RefCell};
|
||||
|
||||
use super::{Encode, Encodeable};
|
||||
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
|
||||
where
|
||||
T: Encode,
|
||||
|
|
|
|||
|
|
@ -7,6 +7,14 @@ pub enum EncodeError {
|
|||
/// The writer ran out of storage.
|
||||
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`
|
||||
#[cfg(feature = "std")]
|
||||
Io {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
mod utils;
|
||||
|
||||
use core::cell::Cell;
|
||||
use std::cell::RefCell;
|
||||
use utils::the_same;
|
||||
|
||||
#[test]
|
||||
|
|
@ -63,12 +65,31 @@ fn test_numbers() {
|
|||
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>::Some(1234));
|
||||
|
||||
the_same(Result::<u32, u8>::Ok(1555));
|
||||
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]
|
||||
|
|
|
|||
Loading…
Reference in New Issue