Merge pull request #1251 from serde-rs/weak

Add impls for Weak
This commit is contained in:
David Tolnay 2018-05-07 11:50:35 -07:00 committed by GitHub
commit 6993b983d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 155 additions and 9 deletions

View File

@ -1474,6 +1474,44 @@ where
////////////////////////////////////////////////////////////////////////////////
/// This impl requires the [`"rc"`] Cargo feature of Serde. The resulting
/// `Weak<T>` has a reference count of 0 and cannot be upgraded.
///
/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
impl<'de, T: ?Sized> Deserialize<'de> for RcWeak<T>
where
T: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
try!(Option::<T>::deserialize(deserializer));
Ok(RcWeak::new())
}
}
/// This impl requires the [`"rc"`] Cargo feature of Serde. The resulting
/// `Weak<T>` has a reference count of 0 and cannot be upgraded.
///
/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
impl<'de, T: ?Sized> Deserialize<'de> for ArcWeak<T>
where
T: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
try!(Option::<T>::deserialize(deserializer));
Ok(ArcWeak::new())
}
}
////////////////////////////////////////////////////////////////////////////////
#[cfg(all(feature = "unstable", feature = "rc", any(feature = "std", feature = "alloc")))]
macro_rules! box_forwarded_impl {
(

View File

@ -179,14 +179,14 @@ mod lib {
pub use std::boxed::Box;
#[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
pub use alloc::rc::Rc;
pub use alloc::rc::{Rc, Weak as RcWeak};
#[cfg(all(feature = "rc", feature = "std"))]
pub use std::rc::Rc;
pub use std::rc::{Rc, Weak as RcWeak};
#[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
pub use alloc::arc::Arc;
pub use alloc::arc::{Arc, Weak as ArcWeak};
#[cfg(all(feature = "rc", feature = "std"))]
pub use std::sync::Arc;
pub use std::sync::{Arc, Weak as ArcWeak};
#[cfg(all(feature = "alloc", not(feature = "std")))]
pub use alloc::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};

View File

@ -374,6 +374,40 @@ deref_impl!(<'a, T: ?Sized> Serialize for Cow<'a, T> where T: Serialize + ToOwne
////////////////////////////////////////////////////////////////////////////////
/// This impl requires the [`"rc"`] Cargo feature of Serde.
///
/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
impl<T: ?Sized> Serialize for RcWeak<T>
where
T: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.upgrade().serialize(serializer)
}
}
/// This impl requires the [`"rc"`] Cargo feature of Serde.
///
/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
impl<T: ?Sized> Serialize for ArcWeak<T>
where
T: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.upgrade().serialize(serializer)
}
}
////////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "unstable")]
#[allow(deprecated)]
impl<T> Serialize for NonZero<T>

View File

@ -17,15 +17,15 @@ use std::ffi::{CString, OsString};
use std::net;
use std::num::Wrapping;
use std::path::{Path, PathBuf};
use std::rc::Rc;
use std::sync::Arc;
use std::rc::{Rc, Weak as RcWeak};
use std::sync::{Arc, Weak as ArcWeak};
use std::time::{Duration, UNIX_EPOCH};
#[cfg(feature = "unstable")]
use std::ffi::CStr;
extern crate serde;
use serde::Deserialize;
use serde::{Deserialize, Deserializer};
extern crate fnv;
use self::fnv::FnvHasher;
@ -182,6 +182,27 @@ macro_rules! declare_error_tests {
}
}
#[derive(Debug)]
struct SkipPartialEq<T>(T);
impl<'de, T> Deserialize<'de> for SkipPartialEq<T>
where
T: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
T::deserialize(deserializer).map(SkipPartialEq)
}
}
impl<T> PartialEq for SkipPartialEq<T> {
fn eq(&self, _other: &Self) -> bool {
true
}
}
fn assert_de_tokens_ignore(ignorable_tokens: &[Token]) {
#[derive(PartialEq, Debug, Deserialize)]
struct IgnoreBase {
@ -788,11 +809,33 @@ declare_tests! {
Token::Bool(true),
],
}
test_rc_weak_some {
SkipPartialEq(RcWeak::<bool>::new()) => &[
Token::Some,
Token::Bool(true),
],
}
test_rc_weak_none {
SkipPartialEq(RcWeak::<bool>::new()) => &[
Token::None,
],
}
test_arc {
Arc::new(true) => &[
Token::Bool(true),
],
}
test_arc_weak_some {
SkipPartialEq(ArcWeak::<bool>::new()) => &[
Token::Some,
Token::Bool(true),
],
}
test_arc_weak_none {
SkipPartialEq(ArcWeak::<bool>::new()) => &[
Token::None,
],
}
test_wrapping {
Wrapping(1usize) => &[
Token::U32(1),

View File

@ -11,11 +11,12 @@ extern crate serde_derive;
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::ffi::CString;
use std::mem;
use std::net;
use std::num::Wrapping;
use std::path::{Path, PathBuf};
use std::rc::Rc;
use std::sync::Arc;
use std::rc::{Rc, Weak as RcWeak};
use std::sync::{Arc, Weak as ArcWeak};
use std::time::{Duration, UNIX_EPOCH};
#[cfg(unix)]
@ -398,11 +399,41 @@ declare_tests! {
Token::Bool(true),
],
}
test_rc_weak_some {
{
let rc = Rc::new(true);
mem::forget(rc.clone());
Rc::downgrade(&rc)
} => &[
Token::Some,
Token::Bool(true),
],
}
test_rc_weak_none {
RcWeak::<bool>::new() => &[
Token::None,
],
}
test_arc {
Arc::new(true) => &[
Token::Bool(true),
],
}
test_arc_weak_some {
{
let arc = Arc::new(true);
mem::forget(arc.clone());
Arc::downgrade(&arc)
} => &[
Token::Some,
Token::Bool(true),
],
}
test_arc_weak_none {
ArcWeak::<bool>::new() => &[
Token::None,
],
}
test_wrapping {
Wrapping(1usize) => &[
Token::U64(1),