mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-07-21 03:55:45 +00:00
Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bd588db067 | |||
| 8f09aeacdd | |||
| 0b5c56b0db | |||
| 85de92e6f7 | |||
| c858a1fa77 | |||
| d02eb22557 | |||
| 034fe25d5b | |||
| 0a230e8598 | |||
| b20214d4a0 | |||
| 34f4b68f77 | |||
| 60e08f9545 | |||
| ba46f45dc5 | |||
| 44b9567e21 | |||
| b276849ce1 | |||
| 398fba9b1e | |||
| cd6697b0e4 | |||
| c162d51866 | |||
| 78a9dbc57e | |||
| 391d3ababf | |||
| 99d9151ce9 | |||
| 7a7a182ab6 | |||
| 9e1f573f88 | |||
| 094f63b86a | |||
| 42fa79455e |
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.119" # remember to update html_root_url and serde_derive dependency
|
version = "1.0.121" # remember to update html_root_url and serde_derive dependency
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
description = "A generic serialization/deserialization framework"
|
description = "A generic serialization/deserialization framework"
|
||||||
@@ -14,7 +14,7 @@ include = ["build.rs", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APAC
|
|||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde_derive = { version = "=1.0.119", optional = true, path = "../serde_derive" }
|
serde_derive = { version = "=1.0.121", optional = true, path = "../serde_derive" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serde_derive = { version = "1.0", path = "../serde_derive" }
|
serde_derive = { version = "1.0", path = "../serde_derive" }
|
||||||
|
|||||||
@@ -130,12 +130,28 @@ impl<'de> Visitor<'de> for IgnoredAny {
|
|||||||
Ok(IgnoredAny)
|
Ok(IgnoredAny)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
serde_if_integer128! {
|
||||||
|
#[inline]
|
||||||
|
fn visit_i128<E>(self, x: i128) -> Result<Self::Value, E> {
|
||||||
|
let _ = x;
|
||||||
|
Ok(IgnoredAny)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_u64<E>(self, x: u64) -> Result<Self::Value, E> {
|
fn visit_u64<E>(self, x: u64) -> Result<Self::Value, E> {
|
||||||
let _ = x;
|
let _ = x;
|
||||||
Ok(IgnoredAny)
|
Ok(IgnoredAny)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
serde_if_integer128! {
|
||||||
|
#[inline]
|
||||||
|
fn visit_u128<E>(self, x: u128) -> Result<Self::Value, E> {
|
||||||
|
let _ = x;
|
||||||
|
Ok(IgnoredAny)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_f64<E>(self, x: f64) -> Result<Self::Value, E> {
|
fn visit_f64<E>(self, x: f64) -> Result<Self::Value, E> {
|
||||||
let _ = x;
|
let _ = x;
|
||||||
|
|||||||
+53
-72
@@ -1260,24 +1260,7 @@ macro_rules! parse_ip_impl {
|
|||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
if deserializer.is_human_readable() {
|
if deserializer.is_human_readable() {
|
||||||
struct IpAddrVisitor;
|
deserializer.deserialize_str(FromStrVisitor::new($expecting))
|
||||||
|
|
||||||
impl<'de> Visitor<'de> for IpAddrVisitor {
|
|
||||||
type Value = $ty;
|
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
formatter.write_str($expecting)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
|
|
||||||
where
|
|
||||||
E: Error,
|
|
||||||
{
|
|
||||||
s.parse().map_err(Error::custom)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
deserializer.deserialize_str(IpAddrVisitor)
|
|
||||||
} else {
|
} else {
|
||||||
<[u8; $size]>::deserialize(deserializer).map(<$ty>::from)
|
<[u8; $size]>::deserialize(deserializer).map(<$ty>::from)
|
||||||
}
|
}
|
||||||
@@ -1405,24 +1388,7 @@ impl<'de> Deserialize<'de> for net::IpAddr {
|
|||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
if deserializer.is_human_readable() {
|
if deserializer.is_human_readable() {
|
||||||
struct IpAddrVisitor;
|
deserializer.deserialize_str(FromStrVisitor::new("IP address"))
|
||||||
|
|
||||||
impl<'de> Visitor<'de> for IpAddrVisitor {
|
|
||||||
type Value = net::IpAddr;
|
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
formatter.write_str("IP address")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
|
|
||||||
where
|
|
||||||
E: Error,
|
|
||||||
{
|
|
||||||
s.parse().map_err(Error::custom)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
deserializer.deserialize_str(IpAddrVisitor)
|
|
||||||
} else {
|
} else {
|
||||||
use lib::net::IpAddr;
|
use lib::net::IpAddr;
|
||||||
deserialize_enum! {
|
deserialize_enum! {
|
||||||
@@ -1449,24 +1415,7 @@ macro_rules! parse_socket_impl {
|
|||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
if deserializer.is_human_readable() {
|
if deserializer.is_human_readable() {
|
||||||
struct SocketAddrVisitor;
|
deserializer.deserialize_str(FromStrVisitor::new($expecting))
|
||||||
|
|
||||||
impl<'de> Visitor<'de> for SocketAddrVisitor {
|
|
||||||
type Value = $ty;
|
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
formatter.write_str($expecting)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
|
|
||||||
where
|
|
||||||
E: Error,
|
|
||||||
{
|
|
||||||
s.parse().map_err(Error::custom)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
deserializer.deserialize_str(SocketAddrVisitor)
|
|
||||||
} else {
|
} else {
|
||||||
<(_, u16)>::deserialize(deserializer).map(|(ip, port)| $new(ip, port))
|
<(_, u16)>::deserialize(deserializer).map(|(ip, port)| $new(ip, port))
|
||||||
}
|
}
|
||||||
@@ -1482,24 +1431,7 @@ impl<'de> Deserialize<'de> for net::SocketAddr {
|
|||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
if deserializer.is_human_readable() {
|
if deserializer.is_human_readable() {
|
||||||
struct SocketAddrVisitor;
|
deserializer.deserialize_str(FromStrVisitor::new("socket address"))
|
||||||
|
|
||||||
impl<'de> Visitor<'de> for SocketAddrVisitor {
|
|
||||||
type Value = net::SocketAddr;
|
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
formatter.write_str("socket address")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
|
|
||||||
where
|
|
||||||
E: Error,
|
|
||||||
{
|
|
||||||
s.parse().map_err(Error::custom)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
deserializer.deserialize_str(SocketAddrVisitor)
|
|
||||||
} else {
|
} else {
|
||||||
use lib::net::SocketAddr;
|
use lib::net::SocketAddr;
|
||||||
deserialize_enum! {
|
deserialize_enum! {
|
||||||
@@ -1917,6 +1849,17 @@ impl<'de> Deserialize<'de> for Duration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_overflow<E>(secs: u64, nanos: u32) -> Result<(), E>
|
||||||
|
where
|
||||||
|
E: Error,
|
||||||
|
{
|
||||||
|
static NANOS_PER_SEC: u32 = 1_000_000_000;
|
||||||
|
match secs.checked_add((nanos / NANOS_PER_SEC) as u64) {
|
||||||
|
Some(_) => Ok(()),
|
||||||
|
None => Err(E::custom("overflow deserializing Duration")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct DurationVisitor;
|
struct DurationVisitor;
|
||||||
|
|
||||||
impl<'de> Visitor<'de> for DurationVisitor {
|
impl<'de> Visitor<'de> for DurationVisitor {
|
||||||
@@ -1942,6 +1885,7 @@ impl<'de> Deserialize<'de> for Duration {
|
|||||||
return Err(Error::invalid_length(1, &self));
|
return Err(Error::invalid_length(1, &self));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
try!(check_overflow(secs, nanos));
|
||||||
Ok(Duration::new(secs, nanos))
|
Ok(Duration::new(secs, nanos))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1975,6 +1919,7 @@ impl<'de> Deserialize<'de> for Duration {
|
|||||||
Some(nanos) => nanos,
|
Some(nanos) => nanos,
|
||||||
None => return Err(<A::Error as Error>::missing_field("nanos")),
|
None => return Err(<A::Error as Error>::missing_field("nanos")),
|
||||||
};
|
};
|
||||||
|
try!(check_overflow(secs, nanos));
|
||||||
Ok(Duration::new(secs, nanos))
|
Ok(Duration::new(secs, nanos))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2603,3 +2548,39 @@ atomic_impl! {
|
|||||||
atomic_impl! {
|
atomic_impl! {
|
||||||
AtomicI64 AtomicU64
|
AtomicI64 AtomicU64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
struct FromStrVisitor<T> {
|
||||||
|
expecting: &'static str,
|
||||||
|
ty: PhantomData<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
impl<T> FromStrVisitor<T> {
|
||||||
|
fn new(expecting: &'static str) -> Self {
|
||||||
|
FromStrVisitor {
|
||||||
|
expecting: expecting,
|
||||||
|
ty: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
impl<'de, T> Visitor<'de> for FromStrVisitor<T>
|
||||||
|
where
|
||||||
|
T: str::FromStr,
|
||||||
|
T::Err: fmt::Display,
|
||||||
|
{
|
||||||
|
type Value = T;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
formatter.write_str(self.expecting)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
|
||||||
|
where
|
||||||
|
E: Error,
|
||||||
|
{
|
||||||
|
s.parse().map_err(Error::custom)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+53
-14
@@ -25,7 +25,7 @@ use lib::*;
|
|||||||
|
|
||||||
use self::private::{First, Second};
|
use self::private::{First, Second};
|
||||||
use __private::de::size_hint;
|
use __private::de::size_hint;
|
||||||
use de::{self, Expected, IntoDeserializer, SeqAccess};
|
use de::{self, Deserializer, Expected, IntoDeserializer, SeqAccess, Visitor};
|
||||||
use ser;
|
use ser;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -665,27 +665,26 @@ where
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/// A deserializer holding a `&[u8]` with a lifetime tied to another
|
/// A deserializer holding a `&[u8]`. Always calls [`Visitor::visit_bytes`].
|
||||||
/// deserializer.
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct BorrowedBytesDeserializer<'de, E> {
|
pub struct BytesDeserializer<'a, E> {
|
||||||
value: &'de [u8],
|
value: &'a [u8],
|
||||||
marker: PhantomData<E>,
|
marker: PhantomData<E>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_copy_clone!(BorrowedBytesDeserializer<'de>);
|
impl<'a, E> BytesDeserializer<'a, E> {
|
||||||
|
/// Create a new deserializer from the given bytes.
|
||||||
impl<'de, E> BorrowedBytesDeserializer<'de, E> {
|
pub fn new(value: &'a [u8]) -> Self {
|
||||||
/// Create a new borrowed deserializer from the given byte slice.
|
BytesDeserializer {
|
||||||
pub fn new(value: &'de [u8]) -> BorrowedBytesDeserializer<'de, E> {
|
|
||||||
BorrowedBytesDeserializer {
|
|
||||||
value: value,
|
value: value,
|
||||||
marker: PhantomData,
|
marker: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de, E> de::Deserializer<'de> for BorrowedBytesDeserializer<'de, E>
|
impl_copy_clone!(BytesDeserializer<'a>);
|
||||||
|
|
||||||
|
impl<'de, 'a, E> Deserializer<'de> for BytesDeserializer<'a, E>
|
||||||
where
|
where
|
||||||
E: de::Error,
|
E: de::Error,
|
||||||
{
|
{
|
||||||
@@ -693,7 +692,47 @@ where
|
|||||||
|
|
||||||
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
where
|
where
|
||||||
V: de::Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
|
{
|
||||||
|
visitor.visit_bytes(self.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_to_deserialize_any! {
|
||||||
|
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
|
||||||
|
bytes byte_buf option unit unit_struct newtype_struct seq tuple
|
||||||
|
tuple_struct map struct enum identifier ignored_any
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A deserializer holding a `&[u8]` with a lifetime tied to another
|
||||||
|
/// deserializer. Always calls [`Visitor::visit_borrowed_bytes`].
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct BorrowedBytesDeserializer<'de, E> {
|
||||||
|
value: &'de [u8],
|
||||||
|
marker: PhantomData<E>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de, E> BorrowedBytesDeserializer<'de, E> {
|
||||||
|
/// Create a new borrowed deserializer from the given borrowed bytes.
|
||||||
|
pub fn new(value: &'de [u8]) -> Self {
|
||||||
|
BorrowedBytesDeserializer {
|
||||||
|
value: value,
|
||||||
|
marker: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_copy_clone!(BorrowedBytesDeserializer<'de>);
|
||||||
|
|
||||||
|
impl<'de, E> Deserializer<'de> for BorrowedBytesDeserializer<'de, E>
|
||||||
|
where
|
||||||
|
E: de::Error,
|
||||||
|
{
|
||||||
|
type Error = E;
|
||||||
|
|
||||||
|
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
|
where
|
||||||
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
visitor.visit_borrowed_bytes(self.value)
|
visitor.visit_borrowed_bytes(self.value)
|
||||||
}
|
}
|
||||||
@@ -701,7 +740,7 @@ where
|
|||||||
forward_to_deserialize_any! {
|
forward_to_deserialize_any! {
|
||||||
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
|
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
|
||||||
bytes byte_buf option unit unit_struct newtype_struct seq tuple
|
bytes byte_buf option unit unit_struct newtype_struct seq tuple
|
||||||
tuple_struct map struct identifier ignored_any enum
|
tuple_struct map struct enum identifier ignored_any
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -84,7 +84,7 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Serde types in rustdoc of other crates get linked to here.
|
// Serde types in rustdoc of other crates get linked to here.
|
||||||
#![doc(html_root_url = "https://docs.rs/serde/1.0.119")]
|
#![doc(html_root_url = "https://docs.rs/serde/1.0.121")]
|
||||||
// Support using Serde without the standard library!
|
// Support using Serde without the standard library!
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
// Unstable functionality only if the user asks for it. For tracking and
|
// Unstable functionality only if the user asks for it. For tracking and
|
||||||
|
|||||||
+50
-32
@@ -1,5 +1,6 @@
|
|||||||
use lib::*;
|
use lib::*;
|
||||||
|
|
||||||
|
use de::value::{BorrowedBytesDeserializer, BytesDeserializer};
|
||||||
use de::{Deserialize, DeserializeSeed, Deserializer, Error, IntoDeserializer, Visitor};
|
use de::{Deserialize, DeserializeSeed, Deserializer, Error, IntoDeserializer, Visitor};
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
@@ -2538,8 +2539,10 @@ mod content {
|
|||||||
// }
|
// }
|
||||||
pub trait IdentifierDeserializer<'de, E: Error> {
|
pub trait IdentifierDeserializer<'de, E: Error> {
|
||||||
type Deserializer: Deserializer<'de, Error = E>;
|
type Deserializer: Deserializer<'de, Error = E>;
|
||||||
|
type BorrowedDeserializer: Deserializer<'de, Error = E>;
|
||||||
|
|
||||||
fn from(self) -> Self::Deserializer;
|
fn from(self) -> Self::Deserializer;
|
||||||
|
fn borrowed(self) -> Self::BorrowedDeserializer;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de, E> IdentifierDeserializer<'de, E> for u32
|
impl<'de, E> IdentifierDeserializer<'de, E> for u32
|
||||||
@@ -2547,10 +2550,15 @@ where
|
|||||||
E: Error,
|
E: Error,
|
||||||
{
|
{
|
||||||
type Deserializer = <u32 as IntoDeserializer<'de, E>>::Deserializer;
|
type Deserializer = <u32 as IntoDeserializer<'de, E>>::Deserializer;
|
||||||
|
type BorrowedDeserializer = <u32 as IntoDeserializer<'de, E>>::Deserializer;
|
||||||
|
|
||||||
fn from(self) -> Self::Deserializer {
|
fn from(self) -> Self::Deserializer {
|
||||||
self.into_deserializer()
|
self.into_deserializer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn borrowed(self) -> Self::BorrowedDeserializer {
|
||||||
|
self.into_deserializer()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct StrDeserializer<'a, E> {
|
pub struct StrDeserializer<'a, E> {
|
||||||
@@ -2558,20 +2566,6 @@ pub struct StrDeserializer<'a, E> {
|
|||||||
marker: PhantomData<E>,
|
marker: PhantomData<E>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, E> IdentifierDeserializer<'a, E> for &'a str
|
|
||||||
where
|
|
||||||
E: Error,
|
|
||||||
{
|
|
||||||
type Deserializer = StrDeserializer<'a, E>;
|
|
||||||
|
|
||||||
fn from(self) -> Self::Deserializer {
|
|
||||||
StrDeserializer {
|
|
||||||
value: self,
|
|
||||||
marker: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'de, 'a, E> Deserializer<'de> for StrDeserializer<'a, E>
|
impl<'de, 'a, E> Deserializer<'de> for StrDeserializer<'a, E>
|
||||||
where
|
where
|
||||||
E: Error,
|
E: Error,
|
||||||
@@ -2592,26 +2586,12 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct BytesDeserializer<'a, E> {
|
pub struct BorrowedStrDeserializer<'de, E> {
|
||||||
value: &'a [u8],
|
value: &'de str,
|
||||||
marker: PhantomData<E>,
|
marker: PhantomData<E>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, E> IdentifierDeserializer<'a, E> for &'a [u8]
|
impl<'de, E> Deserializer<'de> for BorrowedStrDeserializer<'de, E>
|
||||||
where
|
|
||||||
E: Error,
|
|
||||||
{
|
|
||||||
type Deserializer = BytesDeserializer<'a, E>;
|
|
||||||
|
|
||||||
fn from(self) -> Self::Deserializer {
|
|
||||||
BytesDeserializer {
|
|
||||||
value: self,
|
|
||||||
marker: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'de, 'a, E> Deserializer<'de> for BytesDeserializer<'a, E>
|
|
||||||
where
|
where
|
||||||
E: Error,
|
E: Error,
|
||||||
{
|
{
|
||||||
@@ -2621,7 +2601,7 @@ where
|
|||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
visitor.visit_bytes(self.value)
|
visitor.visit_borrowed_str(self.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
forward_to_deserialize_any! {
|
forward_to_deserialize_any! {
|
||||||
@@ -2631,6 +2611,44 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, E> IdentifierDeserializer<'a, E> for &'a str
|
||||||
|
where
|
||||||
|
E: Error,
|
||||||
|
{
|
||||||
|
type Deserializer = StrDeserializer<'a, E>;
|
||||||
|
type BorrowedDeserializer = BorrowedStrDeserializer<'a, E>;
|
||||||
|
|
||||||
|
fn from(self) -> Self::Deserializer {
|
||||||
|
StrDeserializer {
|
||||||
|
value: self,
|
||||||
|
marker: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn borrowed(self) -> Self::BorrowedDeserializer {
|
||||||
|
BorrowedStrDeserializer {
|
||||||
|
value: self,
|
||||||
|
marker: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, E> IdentifierDeserializer<'a, E> for &'a [u8]
|
||||||
|
where
|
||||||
|
E: Error,
|
||||||
|
{
|
||||||
|
type Deserializer = BytesDeserializer<'a, E>;
|
||||||
|
type BorrowedDeserializer = BorrowedBytesDeserializer<'a, E>;
|
||||||
|
|
||||||
|
fn from(self) -> Self::Deserializer {
|
||||||
|
BytesDeserializer::new(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn borrowed(self) -> Self::BorrowedDeserializer {
|
||||||
|
BorrowedBytesDeserializer::new(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A DeserializeSeed helper for implementing deserialize_in_place Visitors.
|
/// A DeserializeSeed helper for implementing deserialize_in_place Visitors.
|
||||||
///
|
///
|
||||||
/// Wraps a mutable reference and calls deserialize_in_place on it.
|
/// Wraps a mutable reference and calls deserialize_in_place on it.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.119" # remember to update html_root_url
|
version = "1.0.121" # remember to update html_root_url
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
|
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
|
||||||
|
|||||||
+66
-54
@@ -1891,17 +1891,23 @@ fn deserialize_generated_identifier(
|
|||||||
let (ignore_variant, fallthrough) = if !is_variant && cattrs.has_flatten() {
|
let (ignore_variant, fallthrough) = if !is_variant && cattrs.has_flatten() {
|
||||||
let ignore_variant = quote!(__other(_serde::__private::de::Content<'de>),);
|
let ignore_variant = quote!(__other(_serde::__private::de::Content<'de>),);
|
||||||
let fallthrough = quote!(_serde::__private::Ok(__Field::__other(__value)));
|
let fallthrough = quote!(_serde::__private::Ok(__Field::__other(__value)));
|
||||||
(Some(ignore_variant), Some(fallthrough))
|
(
|
||||||
|
Some(ignore_variant),
|
||||||
|
Some((fallthrough.clone(), fallthrough)),
|
||||||
|
)
|
||||||
} else if let Some(other_idx) = other_idx {
|
} else if let Some(other_idx) = other_idx {
|
||||||
let ignore_variant = fields[other_idx].1.clone();
|
let ignore_variant = fields[other_idx].1.clone();
|
||||||
let fallthrough = quote!(_serde::__private::Ok(__Field::#ignore_variant));
|
let fallthrough = quote!(_serde::__private::Ok(__Field::#ignore_variant));
|
||||||
(None, Some(fallthrough))
|
(None, Some((fallthrough.clone(), fallthrough)))
|
||||||
} else if is_variant || cattrs.deny_unknown_fields() {
|
} else if is_variant || cattrs.deny_unknown_fields() {
|
||||||
(None, None)
|
(None, None)
|
||||||
} else {
|
} else {
|
||||||
let ignore_variant = quote!(__ignore,);
|
let ignore_variant = quote!(__ignore,);
|
||||||
let fallthrough = quote!(_serde::__private::Ok(__Field::__ignore));
|
let fallthrough = quote!(_serde::__private::Ok(__Field::__ignore));
|
||||||
(Some(ignore_variant), Some(fallthrough))
|
(
|
||||||
|
Some(ignore_variant),
|
||||||
|
Some((fallthrough.clone(), fallthrough)),
|
||||||
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
let visitor_impl = Stmts(deserialize_identifier(
|
let visitor_impl = Stmts(deserialize_identifier(
|
||||||
@@ -1964,16 +1970,22 @@ fn deserialize_custom_identifier(
|
|||||||
if last.attrs.other() {
|
if last.attrs.other() {
|
||||||
let ordinary = &variants[..variants.len() - 1];
|
let ordinary = &variants[..variants.len() - 1];
|
||||||
let fallthrough = quote!(_serde::__private::Ok(#this::#last_ident));
|
let fallthrough = quote!(_serde::__private::Ok(#this::#last_ident));
|
||||||
(ordinary, Some(fallthrough))
|
(ordinary, Some((fallthrough.clone(), fallthrough)))
|
||||||
} else if let Style::Newtype = last.style {
|
} else if let Style::Newtype = last.style {
|
||||||
let ordinary = &variants[..variants.len() - 1];
|
let ordinary = &variants[..variants.len() - 1];
|
||||||
let deserializer = quote!(_serde::__private::de::IdentifierDeserializer::from(__value));
|
let fallthrough = |method| {
|
||||||
let fallthrough = quote! {
|
quote! {
|
||||||
_serde::__private::Result::map(
|
_serde::__private::Result::map(
|
||||||
_serde::Deserialize::deserialize(#deserializer),
|
_serde::Deserialize::deserialize(
|
||||||
#this::#last_ident)
|
_serde::__private::de::IdentifierDeserializer::#method(__value)
|
||||||
|
),
|
||||||
|
#this::#last_ident)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
(ordinary, Some(fallthrough))
|
(
|
||||||
|
ordinary,
|
||||||
|
Some((fallthrough(quote!(from)), fallthrough(quote!(borrowed)))),
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
(variants, None)
|
(variants, None)
|
||||||
}
|
}
|
||||||
@@ -2045,7 +2057,8 @@ fn deserialize_identifier(
|
|||||||
this: &TokenStream,
|
this: &TokenStream,
|
||||||
fields: &[(String, Ident, Vec<String>)],
|
fields: &[(String, Ident, Vec<String>)],
|
||||||
is_variant: bool,
|
is_variant: bool,
|
||||||
fallthrough: Option<TokenStream>,
|
// .0 for referenced data, .1 -- for borrowed
|
||||||
|
fallthrough: Option<(TokenStream, TokenStream)>,
|
||||||
collect_other_fields: bool,
|
collect_other_fields: bool,
|
||||||
) -> Fragment {
|
) -> Fragment {
|
||||||
let mut flat_fields = Vec::new();
|
let mut flat_fields = Vec::new();
|
||||||
@@ -2053,14 +2066,11 @@ fn deserialize_identifier(
|
|||||||
flat_fields.extend(aliases.iter().map(|alias| (alias, ident)))
|
flat_fields.extend(aliases.iter().map(|alias| (alias, ident)))
|
||||||
}
|
}
|
||||||
|
|
||||||
let field_strs = flat_fields.iter().map(|(name, _)| name);
|
let field_strs: &Vec<_> = &flat_fields.iter().map(|(name, _)| name).collect();
|
||||||
let field_borrowed_strs = flat_fields.iter().map(|(name, _)| name);
|
let field_bytes: &Vec<_> = &flat_fields
|
||||||
let field_bytes = flat_fields
|
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(name, _)| Literal::byte_string(name.as_bytes()));
|
.map(|(name, _)| Literal::byte_string(name.as_bytes()))
|
||||||
let field_borrowed_bytes = flat_fields
|
.collect();
|
||||||
.iter()
|
|
||||||
.map(|(name, _)| Literal::byte_string(name.as_bytes()));
|
|
||||||
|
|
||||||
let constructors: &Vec<_> = &flat_fields
|
let constructors: &Vec<_> = &flat_fields
|
||||||
.iter()
|
.iter()
|
||||||
@@ -2111,16 +2121,18 @@ fn deserialize_identifier(
|
|||||||
(None, None, None, None)
|
(None, None, None, None)
|
||||||
};
|
};
|
||||||
|
|
||||||
let fallthrough_arm = if let Some(fallthrough) = fallthrough {
|
let (fallthrough_arm, fallthrough_borrowed_arm) = if let Some(fallthrough) = fallthrough {
|
||||||
fallthrough
|
fallthrough
|
||||||
} else if is_variant {
|
} else if is_variant {
|
||||||
quote! {
|
let fallthrough = quote! {
|
||||||
_serde::__private::Err(_serde::de::Error::unknown_variant(__value, VARIANTS))
|
_serde::__private::Err(_serde::de::Error::unknown_variant(__value, VARIANTS))
|
||||||
}
|
};
|
||||||
|
(fallthrough.clone(), fallthrough)
|
||||||
} else {
|
} else {
|
||||||
quote! {
|
let fallthrough = quote! {
|
||||||
_serde::__private::Err(_serde::de::Error::unknown_field(__value, FIELDS))
|
_serde::__private::Err(_serde::de::Error::unknown_field(__value, FIELDS))
|
||||||
}
|
};
|
||||||
|
(fallthrough.clone(), fallthrough)
|
||||||
};
|
};
|
||||||
|
|
||||||
let variant_indices = 0_u64..;
|
let variant_indices = 0_u64..;
|
||||||
@@ -2217,37 +2229,6 @@ fn deserialize_identifier(
|
|||||||
{
|
{
|
||||||
_serde::__private::Ok(__Field::__other(_serde::__private::de::Content::Unit))
|
_serde::__private::Ok(__Field::__other(_serde::__private::de::Content::Unit))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_borrowed_str<__E>(self, __value: &'de str) -> _serde::__private::Result<Self::Value, __E>
|
|
||||||
where
|
|
||||||
__E: _serde::de::Error,
|
|
||||||
{
|
|
||||||
match __value {
|
|
||||||
#(
|
|
||||||
#field_borrowed_strs => _serde::__private::Ok(#constructors),
|
|
||||||
)*
|
|
||||||
_ => {
|
|
||||||
#value_as_borrowed_str_content
|
|
||||||
#fallthrough_arm
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_borrowed_bytes<__E>(self, __value: &'de [u8]) -> _serde::__private::Result<Self::Value, __E>
|
|
||||||
where
|
|
||||||
__E: _serde::de::Error,
|
|
||||||
{
|
|
||||||
match __value {
|
|
||||||
#(
|
|
||||||
#field_borrowed_bytes => _serde::__private::Ok(#constructors),
|
|
||||||
)*
|
|
||||||
_ => {
|
|
||||||
#bytes_to_str
|
|
||||||
#value_as_borrowed_bytes_content
|
|
||||||
#fallthrough_arm
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
quote! {
|
quote! {
|
||||||
@@ -2290,6 +2271,21 @@ fn deserialize_identifier(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_borrowed_str<__E>(self, __value: &'de str) -> _serde::__private::Result<Self::Value, __E>
|
||||||
|
where
|
||||||
|
__E: _serde::de::Error,
|
||||||
|
{
|
||||||
|
match __value {
|
||||||
|
#(
|
||||||
|
#field_strs => _serde::__private::Ok(#constructors),
|
||||||
|
)*
|
||||||
|
_ => {
|
||||||
|
#value_as_borrowed_str_content
|
||||||
|
#fallthrough_borrowed_arm
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn visit_bytes<__E>(self, __value: &[u8]) -> _serde::__private::Result<Self::Value, __E>
|
fn visit_bytes<__E>(self, __value: &[u8]) -> _serde::__private::Result<Self::Value, __E>
|
||||||
where
|
where
|
||||||
__E: _serde::de::Error,
|
__E: _serde::de::Error,
|
||||||
@@ -2305,6 +2301,22 @@ fn deserialize_identifier(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_borrowed_bytes<__E>(self, __value: &'de [u8]) -> _serde::__private::Result<Self::Value, __E>
|
||||||
|
where
|
||||||
|
__E: _serde::de::Error,
|
||||||
|
{
|
||||||
|
match __value {
|
||||||
|
#(
|
||||||
|
#field_bytes => _serde::__private::Ok(#constructors),
|
||||||
|
)*
|
||||||
|
_ => {
|
||||||
|
#bytes_to_str
|
||||||
|
#value_as_borrowed_bytes_content
|
||||||
|
#fallthrough_borrowed_arm
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
//!
|
//!
|
||||||
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html
|
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html
|
||||||
|
|
||||||
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.119")]
|
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.121")]
|
||||||
#![allow(unknown_lints, bare_trait_objects)]
|
#![allow(unknown_lints, bare_trait_objects)]
|
||||||
#![deny(clippy::all, clippy::pedantic)]
|
#![deny(clippy::all, clippy::pedantic)]
|
||||||
// Ignored clippy lints
|
// Ignored clippy lints
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_test"
|
name = "serde_test"
|
||||||
version = "1.0.119" # remember to update html_root_url
|
version = "1.0.121" # remember to update html_root_url
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
description = "Token De/Serializer for testing De/Serialize implementations"
|
description = "Token De/Serializer for testing De/Serialize implementations"
|
||||||
|
|||||||
@@ -144,7 +144,7 @@
|
|||||||
//! # }
|
//! # }
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.119")]
|
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.121")]
|
||||||
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
|
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
|
||||||
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
|
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
|
||||||
// Ignored clippy lints
|
// Ignored clippy lints
|
||||||
|
|||||||
@@ -90,6 +90,30 @@ fn test_struct() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_field_identifier() {
|
||||||
|
#[derive(Deserialize, Debug, PartialEq)]
|
||||||
|
#[serde(field_identifier)]
|
||||||
|
enum FieldStr<'a> {
|
||||||
|
#[serde(borrow)]
|
||||||
|
Str(&'a str),
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_de_tokens(&FieldStr::Str("value"), &[Token::BorrowedStr("value")]);
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug, PartialEq)]
|
||||||
|
#[serde(field_identifier)]
|
||||||
|
enum FieldBytes<'a> {
|
||||||
|
#[serde(borrow)]
|
||||||
|
Bytes(&'a [u8]),
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_de_tokens(
|
||||||
|
&FieldBytes::Bytes(b"value"),
|
||||||
|
&[Token::BorrowedBytes(b"value")],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_cow() {
|
fn test_cow() {
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
|
|||||||
@@ -1452,4 +1452,25 @@ declare_error_tests! {
|
|||||||
],
|
],
|
||||||
"invalid value: integer `65536`, expected u16",
|
"invalid value: integer `65536`, expected u16",
|
||||||
}
|
}
|
||||||
|
test_duration_overflow_seq<Duration> {
|
||||||
|
&[
|
||||||
|
Token::Seq { len: Some(2) },
|
||||||
|
Token::U64(u64::max_value()),
|
||||||
|
Token::U32(1_000_000_000),
|
||||||
|
Token::SeqEnd,
|
||||||
|
],
|
||||||
|
"overflow deserializing Duration",
|
||||||
|
}
|
||||||
|
test_duration_overflow_struct<Duration> {
|
||||||
|
&[
|
||||||
|
Token::Struct { name: "Duration", len: 2 },
|
||||||
|
Token::Str("secs"),
|
||||||
|
Token::U64(u64::max_value()),
|
||||||
|
|
||||||
|
Token::Str("nanos"),
|
||||||
|
Token::U32(1_000_000_000),
|
||||||
|
Token::StructEnd,
|
||||||
|
],
|
||||||
|
"overflow deserializing Duration",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user