Skip to content

Commit

Permalink
Add Serialize/Deserialize impls for Range{From,Full,To}
Browse files Browse the repository at this point in the history
CC #796
CC #1466
CC #1713
  • Loading branch information
tbu- committed Jun 9, 2023
1 parent 8a4dfa7 commit e76e87a
Show file tree
Hide file tree
Showing 3 changed files with 359 additions and 4 deletions.
316 changes: 313 additions & 3 deletions serde/src/de/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2258,9 +2258,9 @@ impl<'de> Deserialize<'de> for SystemTime {
//
// #[derive(Deserialize)]
// #[serde(deny_unknown_fields)]
// struct Range {
// start: u64,
// end: u32,
// struct Range<Idx> {
// start: Idx,
// end: Idx,
// }
impl<'de, Idx> Deserialize<'de> for Range<Idx>
where
Expand Down Expand Up @@ -2434,6 +2434,316 @@ mod range {

////////////////////////////////////////////////////////////////////////////////

// Similar to:
//
// #[derive(Deserialize)]
// #[serde(deny_unknown_fields)]
// struct RangeFrom<Idx> {
// start: Idx,
// }
impl<'de, Idx> Deserialize<'de> for RangeFrom<Idx>
where
Idx: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let start = try!(deserializer.deserialize_struct(
"RangeFrom",
range_from::FIELDS,
range_from::RangeFromVisitor {
expecting: "struct RangeFrom",
phantom: PhantomData,
},
));
Ok(start..)
}
}

mod range_from {
use lib::*;

use de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};

pub const FIELDS: &'static [&'static str] = &["end"];

// If this were outside of the serde crate, it would just use:
//
// #[derive(Deserialize)]
// #[serde(field_identifier, rename_all = "lowercase")]
enum Field {
End,
}

impl<'de> Deserialize<'de> for Field {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct FieldVisitor;

impl<'de> Visitor<'de> for FieldVisitor {
type Value = Field;

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("`end`")
}

fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: Error,
{
match value {
"end" => Ok(Field::End),
_ => Err(Error::unknown_field(value, FIELDS)),
}
}

fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
where
E: Error,
{
match value {
b"end" => Ok(Field::End),
_ => {
let value = ::__private::from_utf8_lossy(value);
Err(Error::unknown_field(&*value, FIELDS))
}
}
}
}

deserializer.deserialize_identifier(FieldVisitor)
}
}

pub struct RangeFromVisitor<Idx> {
pub expecting: &'static str,
pub phantom: PhantomData<Idx>,
}

impl<'de, Idx> Visitor<'de> for RangeFromVisitor<Idx>
where
Idx: Deserialize<'de>,
{
type Value = Idx;

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str(self.expecting)
}

fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let end: Idx = match try!(seq.next_element()) {
Some(value) => value,
None => {
return Err(Error::invalid_length(0, &self));
}
};
Ok(end)
}

fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
let mut end: Option<Idx> = None;
while let Some(key) = try!(map.next_key()) {
match key {
Field::End => {
if end.is_some() {
return Err(<A::Error as Error>::duplicate_field("end"));
}
end = Some(try!(map.next_value()));
}
}
}
let end = match end {
Some(end) => end,
None => return Err(<A::Error as Error>::missing_field("end")),
};
Ok(end)
}
}
}

////////////////////////////////////////////////////////////////////////////////

// Similar to:
//
// #[derive(Deserialize)]
// #[serde(deny_unknown_fields)]
// struct RangeTo<Idx> {
// start: Idx,
// }
impl<'de, Idx> Deserialize<'de> for RangeTo<Idx>
where
Idx: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let end = try!(deserializer.deserialize_struct(
"RangeTo",
range_to::FIELDS,
range_to::RangeToVisitor {
expecting: "struct RangeTo",
phantom: PhantomData,
},
));
Ok(..end)
}
}

mod range_to {
use lib::*;

use de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};

pub const FIELDS: &'static [&'static str] = &["start"];

// If this were outside of the serde crate, it would just use:
//
// #[derive(Deserialize)]
// #[serde(field_identifier, rename_all = "lowercase")]
enum Field {
Start,
}

