Serde support

This commit is contained in:
Artem Vorotnikov
2019-01-20 14:01:37 +03:00
parent fa16a1decb
commit d551759884
5 changed files with 427 additions and 5 deletions

View File

@@ -28,3 +28,8 @@ scoped_threadpool = "0.1.8"
[dependencies]
generic-array = "0.11.0"
hash32 = "0.1.0"
[dependencies.serde]
version = "1"
optional = true
default-features = false

View File

@@ -3,7 +3,7 @@ set -euxo pipefail
main() {
cargo check --target $TARGET
if [ $TRAVIS_RUST_VERSION = nightly ]; then
cargo check --target $TARGET --features 'const-fn smaller-atomics'
cargo check --target $TARGET --features 'serde const-fn smaller-atomics'
fi
if [ $TARGET = x86_64-unknown-linux-gnu ]; then
@@ -11,17 +11,17 @@ main() {
cargo test --target $TARGET --release
if [ $TRAVIS_RUST_VERSION = nightly ]; then
cargo test --target $TARGET --features 'const-fn smaller-atomics'
cargo test --target $TARGET --release --features 'const-fn smaller-atomics'
cargo test --target $TARGET --features 'serde const-fn smaller-atomics'
cargo test --target $TARGET --release --features 'serde const-fn smaller-atomics'
export RUSTFLAGS="-Z sanitizer=thread"
export RUST_TEST_THREADS=1
export TSAN_OPTIONS="suppressions=$(pwd)/blacklist.txt"
cargo test --test tsan --target $TARGET
cargo test --test tsan --target $TARGET --features 'const-fn smaller-atomics'
cargo test --test tsan --target $TARGET --features 'serde const-fn smaller-atomics'
cargo test --test tsan --target $TARGET --release
cargo test --test tsan --target $TARGET --release --features 'const-fn smaller-atomics'
cargo test --test tsan --target $TARGET --release --features 'serde const-fn smaller-atomics'
fi
fi
}

288
src/de.rs Normal file
View File

@@ -0,0 +1,288 @@
use core::fmt;
use core::marker::PhantomData;
use generic_array::{typenum::PowerOfTwo, ArrayLength};
use hash32::{BuildHasherDefault, Hash, Hasher};
use serde::de::{self, Deserialize, Deserializer, Error, MapAccess, SeqAccess};
use super::binary_heap::Kind as BinaryHeapKind;
use super::indexmap::{Bucket, Pos};
use BinaryHeap;
use IndexMap;
use IndexSet;
use LinearMap;
use String;
use Vec;
// Sequential containers
impl<'de, T, N, KIND> Deserialize<'de> for BinaryHeap<T, N, KIND>
where
T: Ord + Deserialize<'de>,
N: ArrayLength<T>,
KIND: BinaryHeapKind,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct ValueVisitor<'de, T, N, KIND>(PhantomData<(&'de (), T, N, KIND)>);
impl<'de, T, N, KIND> de::Visitor<'de> for ValueVisitor<'de, T, N, KIND>
where
T: Ord + Deserialize<'de>,
N: ArrayLength<T>,
KIND: BinaryHeapKind,
{
type Value = BinaryHeap<T, N, KIND>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a sequence")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut values = BinaryHeap::new();
while let Some(value) = seq.next_element()? {
if values.push(value).is_err() {
return Err(A::Error::invalid_length(values.capacity() + 1, &self))?;
}
}
Ok(values)
}
}
deserializer.deserialize_seq(ValueVisitor(PhantomData))
}
}
impl<'de, T, N, S> Deserialize<'de> for IndexSet<T, N, BuildHasherDefault<S>>
where
T: Eq + Hash + Deserialize<'de>,
S: Hasher + Default,
N: ArrayLength<Bucket<T, ()>> + ArrayLength<Option<Pos>> + PowerOfTwo,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct ValueVisitor<'de, T, N, S>(PhantomData<(&'de (), T, N, S)>);
impl<'de, T, N, S> de::Visitor<'de> for ValueVisitor<'de, T, N, S>
where
T: Eq + Hash + Deserialize<'de>,
S: Hasher + Default,
N: ArrayLength<Bucket<T, ()>> + ArrayLength<Option<Pos>> + PowerOfTwo,
{
type Value = IndexSet<T, N, BuildHasherDefault<S>>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a sequence")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut values = IndexSet::new();
while let Some(value) = seq.next_element()? {
if values.insert(value).is_err() {
return Err(A::Error::invalid_length(values.capacity() + 1, &self))?;
}
}
Ok(values)
}
}
deserializer.deserialize_seq(ValueVisitor(PhantomData))
}
}
impl<'de, T, N> Deserialize<'de> for Vec<T, N>
where
N: ArrayLength<T>,
T: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct ValueVisitor<'de, T, N>(PhantomData<(&'de (), T, N)>);
impl<'de, T, N> de::Visitor<'de> for ValueVisitor<'de, T, N>
where
N: ArrayLength<T>,
T: Deserialize<'de>,
{
type Value = Vec<T, N>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a sequence")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut values = Vec::new();
while let Some(value) = seq.next_element()? {
if values.push(value).is_err() {
return Err(A::Error::invalid_length(values.capacity() + 1, &self))?;
}
}
Ok(values)
}
}
deserializer.deserialize_seq(ValueVisitor(PhantomData))
}
}
// Dictionaries
impl<'de, K, V, N, S> Deserialize<'de> for IndexMap<K, V, N, BuildHasherDefault<S>>
where
K: Eq + Hash + Deserialize<'de>,
V: Deserialize<'de>,
N: ArrayLength<Bucket<K, V>> + ArrayLength<Option<Pos>> + PowerOfTwo,
S: Default + Hasher,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct ValueVisitor<'de, K, V, N, S>(PhantomData<(&'de (), K, V, N, S)>);
impl<'de, K, V, N, S> de::Visitor<'de> for ValueVisitor<'de, K, V, N, S>
where
K: Eq + Hash + Deserialize<'de>,
V: Deserialize<'de>,
N: ArrayLength<Bucket<K, V>> + ArrayLength<Option<Pos>> + PowerOfTwo,
S: Default + Hasher,
{
type Value = IndexMap<K, V, N, BuildHasherDefault<S>>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a map")
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
let mut values = IndexMap::new();
while let Some((key, value)) = map.next_entry()? {
if values.insert(key, value).is_err() {
return Err(A::Error::invalid_length(values.capacity() + 1, &self))?;
}
}
Ok(values)
}
}
deserializer.deserialize_seq(ValueVisitor(PhantomData))
}
}
impl<'de, K, V, N> Deserialize<'de> for LinearMap<K, V, N>
where
K: Eq + Deserialize<'de>,
V: Deserialize<'de>,
N: ArrayLength<(K, V)>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct ValueVisitor<'de, K, V, N>(PhantomData<(&'de (), K, V, N)>);
impl<'de, K, V, N> de::Visitor<'de> for ValueVisitor<'de, K, V, N>
where
K: Eq + Deserialize<'de>,
V: Deserialize<'de>,
N: ArrayLength<(K, V)>,
{
type Value = LinearMap<K, V, N>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a map")
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
let mut values = LinearMap::new();
while let Some((key, value)) = map.next_entry()? {
if values.insert(key, value).is_err() {
return Err(A::Error::invalid_length(values.capacity() + 1, &self))?;
}
}
Ok(values)
}
}
deserializer.deserialize_seq(ValueVisitor(PhantomData))
}
}
// String containers
impl<'de, N> Deserialize<'de> for String<N>
where
N: ArrayLength<u8>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct ValueVisitor<'de, N>(PhantomData<(&'de (), N)>);
impl<'de, N> de::Visitor<'de> for ValueVisitor<'de, N>
where
N: ArrayLength<u8>,
{
type Value = String<N>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(
formatter,
"a string no more than {} bytes long",
N::to_u64()
)
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
let mut s = String::new();
s.push_str(v)
.map_err(|_| E::invalid_length(v.len(), &self))?;
Ok(s)
}
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
where
E: de::Error,
{
let mut bytes = Vec::new();
if bytes.extend_from_slice(v).is_err() {
return Err(E::invalid_value(de::Unexpected::Bytes(v), &self));
}
String::from_utf8(bytes)
.map_err(|_| E::invalid_value(de::Unexpected::Bytes(v), &self))
}
}
deserializer.deserialize_str(ValueVisitor::<'de, N>(PhantomData))
}
}

