Auto merge of #57 - Xaeroxe:serde, r=mbrubeck

Add serde support

Things done in this PR:

- Add optional serde dependency
- Add Serialize and Deserialize implementations to SmallVec
- Add test_serde to verify functionality.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/rust-smallvec/57)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo
2017-08-10 18:03:05 -05:00
committed by GitHub
3 changed files with 83 additions and 2 deletions
+2 -2
View File
@@ -5,9 +5,9 @@ rust:
- stable
script: |
cargo build --verbose &&
cargo build --features=heapsizeof --verbose &&
cargo build --all-features --verbose &&
cargo test --verbose &&
cargo test --features=heapsizeof --verbose &&
cargo test --all-features --verbose &&
([ $TRAVIS_RUST_VERSION != nightly ] || cargo test --verbose --no-default-features) &&
([ $TRAVIS_RUST_VERSION != nightly ] || cargo bench --verbose bench)
notifications:
+4
View File
@@ -20,3 +20,7 @@ path = "lib.rs"
[dependencies]
heapsize = { version = "0.4", optional = true }
serde = { version = "1", optional = true }
[dev_dependencies]
bincode = "0.8"
+77
View File
@@ -29,6 +29,9 @@ use alloc::Vec;
#[cfg(feature="heapsizeof")]
extern crate heapsize;
#[cfg(feature = "serde")]
extern crate serde;
#[cfg(not(feature = "std"))]
mod std {
pub use core::*;
@@ -47,6 +50,12 @@ use std::slice;
use std::io;
#[cfg(feature="heapsizeof")]
use std::os::raw::c_void;
#[cfg(feature = "serde")]
use serde::ser::{Serialize, Serializer, SerializeSeq};
#[cfg(feature = "serde")]
use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor};
#[cfg(feature = "serde")]
use std::marker::PhantomData;
#[cfg(feature="heapsizeof")]
use heapsize::{HeapSizeOf, heap_size_of};
@@ -713,6 +722,53 @@ impl<A: Array<Item = u8>> io::Write for SmallVec<A> {
}
}
#[cfg(feature = "serde")]
impl<A: Array> Serialize for SmallVec<A> where A::Item: Serialize {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut state = serializer.serialize_seq(Some(self.len()))?;
for item in self {
state.serialize_element(&item)?;
}
state.end()
}
}
#[cfg(feature = "serde")]
impl<'de, A: Array> Deserialize<'de> for SmallVec<A> where A::Item: Deserialize<'de> {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
deserializer.deserialize_seq(SmallVecVisitor{phantom: PhantomData})
}
}
#[cfg(feature = "serde")]
struct SmallVecVisitor<A> {
phantom: PhantomData<A>
}
#[cfg(feature = "serde")]
impl<'de, A: Array> Visitor<'de> for SmallVecVisitor<A>
where A::Item: Deserialize<'de>,
{
type Value = SmallVec<A>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a sequence")
}
fn visit_seq<B>(self, mut seq: B) -> Result<Self::Value, B::Error>
where
B: SeqAccess<'de>,
{
let mut values = SmallVec::new();
while let Some(value) = seq.next_element()? {
values.push(value);
}
Ok(values)
}
}
impl<'a, A: Array> From<&'a [A::Item]> for SmallVec<A> where A::Item: Clone {
#[inline]
fn from(slice: &'a [A::Item]) -> SmallVec<A> {
@@ -1549,4 +1605,25 @@ pub mod tests {
small_vec.write_all(&data[..]).unwrap();
assert_eq!(small_vec.as_ref(), data.as_ref());
}
extern crate bincode;
#[cfg(feature = "serde")]
#[test]
fn test_serde() {
use self::bincode::{serialize, deserialize, Bounded};
let mut small_vec: SmallVec<[i32; 2]> = SmallVec::new();
small_vec.push(1);
let encoded = serialize(&small_vec, Bounded(100)).unwrap();
let decoded: SmallVec<[i32; 2]> = deserialize(&encoded).unwrap();
assert_eq!(small_vec, decoded);
small_vec.push(2);
// Spill the vec
small_vec.push(3);
small_vec.push(4);
// Check again after spilling.
let encoded = serialize(&small_vec, Bounded(100)).unwrap();
let decoded: SmallVec<[i32; 2]> = deserialize(&encoded).unwrap();
assert_eq!(small_vec, decoded);
}
}