Merge pull request #731 from serde-rs/pubtuple

No tuple structs with private fields in public API
This commit is contained in:
Oliver Schneider 2017-01-31 08:56:46 +01:00 committed by GitHub
commit 74cf80989d
3 changed files with 84 additions and 31 deletions

View File

@ -51,7 +51,9 @@ use bytes;
/// This represents all the possible errors that can occur using the `ValueDeserializer`. /// This represents all the possible errors that can occur using the `ValueDeserializer`.
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct Error(ErrorImpl); pub struct Error {
err: ErrorImpl,
}
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "collections"))]
type ErrorImpl = Box<str>; type ErrorImpl = Box<str>;
@ -61,19 +63,23 @@ type ErrorImpl = ();
impl de::Error for Error { impl de::Error for Error {
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "collections"))]
fn custom<T: Display>(msg: T) -> Self { fn custom<T: Display>(msg: T) -> Self {
Error(msg.to_string().into_boxed_str()) Error {
err: msg.to_string().into_boxed_str(),
}
} }
#[cfg(not(any(feature = "std", feature = "collections")))] #[cfg(not(any(feature = "std", feature = "collections")))]
fn custom<T: Display>(_msg: T) -> Self { fn custom<T: Display>(_msg: T) -> Self {
Error(()) Error {
err: (),
}
} }
} }
impl Display for Error { impl Display for Error {
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "collections"))]
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
formatter.write_str(&self.0) formatter.write_str(&self.err)
} }
#[cfg(not(any(feature = "std", feature = "collections")))] #[cfg(not(any(feature = "std", feature = "collections")))]
@ -85,7 +91,7 @@ impl Display for Error {
impl error::Error for Error { impl error::Error for Error {
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "collections"))]
fn description(&self) -> &str { fn description(&self) -> &str {
&self.0 &self.err
} }
#[cfg(not(any(feature = "std", feature = "collections")))] #[cfg(not(any(feature = "std", feature = "collections")))]
@ -113,12 +119,16 @@ impl<E> ValueDeserializer<E> for ()
type Deserializer = UnitDeserializer<E>; type Deserializer = UnitDeserializer<E>;
fn into_deserializer(self) -> UnitDeserializer<E> { fn into_deserializer(self) -> UnitDeserializer<E> {
UnitDeserializer(PhantomData) UnitDeserializer {
marker: PhantomData,
}
} }
} }
/// A helper deserializer that deserializes a `()`. /// A helper deserializer that deserializes a `()`.
pub struct UnitDeserializer<E>(PhantomData<E>); pub struct UnitDeserializer<E> {
marker: PhantomData<E>,
}
impl<E> de::Deserializer for UnitDeserializer<E> impl<E> de::Deserializer for UnitDeserializer<E>
where E: de::Error where E: de::Error
@ -149,7 +159,10 @@ impl<E> de::Deserializer for UnitDeserializer<E>
macro_rules! primitive_deserializer { macro_rules! primitive_deserializer {
($ty:ty, $name:ident, $method:ident $($cast:tt)*) => { ($ty:ty, $name:ident, $method:ident $($cast:tt)*) => {
/// A helper deserializer that deserializes a number. /// A helper deserializer that deserializes a number.
pub struct $name<E>($ty, PhantomData<E>); pub struct $name<E> {
value: $ty,
marker: PhantomData<E>
}
impl<E> ValueDeserializer<E> for $ty impl<E> ValueDeserializer<E> for $ty
where E: de::Error, where E: de::Error,
@ -157,7 +170,10 @@ macro_rules! primitive_deserializer {
type Deserializer = $name<E>; type Deserializer = $name<E>;
fn into_deserializer(self) -> $name<E> { fn into_deserializer(self) -> $name<E> {
$name(self, PhantomData) $name {
value: self,
marker: PhantomData,
}
} }
} }
@ -175,7 +191,7 @@ macro_rules! primitive_deserializer {
fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error> fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where V: de::Visitor, where V: de::Visitor,
{ {
visitor.$method(self.0 $($cast)*) visitor.$method(self.value $($cast)*)
} }
} }
} }
@ -199,7 +215,10 @@ primitive_deserializer!(char, CharDeserializer, visit_char);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// A helper deserializer that deserializes a `&str`. /// A helper deserializer that deserializes a `&str`.
pub struct StrDeserializer<'a, E>(&'a str, PhantomData<E>); pub struct StrDeserializer<'a, E> {
value: &'a str,
marker: PhantomData<E>,
}
impl<'a, E> ValueDeserializer<E> for &'a str impl<'a, E> ValueDeserializer<E> for &'a str
where E: de::Error, where E: de::Error,
@ -207,7 +226,10 @@ impl<'a, E> ValueDeserializer<E> for &'a str
type Deserializer = StrDeserializer<'a, E>; type Deserializer = StrDeserializer<'a, E>;
fn into_deserializer(self) -> StrDeserializer<'a, E> { fn into_deserializer(self) -> StrDeserializer<'a, E> {
StrDeserializer(self, PhantomData) StrDeserializer {
value: self,
marker: PhantomData,
}
} }
} }
@ -219,7 +241,7 @@ impl<'a, E> de::Deserializer for StrDeserializer<'a, E>
fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error> fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where V: de::Visitor, where V: de::Visitor,
{ {
visitor.visit_str(self.0) visitor.visit_str(self.value)
} }
fn deserialize_enum<V>(self, fn deserialize_enum<V>(self,
@ -255,7 +277,10 @@ impl<'a, E> de::EnumVisitor for StrDeserializer<'a, E>
/// A helper deserializer that deserializes a `String`. /// A helper deserializer that deserializes a `String`.
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "collections"))]
pub struct StringDeserializer<E>(String, PhantomData<E>); pub struct StringDeserializer<E> {
value: String,
marker: PhantomData<E>,
}
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "collections"))]
impl<E> ValueDeserializer<E> for String impl<E> ValueDeserializer<E> for String
@ -264,7 +289,10 @@ impl<E> ValueDeserializer<E> for String
type Deserializer = StringDeserializer<E>; type Deserializer = StringDeserializer<E>;
fn into_deserializer(self) -> StringDeserializer<E> { fn into_deserializer(self) -> StringDeserializer<E> {
StringDeserializer(self, PhantomData) StringDeserializer {
value: self,
marker: PhantomData,
}
} }
} }
@ -277,7 +305,7 @@ impl<E> de::Deserializer for StringDeserializer<E>
fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error> fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where V: de::Visitor, where V: de::Visitor,
{ {
visitor.visit_string(self.0) visitor.visit_string(self.value)
} }
fn deserialize_enum<V>(self, fn deserialize_enum<V>(self,
@ -314,7 +342,10 @@ impl<'a, E> de::EnumVisitor for StringDeserializer<E>
/// A helper deserializer that deserializes a `String`. /// A helper deserializer that deserializes a `String`.
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "collections"))]
pub struct CowStrDeserializer<'a, E>(Cow<'a, str>, PhantomData<E>); pub struct CowStrDeserializer<'a, E> {
value: Cow<'a, str>,
marker: PhantomData<E>,
}
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "collections"))]
impl<'a, E> ValueDeserializer<E> for Cow<'a, str> impl<'a, E> ValueDeserializer<E> for Cow<'a, str>
@ -323,7 +354,10 @@ impl<'a, E> ValueDeserializer<E> for Cow<'a, str>
type Deserializer = CowStrDeserializer<'a, E>; type Deserializer = CowStrDeserializer<'a, E>;
fn into_deserializer(self) -> CowStrDeserializer<'a, E> { fn into_deserializer(self) -> CowStrDeserializer<'a, E> {
CowStrDeserializer(self, PhantomData) CowStrDeserializer {
value: self,
marker: PhantomData,
}
} }
} }
@ -336,7 +370,7 @@ impl<'a, E> de::Deserializer for CowStrDeserializer<'a, E>
fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error> fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where V: de::Visitor, where V: de::Visitor,
{ {
match self.0 { match self.value {
Cow::Borrowed(string) => visitor.visit_str(string), Cow::Borrowed(string) => visitor.visit_str(string),
Cow::Owned(string) => visitor.visit_string(string), Cow::Owned(string) => visitor.visit_string(string),
} }
@ -885,12 +919,18 @@ impl<'a, E> ValueDeserializer<E> for bytes::Bytes<'a>
type Deserializer = BytesDeserializer<'a, E>; type Deserializer = BytesDeserializer<'a, E>;
fn into_deserializer(self) -> BytesDeserializer<'a, E> { fn into_deserializer(self) -> BytesDeserializer<'a, E> {
BytesDeserializer(self.into(), PhantomData) BytesDeserializer {
value: self.into(),
marker: PhantomData,
}
} }
} }
/// A helper deserializer that deserializes a `&[u8]`. /// A helper deserializer that deserializes a `&[u8]`.
pub struct BytesDeserializer<'a, E>(&'a [u8], PhantomData<E>); pub struct BytesDeserializer<'a, E> {
value: &'a [u8],
marker: PhantomData<E>,
}
impl<'a, E> de::Deserializer for BytesDeserializer<'a, E> impl<'a, E> de::Deserializer for BytesDeserializer<'a, E>
where E: de::Error where E: de::Error
@ -900,7 +940,7 @@ impl<'a, E> de::Deserializer for BytesDeserializer<'a, E>
fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error> fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where V: de::Visitor, where V: de::Visitor,
{ {
visitor.visit_bytes(self.0) visitor.visit_bytes(self.value)
} }
forward_to_deserialize! { forward_to_deserialize! {
@ -919,13 +959,19 @@ impl<E> ValueDeserializer<E> for bytes::ByteBuf
type Deserializer = ByteBufDeserializer<E>; type Deserializer = ByteBufDeserializer<E>;
fn into_deserializer(self) -> Self::Deserializer { fn into_deserializer(self) -> Self::Deserializer {
ByteBufDeserializer(self.into(), PhantomData) ByteBufDeserializer {
value: self.into(),
marker: PhantomData,
}
} }
} }
/// A helper deserializer that deserializes a `Vec<u8>`. /// A helper deserializer that deserializes a `Vec<u8>`.
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "collections"))]
pub struct ByteBufDeserializer<E>(Vec<u8>, PhantomData<E>); pub struct ByteBufDeserializer<E> {
value: Vec<u8>,
marker: PhantomData<E>,
}
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "collections"))]
impl<E> de::Deserializer for ByteBufDeserializer<E> impl<E> de::Deserializer for ByteBufDeserializer<E>
@ -936,7 +982,7 @@ impl<E> de::Deserializer for ByteBufDeserializer<E>
fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error> fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where V: de::Visitor, where V: de::Visitor,
{ {
visitor.visit_byte_buf(self.0) visitor.visit_byte_buf(self.value)
} }
forward_to_deserialize! { forward_to_deserialize! {
@ -952,10 +998,12 @@ mod private {
use de::{self, Unexpected}; use de::{self, Unexpected};
use core::marker::PhantomData; use core::marker::PhantomData;
pub struct UnitOnly<E>(PhantomData<E>); pub struct UnitOnly<E> {
marker: PhantomData<E>,
}
pub fn unit_only<T, E>(t: T) -> (T, UnitOnly<E>) { pub fn unit_only<T, E>(t: T) -> (T, UnitOnly<E>) {
(t, UnitOnly(PhantomData)) (t, UnitOnly { marker: PhantomData })
} }
impl<E> de::VariantVisitor for UnitOnly<E> impl<E> de::VariantVisitor for UnitOnly<E>

View File

@ -231,7 +231,7 @@ impl<'a, I> Serialize for Iterator<I>
where S: Serializer, where S: Serializer,
{ {
// FIXME: use specialization to prevent invalidating the object in case of clonable iterators? // FIXME: use specialization to prevent invalidating the object in case of clonable iterators?
let iter = match self.0.borrow_mut().take() { let iter = match self.data.borrow_mut().take() {
Some(iter) => iter.into_iter(), Some(iter) => iter.into_iter(),
None => return Err(Error::custom("Iterator used twice")), None => return Err(Error::custom("Iterator used twice")),
}; };

View File

@ -805,9 +805,12 @@ pub trait SerializeStructVariant {
/// of this with the `serde::ser::iterator` function every time you want to /// of this with the `serde::ser::iterator` function every time you want to
/// serialize an iterator. /// serialize an iterator.
#[cfg(feature = "unstable")] #[cfg(feature = "unstable")]
pub struct Iterator<I>(RefCell<Option<I>>) pub struct Iterator<I>
where <I as IntoIterator>::Item: Serialize, where <I as IntoIterator>::Item: Serialize,
I: IntoIterator; I: IntoIterator
{
data: RefCell<Option<I>>,
}
/// Create a wrapper type that can be passed to any function expecting a /// Create a wrapper type that can be passed to any function expecting a
/// `Serialize` and will serialize the given iterator as a sequence. /// `Serialize` and will serialize the given iterator as a sequence.
@ -816,5 +819,7 @@ pub fn iterator<I>(iter: I) -> Iterator<I>
where <I as IntoIterator>::Item: Serialize, where <I as IntoIterator>::Item: Serialize,
I: IntoIterator I: IntoIterator
{ {
Iterator(RefCell::new(Some(iter))) Iterator {
data: RefCell::new(Some(iter)),
}
} }