diff --git a/Cargo.toml b/Cargo.toml index fac1916..c3b76aa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,3 +9,7 @@ readme = "README.md" keywords = ["slice", "tagged", "pointer"] [dependencies] +serde = { version = "1.0.130", optional = true } + +[dev-dependencies] +bincode = "1.3.3" \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index c0cd111..dd6b02c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -39,6 +39,13 @@ use std::ptr::NonNull; #[cfg(target_arch = "x86_64")] use std::slice; +#[cfg(feature = "serde")] +extern crate serde; +#[cfg(feature = "serde")] +use serde::ser::{Serialize, SerializeSeq, Serializer}; +#[cfg(feature = "serde")] +use serde::de::{Deserialize, Deserializer}; + /// An owned slice that tries to use only one word of storage. /// /// See the [module-level documentation](index.html) for more. @@ -498,6 +505,38 @@ impl fmt::Pointer for ThinBoxedSlice { } } +#[cfg(feature = "serde")] +impl Serialize for ThinBoxedSlice +where + V: Serialize +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let data: &[V] = &*self; + let mut seq = serializer.serialize_seq(Some(data.len()))?; + for element in data { + seq.serialize_element(element)?; + } + seq.end() + } +} + +#[cfg(feature = "serde")] +impl<'de, V> Deserialize<'de> for ThinBoxedSlice +where + V: Deserialize<'de> +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let data: Box<[V]> = Deserialize::deserialize(deserializer)?; + Ok(data.into()) + } +} + #[cfg(target_arch = "x86_64")] #[test] fn test_spilled_storage() { @@ -542,3 +581,12 @@ fn test_leak_large() { static_ref[123] *= 1000; assert_eq!(static_ref[123], 456000); } + +#[cfg(feature = "serde")] +#[test] +fn test_serde() { + let x = ThinBoxedSlice::from(vec![4,2,3].into_boxed_slice()); + let serialized_x = bincode::serialize(&x).expect("Serialization failed"); + let deserialized_x = bincode::deserialize(serialized_x.as_slice()).expect("Deserialization failed"); + assert_eq!(x, deserialized_x); +}