impl<'de> Deserialize<'de> for Field {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct FieldVisitor;

impl<'de> Visitor<'de> for FieldVisitor {
type Value = Field;

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("`start`")
}

fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: Error,
{
match value {
"start" => Ok(Field::Start),
_ => Err(Error::unknown_field(value, FIELDS)),
}
}

fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
where
E: Error,
{
match value {
b"start" => Ok(Field::Start),
_ => {
let value = ::__private::from_utf8_lossy(value);
Err(Error::unknown_field(&*value, FIELDS))
}
}
}
}

deserializer.deserialize_identifier(FieldVisitor)
}
}

pub struct RangeToVisitor<Idx> {
pub expecting: &'static str,
pub phantom: PhantomData<Idx>,
}

impl<'de, Idx> Visitor<'de> for RangeToVisitor<Idx>
where
Idx: Deserialize<'de>,
{
type Value = Idx;

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str(self.expecting)
}

fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let start: Idx = match try!(seq.next_element()) {
Some(value) => value,
None => {
return Err(Error::invalid_length(0, &self));
}
};
Ok(start)
}

fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
let mut start: Option<Idx> = None;
while let Some(key) = try!(map.next_key()) {
match key {
Field::Start => {
if start.is_some() {
return Err(<A::Error as Error>::duplicate_field("start"));
}
start = Some(try!(map.next_value()));
}
}
}
let start = match start {
Some(start) => start,
None => return Err(<A::Error as Error>::missing_field("start")),
};
Ok(start)
}
}
}

////////////////////////////////////////////////////////////////////////////////

// Similar to:
//
// #[derive(Deserialize)]
// #[serde(deny_unknown_fields)]
// struct RangeFull;
impl<'de> Deserialize<'de> for RangeFull {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_unit_struct("RangeFull", RangeFullVisitor)
}
}

struct RangeFullVisitor;

impl<'de> Visitor<'de> for RangeFullVisitor {
type Value = RangeFull;

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("unit")
}

#[inline]
fn visit_unit<E>(self) -> Result<Self::Value, E>
where
E: Error,
{
Ok(..)
}
}

////////////////////////////////////////////////////////////////////////////////

#[cfg(any(not(no_ops_bound), all(feature = "std", not(no_collections_bound))))]
impl<'de, T> Deserialize<'de> for Bound<T>
where
Expand Down
2 changes: 1 addition & 1 deletion serde/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ mod lib {
pub use self::core::fmt::{self, Debug, Display};
pub use self::core::marker::{self, PhantomData};
pub use self::core::num::Wrapping;
pub use self::core::ops::Range;
pub use self::core::ops::{Range, RangeFrom, RangeFull, RangeTo};
pub use self::core::option::{self, Option};
pub use self::core::result::{self, Result};

Expand Down
45 changes: 45 additions & 0 deletions serde/src/ser/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,34 @@ where

////////////////////////////////////////////////////////////////////////////////

impl<Idx> Serialize for RangeFrom<Idx>
where
Idx: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
use super::SerializeStruct;
let mut state = try!(serializer.serialize_struct("RangeFrom", 1));
try!(state.serialize_field("start", &self.start));
state.end()
}
}

////////////////////////////////////////////////////////////////////////////////

impl Serialize for RangeFull {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_unit_struct("RangeFull")
}
}

////////////////////////////////////////////////////////////////////////////////

#[cfg(not(no_range_inclusive))]
impl<Idx> Serialize for RangeInclusive<Idx>
where
Expand All @@ -276,6 +304,23 @@ where

////////////////////////////////////////////////////////////////////////////////

impl<Idx> Serialize for RangeTo<Idx>
where
Idx: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
use super::SerializeStruct;
let mut state = try!(serializer.serialize_struct("RangeTo", 1));
try!(state.serialize_field("end", &self.end));
state.end()
}
}

////////////////////////////////////////////////////////////////////////////////

#[cfg(any(not(no_ops_bound), all(feature = "std", not(no_collections_bound))))]
impl<T> Serialize for Bound<T>
where
Expand Down

0 comments on commit e76e87a

Please sign in to comment.