View File

@@ -89,6 +89,9 @@ extern crate hash32;
#[cfg(test)]
extern crate std;
#[cfg(feature = "serde")]
extern crate serde;
#[macro_use]
mod const_fn;
@@ -108,6 +111,11 @@ mod linear_map;
mod string;
mod vec;
#[cfg(feature = "serde")]
mod de;
#[cfg(feature = "serde")]
mod ser;
pub mod binary_heap;
pub mod spsc;

121
src/ser.rs Normal file
View File

@@ -0,0 +1,121 @@
use hash32::{BuildHasher, Hash};
use generic_array::{typenum::PowerOfTwo, ArrayLength};
use serde::ser::{Serialize, SerializeMap, SerializeSeq, Serializer};
use super::binary_heap::Kind as BinaryHeapKind;
use super::indexmap::{Bucket, Pos};
use BinaryHeap;
use IndexMap;
use IndexSet;
use LinearMap;
use String;
use Vec;
// Sequential containers
impl<T, N, KIND> Serialize for BinaryHeap<T, N, KIND>
where
T: Ord + Serialize,
N: ArrayLength<T>,
KIND: BinaryHeapKind,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut seq = serializer.serialize_seq(Some(self.len()))?;
for element in self {
seq.serialize_element(element)?;
}
seq.end()
}
}
impl<T, N, S> Serialize for IndexSet<T, N, S>
where
T: Eq + Hash + Serialize,
S: BuildHasher,
N: ArrayLength<Bucket<T, ()>> + ArrayLength<Option<Pos>> + PowerOfTwo,
{
fn serialize<SER>(&self, serializer: SER) -> Result<SER::Ok, SER::Error>
where
SER: Serializer,
{
let mut seq = serializer.serialize_seq(Some(self.len()))?;
for element in self {
seq.serialize_element(element)?;
}
seq.end()
}
}
impl<T, N> Serialize for Vec<T, N>
where
T: Serialize,
N: ArrayLength<T>,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut seq = serializer.serialize_seq(Some(self.len()))?;
for element in self {
seq.serialize_element(element)?;
}
seq.end()
}
}
// Dictionaries
impl<K, V, N, S> Serialize for IndexMap<K, V, N, S>
where
K: Eq + Hash + Serialize,
N: ArrayLength<Bucket<K, V>> + ArrayLength<Option<Pos>>,
S: BuildHasher,
V: Serialize,
{
fn serialize<SER>(&self, serializer: SER) -> Result<SER::Ok, SER::Error>
where
SER: Serializer,
{
let mut map = serializer.serialize_map(Some(self.len()))?;
for (k, v) in self {
map.serialize_entry(k, v)?;
}
map.end()
}
}
impl<K, V, N> Serialize for LinearMap<K, V, N>
where
N: ArrayLength<(K, V)>,
K: Eq + Serialize,
V: Serialize,
{
fn serialize<SER>(&self, serializer: SER) -> Result<SER::Ok, SER::Error>
where
SER: Serializer,
{
let mut map = serializer.serialize_map(Some(self.len()))?;
for (k, v) in self {
map.serialize_entry(k, v)?;
}
map.end()
}
}
// String containers
impl<N> Serialize for String<N>
where
N: ArrayLength<u8>,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&*self)
}
}