Added support for atomic integers
This commit is contained in:
parent
8ab730eb87
commit
1f261cede3
|
|
@ -23,9 +23,10 @@ description = "A binary serialization / deserialization strategy for transformin
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["std", "derive"]
|
default = ["std", "derive", "atomic"]
|
||||||
std = ["alloc"]
|
std = ["alloc"]
|
||||||
alloc = []
|
alloc = []
|
||||||
|
atomic = []
|
||||||
derive = ["bincode_derive"]
|
derive = ["bincode_derive"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,137 @@
|
||||||
|
use crate::{de::Decodable, enc::Encodeable};
|
||||||
|
use core::sync::atomic::{
|
||||||
|
AtomicBool, AtomicI16, AtomicI32, AtomicI64, AtomicI8, AtomicIsize, AtomicU16, AtomicU32,
|
||||||
|
AtomicU64, AtomicU8, AtomicUsize, Ordering,
|
||||||
|
};
|
||||||
|
|
||||||
|
impl Encodeable for AtomicBool {
|
||||||
|
fn encode<E: crate::enc::Encode>(&self, encoder: E) -> Result<(), crate::error::EncodeError> {
|
||||||
|
self.load(Ordering::SeqCst).encode(encoder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Decodable for AtomicBool {
|
||||||
|
fn decode<D: crate::de::Decode>(decoder: D) -> Result<Self, crate::error::DecodeError> {
|
||||||
|
Ok(AtomicBool::new(Decodable::decode(decoder)?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Encodeable for AtomicU8 {
|
||||||
|
fn encode<E: crate::enc::Encode>(&self, encoder: E) -> Result<(), crate::error::EncodeError> {
|
||||||
|
self.load(Ordering::SeqCst).encode(encoder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Decodable for AtomicU8 {
|
||||||
|
fn decode<D: crate::de::Decode>(decoder: D) -> Result<Self, crate::error::DecodeError> {
|
||||||
|
Ok(AtomicU8::new(Decodable::decode(decoder)?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Encodeable for AtomicU16 {
|
||||||
|
fn encode<E: crate::enc::Encode>(&self, encoder: E) -> Result<(), crate::error::EncodeError> {
|
||||||
|
self.load(Ordering::SeqCst).encode(encoder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Decodable for AtomicU16 {
|
||||||
|
fn decode<D: crate::de::Decode>(decoder: D) -> Result<Self, crate::error::DecodeError> {
|
||||||
|
Ok(AtomicU16::new(Decodable::decode(decoder)?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Encodeable for AtomicU32 {
|
||||||
|
fn encode<E: crate::enc::Encode>(&self, encoder: E) -> Result<(), crate::error::EncodeError> {
|
||||||
|
self.load(Ordering::SeqCst).encode(encoder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Decodable for AtomicU32 {
|
||||||
|
fn decode<D: crate::de::Decode>(decoder: D) -> Result<Self, crate::error::DecodeError> {
|
||||||
|
Ok(AtomicU32::new(Decodable::decode(decoder)?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Encodeable for AtomicU64 {
|
||||||
|
fn encode<E: crate::enc::Encode>(&self, encoder: E) -> Result<(), crate::error::EncodeError> {
|
||||||
|
self.load(Ordering::SeqCst).encode(encoder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Decodable for AtomicU64 {
|
||||||
|
fn decode<D: crate::de::Decode>(decoder: D) -> Result<Self, crate::error::DecodeError> {
|
||||||
|
Ok(AtomicU64::new(Decodable::decode(decoder)?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Encodeable for AtomicUsize {
|
||||||
|
fn encode<E: crate::enc::Encode>(&self, encoder: E) -> Result<(), crate::error::EncodeError> {
|
||||||
|
self.load(Ordering::SeqCst).encode(encoder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Decodable for AtomicUsize {
|
||||||
|
fn decode<D: crate::de::Decode>(decoder: D) -> Result<Self, crate::error::DecodeError> {
|
||||||
|
Ok(AtomicUsize::new(Decodable::decode(decoder)?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Encodeable for AtomicI8 {
|
||||||
|
fn encode<E: crate::enc::Encode>(&self, encoder: E) -> Result<(), crate::error::EncodeError> {
|
||||||
|
self.load(Ordering::SeqCst).encode(encoder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Decodable for AtomicI8 {
|
||||||
|
fn decode<D: crate::de::Decode>(decoder: D) -> Result<Self, crate::error::DecodeError> {
|
||||||
|
Ok(AtomicI8::new(Decodable::decode(decoder)?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Encodeable for AtomicI16 {
|
||||||
|
fn encode<E: crate::enc::Encode>(&self, encoder: E) -> Result<(), crate::error::EncodeError> {
|
||||||
|
self.load(Ordering::SeqCst).encode(encoder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Decodable for AtomicI16 {
|
||||||
|
fn decode<D: crate::de::Decode>(decoder: D) -> Result<Self, crate::error::DecodeError> {
|
||||||
|
Ok(AtomicI16::new(Decodable::decode(decoder)?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Encodeable for AtomicI32 {
|
||||||
|
fn encode<E: crate::enc::Encode>(&self, encoder: E) -> Result<(), crate::error::EncodeError> {
|
||||||
|
self.load(Ordering::SeqCst).encode(encoder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Decodable for AtomicI32 {
|
||||||
|
fn decode<D: crate::de::Decode>(decoder: D) -> Result<Self, crate::error::DecodeError> {
|
||||||
|
Ok(AtomicI32::new(Decodable::decode(decoder)?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Encodeable for AtomicI64 {
|
||||||
|
fn encode<E: crate::enc::Encode>(&self, encoder: E) -> Result<(), crate::error::EncodeError> {
|
||||||
|
self.load(Ordering::SeqCst).encode(encoder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Decodable for AtomicI64 {
|
||||||
|
fn decode<D: crate::de::Decode>(decoder: D) -> Result<Self, crate::error::DecodeError> {
|
||||||
|
Ok(AtomicI64::new(Decodable::decode(decoder)?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Encodeable for AtomicIsize {
|
||||||
|
fn encode<E: crate::enc::Encode>(&self, encoder: E) -> Result<(), crate::error::EncodeError> {
|
||||||
|
self.load(Ordering::SeqCst).encode(encoder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Decodable for AtomicIsize {
|
||||||
|
fn decode<D: crate::de::Decode>(decoder: D) -> Result<Self, crate::error::DecodeError> {
|
||||||
|
Ok(AtomicIsize::new(Decodable::decode(decoder)?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
|
#[cfg(feature = "atomic")]
|
||||||
|
mod atomic;
|
||||||
|
#[cfg(feature = "atomic")]
|
||||||
|
pub use self::atomic::*;
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
mod impl_alloc;
|
mod impl_alloc;
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ use alloc::borrow::Cow;
|
||||||
use alloc::collections::*;
|
use alloc::collections::*;
|
||||||
use alloc::rc::Rc;
|
use alloc::rc::Rc;
|
||||||
use alloc::sync::Arc;
|
use alloc::sync::Arc;
|
||||||
use utils::the_same;
|
use utils::{the_same, the_same_with_comparer};
|
||||||
|
|
||||||
struct Foo {
|
struct Foo {
|
||||||
pub a: u32,
|
pub a: u32,
|
||||||
|
|
@ -55,6 +55,18 @@ fn test_alloc_commons() {
|
||||||
the_same(Cow::<u32>::Borrowed(&5));
|
the_same(Cow::<u32>::Borrowed(&5));
|
||||||
the_same(Rc::<u32>::new(5));
|
the_same(Rc::<u32>::new(5));
|
||||||
the_same(Arc::<u32>::new(5));
|
the_same(Arc::<u32>::new(5));
|
||||||
|
the_same_with_comparer(
|
||||||
|
{
|
||||||
|
let mut map = BinaryHeap::<u32>::new();
|
||||||
|
map.push(1);
|
||||||
|
map.push(2);
|
||||||
|
map.push(3);
|
||||||
|
map.push(4);
|
||||||
|
map.push(5);
|
||||||
|
map
|
||||||
|
},
|
||||||
|
|a, b| a.into_iter().collect::<Vec<_>>() == b.into_iter().collect::<Vec<_>>(),
|
||||||
|
);
|
||||||
the_same({
|
the_same({
|
||||||
let mut map = BTreeMap::<u32, i32>::new();
|
let mut map = BTreeMap::<u32, i32>::new();
|
||||||
map.insert(5, -5);
|
map.insert(5, -5);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
#![cfg(feature = "atomic")]
|
||||||
|
|
||||||
|
mod utils;
|
||||||
|
|
||||||
|
use core::sync::atomic::{
|
||||||
|
AtomicBool, AtomicI16, AtomicI32, AtomicI64, AtomicI8, AtomicIsize, AtomicU16, AtomicU32,
|
||||||
|
AtomicU64, AtomicU8, AtomicUsize, Ordering,
|
||||||
|
};
|
||||||
|
use utils::the_same_with_comparer;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_atomic_commons() {
|
||||||
|
the_same_with_comparer(AtomicBool::new(true), |a, b| {
|
||||||
|
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
||||||
|
});
|
||||||
|
the_same_with_comparer(AtomicBool::new(false), |a, b| {
|
||||||
|
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
||||||
|
});
|
||||||
|
the_same_with_comparer(AtomicU8::new(0), |a, b| {
|
||||||
|
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
||||||
|
});
|
||||||
|
the_same_with_comparer(AtomicU16::new(0), |a, b| {
|
||||||
|
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
||||||
|
});
|
||||||
|
the_same_with_comparer(AtomicU32::new(0), |a, b| {
|
||||||
|
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
||||||
|
});
|
||||||
|
the_same_with_comparer(AtomicU64::new(0), |a, b| {
|
||||||
|
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
||||||
|
});
|
||||||
|
the_same_with_comparer(AtomicUsize::new(0), |a, b| {
|
||||||
|
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
||||||
|
});
|
||||||
|
the_same_with_comparer(AtomicI8::new(0), |a, b| {
|
||||||
|
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
||||||
|
});
|
||||||
|
the_same_with_comparer(AtomicI16::new(0), |a, b| {
|
||||||
|
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
||||||
|
});
|
||||||
|
the_same_with_comparer(AtomicI32::new(0), |a, b| {
|
||||||
|
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
||||||
|
});
|
||||||
|
the_same_with_comparer(AtomicI64::new(0), |a, b| {
|
||||||
|
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
||||||
|
});
|
||||||
|
the_same_with_comparer(AtomicIsize::new(0), |a, b| {
|
||||||
|
a.load(Ordering::SeqCst) == b.load(Ordering::SeqCst)
|
||||||
|
});
|
||||||
|
}
|
||||||
21
tests/std.rs
21
tests/std.rs
|
|
@ -11,6 +11,8 @@ use std::{
|
||||||
};
|
};
|
||||||
use utils::the_same;
|
use utils::the_same;
|
||||||
|
|
||||||
|
use crate::utils::the_same_with_comparer;
|
||||||
|
|
||||||
struct Foo {
|
struct Foo {
|
||||||
pub a: u32,
|
pub a: u32,
|
||||||
pub b: u32,
|
pub b: u32,
|
||||||
|
|
@ -79,7 +81,14 @@ fn test_std_commons() {
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
)));
|
)));
|
||||||
|
the_same_with_comparer(Mutex::new("Hello world".to_string()), |a, b| {
|
||||||
|
&*a.lock().unwrap() == &*b.lock().unwrap()
|
||||||
|
});
|
||||||
|
the_same_with_comparer(RwLock::new("Hello world".to_string()), |a, b| {
|
||||||
|
&*a.read().unwrap() == &*b.read().unwrap()
|
||||||
|
});
|
||||||
|
|
||||||
|
// Borrowed values
|
||||||
let config = bincode::config::Default;
|
let config = bincode::config::Default;
|
||||||
let mut buffer = [0u8; 1024];
|
let mut buffer = [0u8; 1024];
|
||||||
|
|
||||||
|
|
@ -89,18 +98,6 @@ fn test_std_commons() {
|
||||||
let decoded: &CStr = bincode::decode_with_config(&mut buffer[..len], config).unwrap();
|
let decoded: &CStr = bincode::decode_with_config(&mut buffer[..len], config).unwrap();
|
||||||
assert_eq!(cstr, decoded);
|
assert_eq!(cstr, decoded);
|
||||||
|
|
||||||
// Mutex<T>
|
|
||||||
let mutex = Mutex::new("Hello world".to_string());
|
|
||||||
let len = bincode::encode_into_slice_with_config(&mutex, &mut buffer, config).unwrap();
|
|
||||||
let decoded: Mutex<String> = bincode::decode_with_config(&mut buffer[..len], config).unwrap();
|
|
||||||
assert_eq!(&*mutex.lock().unwrap(), &*decoded.lock().unwrap());
|
|
||||||
|
|
||||||
// RwLock<T>
|
|
||||||
let rwlock = RwLock::new("Hello world".to_string());
|
|
||||||
let len = bincode::encode_into_slice_with_config(&rwlock, &mut buffer, config).unwrap();
|
|
||||||
let decoded: RwLock<String> = bincode::decode_with_config(&mut buffer[..len], config).unwrap();
|
|
||||||
assert_eq!(&*rwlock.read().unwrap(), &*decoded.read().unwrap());
|
|
||||||
|
|
||||||
// Path
|
// Path
|
||||||
let path = Path::new("C:/Program Files/Foo");
|
let path = Path::new("C:/Program Files/Foo");
|
||||||
let len = bincode::encode_into_slice_with_config(path, &mut buffer, config).unwrap();
|
let len = bincode::encode_into_slice_with_config(path, &mut buffer, config).unwrap();
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,14 @@
|
||||||
use bincode::config::{self, Config};
|
use bincode::config::{self, Config};
|
||||||
use core::fmt::Debug;
|
use core::fmt::Debug;
|
||||||
|
|
||||||
fn the_same_with_config<V, C>(element: V, config: C)
|
fn the_same_with_config<V, C, CMP>(element: &V, config: C, cmp: CMP)
|
||||||
where
|
where
|
||||||
V: bincode::enc::Encodeable + bincode::de::Decodable + PartialEq + Debug + Clone + 'static,
|
V: bincode::enc::Encodeable + bincode::de::Decodable + Debug + 'static,
|
||||||
C: Config,
|
C: Config,
|
||||||
|
CMP: Fn(&V, &V) -> bool,
|
||||||
{
|
{
|
||||||
let mut buffer = [0u8; 1024];
|
let mut buffer = [0u8; 1024];
|
||||||
let len = bincode::encode_into_slice_with_config(element.clone(), &mut buffer, config).unwrap();
|
let len = bincode::encode_into_slice_with_config(&element, &mut buffer, config).unwrap();
|
||||||
println!(
|
println!(
|
||||||
"{:?}: {:?} ({:?})",
|
"{:?}: {:?} ({:?})",
|
||||||
element,
|
element,
|
||||||
|
|
@ -16,68 +17,91 @@ where
|
||||||
);
|
);
|
||||||
let decoded: V = bincode::decode_with_config(&mut buffer, config).unwrap();
|
let decoded: V = bincode::decode_with_config(&mut buffer, config).unwrap();
|
||||||
|
|
||||||
assert_eq!(element, decoded);
|
assert!(
|
||||||
|
cmp(&element, &decoded),
|
||||||
|
"Comparison failed\nDecoded: {:?}\nExpected: {:?}\nBytes: {:?}",
|
||||||
|
decoded,
|
||||||
|
element,
|
||||||
|
&buffer[..len],
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn the_same<V>(element: V)
|
pub fn the_same_with_comparer<V, CMP>(element: V, cmp: CMP)
|
||||||
where
|
where
|
||||||
V: bincode::enc::Encodeable + bincode::de::Decodable + PartialEq + Debug + Clone + 'static,
|
V: bincode::enc::Encodeable + bincode::de::Decodable + Debug + 'static,
|
||||||
|
CMP: Fn(&V, &V) -> bool,
|
||||||
{
|
{
|
||||||
// A matrix of each different config option possible
|
// A matrix of each different config option possible
|
||||||
the_same_with_config(
|
the_same_with_config(
|
||||||
element.clone(),
|
&element,
|
||||||
config::Default
|
config::Default
|
||||||
.with_little_endian()
|
.with_little_endian()
|
||||||
.with_fixed_int_encoding()
|
.with_fixed_int_encoding()
|
||||||
.skip_fixed_array_length(),
|
.skip_fixed_array_length(),
|
||||||
|
&cmp,
|
||||||
);
|
);
|
||||||
the_same_with_config(
|
the_same_with_config(
|
||||||
element.clone(),
|
&element,
|
||||||
config::Default
|
config::Default
|
||||||
.with_big_endian()
|
.with_big_endian()
|
||||||
.with_fixed_int_encoding()
|
.with_fixed_int_encoding()
|
||||||
.skip_fixed_array_length(),
|
.skip_fixed_array_length(),
|
||||||
|
&cmp,
|
||||||
);
|
);
|
||||||
the_same_with_config(
|
the_same_with_config(
|
||||||
element.clone(),
|
&element,
|
||||||
config::Default
|
config::Default
|
||||||
.with_little_endian()
|
.with_little_endian()
|
||||||
.with_variable_int_encoding()
|
.with_variable_int_encoding()
|
||||||
.skip_fixed_array_length(),
|
.skip_fixed_array_length(),
|
||||||
|
&cmp,
|
||||||
);
|
);
|
||||||
the_same_with_config(
|
the_same_with_config(
|
||||||
element.clone(),
|
&element,
|
||||||
config::Default
|
config::Default
|
||||||
.with_big_endian()
|
.with_big_endian()
|
||||||
.with_variable_int_encoding()
|
.with_variable_int_encoding()
|
||||||
.skip_fixed_array_length(),
|
.skip_fixed_array_length(),
|
||||||
|
&cmp,
|
||||||
);
|
);
|
||||||
the_same_with_config(
|
the_same_with_config(
|
||||||
element.clone(),
|
&element,
|
||||||
config::Default
|
config::Default
|
||||||
.with_little_endian()
|
.with_little_endian()
|
||||||
.with_fixed_int_encoding()
|
.with_fixed_int_encoding()
|
||||||
.write_fixed_array_length(),
|
.write_fixed_array_length(),
|
||||||
|
&cmp,
|
||||||
);
|
);
|
||||||
the_same_with_config(
|
the_same_with_config(
|
||||||
element.clone(),
|
&element,
|
||||||
config::Default
|
config::Default
|
||||||
.with_big_endian()
|
.with_big_endian()
|
||||||
.with_fixed_int_encoding()
|
.with_fixed_int_encoding()
|
||||||
.write_fixed_array_length(),
|
.write_fixed_array_length(),
|
||||||
|
&cmp,
|
||||||
);
|
);
|
||||||
the_same_with_config(
|
the_same_with_config(
|
||||||
element.clone(),
|
&element,
|
||||||
config::Default
|
config::Default
|
||||||
.with_little_endian()
|
.with_little_endian()
|
||||||
.with_variable_int_encoding()
|
.with_variable_int_encoding()
|
||||||
.write_fixed_array_length(),
|
.write_fixed_array_length(),
|
||||||
|
&cmp,
|
||||||
);
|
);
|
||||||
the_same_with_config(
|
the_same_with_config(
|
||||||
element,
|
&element,
|
||||||
config::Default
|
config::Default
|
||||||
.with_big_endian()
|
.with_big_endian()
|
||||||
.with_variable_int_encoding()
|
.with_variable_int_encoding()
|
||||||
.write_fixed_array_length(),
|
.write_fixed_array_length(),
|
||||||
|
&cmp,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)] // This is not used in every test
|
||||||
|
pub fn the_same<V>(element: V)
|
||||||
|
where
|
||||||
|
V: bincode::enc::Encodeable + bincode::de::Decodable + PartialEq + Debug + 'static,
|
||||||
|
{
|
||||||
|
the_same_with_comparer(element, |a, b| a == b);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue