Impl Serialize for Bound<T>
This commit is contained in:
parent
bb99b31eb0
commit
4bb45c8252
@ -2269,6 +2269,116 @@ mod range {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
impl<'de, T> Deserialize<'de> for Bound<T>
|
||||||
|
where
|
||||||
|
T: Deserialize<'de>
|
||||||
|
{
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
enum Field {
|
||||||
|
Unbounded,
|
||||||
|
Included,
|
||||||
|
Excluded,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> Deserialize<'de> for Field {
|
||||||
|
#[inline]
|
||||||
|
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("`Unbounded`, `Included` or `Excluded`")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_u32<E>(self, value: u32) -> Result<Self::Value, E>
|
||||||
|
where
|
||||||
|
E: Error,
|
||||||
|
{
|
||||||
|
match value {
|
||||||
|
0 => Ok(Field::Unbounded),
|
||||||
|
1 => Ok(Field::Included),
|
||||||
|
2 => Ok(Field::Excluded),
|
||||||
|
_ => Err(Error::invalid_value(
|
||||||
|
Unexpected::Unsigned(value as u64),
|
||||||
|
&self,
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
|
||||||
|
where
|
||||||
|
E: Error,
|
||||||
|
{
|
||||||
|
match value {
|
||||||
|
"Unbounded" => Ok(Field::Unbounded),
|
||||||
|
"Included" => Ok(Field::Included),
|
||||||
|
"Excluded" => Ok(Field::Excluded),
|
||||||
|
_ => Err(Error::unknown_variant(value, VARIANTS)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
|
||||||
|
where
|
||||||
|
E: Error,
|
||||||
|
{
|
||||||
|
match value {
|
||||||
|
b"Unbounded" => Ok(Field::Unbounded),
|
||||||
|
b"Included" => Ok(Field::Included),
|
||||||
|
b"Excluded" => Ok(Field::Excluded),
|
||||||
|
_ => match str::from_utf8(value) {
|
||||||
|
Ok(value) => Err(Error::unknown_variant(value, VARIANTS)),
|
||||||
|
Err(_) => {
|
||||||
|
Err(Error::invalid_value(Unexpected::Bytes(value), &self))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deserializer.deserialize_identifier(FieldVisitor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct BoundVisitor<T>(PhantomData<Bound<T>>);
|
||||||
|
|
||||||
|
impl<'de, T> Visitor<'de> for BoundVisitor<T>
|
||||||
|
where
|
||||||
|
T: Deserialize<'de>,
|
||||||
|
{
|
||||||
|
type Value = Bound<T>;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
formatter.write_str("enum Bound")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
|
||||||
|
where
|
||||||
|
A: EnumAccess<'de>,
|
||||||
|
{
|
||||||
|
match try!(data.variant()) {
|
||||||
|
(Field::Unbounded, v) => v.newtype_variant().map(|_: T| Bound::Unbounded),
|
||||||
|
(Field::Included, v) => v.newtype_variant().map(Bound::Included),
|
||||||
|
(Field::Excluded, v) => v.newtype_variant().map(Bound::Excluded),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const VARIANTS: &'static [&'static str] = &["Unbounded", "Included", "Excluded"];
|
||||||
|
|
||||||
|
deserializer.deserialize_enum("Bound", VARIANTS, BoundVisitor(PhantomData))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
macro_rules! nonzero_integers {
|
macro_rules! nonzero_integers {
|
||||||
( $( $T: ident, )+ ) => {
|
( $( $T: ident, )+ ) => {
|
||||||
$(
|
$(
|
||||||
|
@ -160,7 +160,7 @@ mod lib {
|
|||||||
pub use self::core::default::{self, Default};
|
pub use self::core::default::{self, Default};
|
||||||
pub use self::core::fmt::{self, Debug, Display};
|
pub use self::core::fmt::{self, Debug, Display};
|
||||||
pub use self::core::marker::{self, PhantomData};
|
pub use self::core::marker::{self, PhantomData};
|
||||||
pub use self::core::ops::Range;
|
pub use self::core::ops::{Range, Bound};
|
||||||
pub use self::core::option::{self, Option};
|
pub use self::core::option::{self, Option};
|
||||||
pub use self::core::result::{self, Result};
|
pub use self::core::result::{self, Result};
|
||||||
|
|
||||||
|
@ -256,6 +256,24 @@ where
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
impl<T> Serialize for Bound<T>
|
||||||
|
where
|
||||||
|
T: Serialize,
|
||||||
|
{
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
match *self {
|
||||||
|
Bound::Unbounded => serializer.serialize_unit_variant("Bound", 0, "Unbounded"),
|
||||||
|
Bound::Included(ref value) => serializer.serialize_newtype_variant("Bound", 1, "Included", value),
|
||||||
|
Bound::Excluded(ref value) => serializer.serialize_newtype_variant("Bound", 2, "Excluded", value),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
impl Serialize for () {
|
impl Serialize for () {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
@ -10,6 +10,7 @@ use std::path::{Path, PathBuf};
|
|||||||
use std::rc::{Rc, Weak as RcWeak};
|
use std::rc::{Rc, Weak as RcWeak};
|
||||||
use std::sync::{Arc, Weak as ArcWeak};
|
use std::sync::{Arc, Weak as ArcWeak};
|
||||||
use std::time::{Duration, UNIX_EPOCH};
|
use std::time::{Duration, UNIX_EPOCH};
|
||||||
|
use std::ops::Bound;
|
||||||
|
|
||||||
use fnv::FnvHasher;
|
use fnv::FnvHasher;
|
||||||
use serde::{Deserialize, Deserializer};
|
use serde::{Deserialize, Deserializer};
|
||||||
@ -836,6 +837,23 @@ declare_tests! {
|
|||||||
Token::SeqEnd,
|
Token::SeqEnd,
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
test_bound {
|
||||||
|
Bound::Unbounded::<()> => &[
|
||||||
|
Token::Enum { name: "Bound" },
|
||||||
|
Token::Str("Unbounded"),
|
||||||
|
Token::Unit,
|
||||||
|
],
|
||||||
|
Bound::Included(0) => &[
|
||||||
|
Token::Enum { name: "Bound" },
|
||||||
|
Token::Str("Included"),
|
||||||
|
Token::U8(0),
|
||||||
|
],
|
||||||
|
Bound::Excluded(0) => &[
|
||||||
|
Token::Enum { name: "Bound" },
|
||||||
|
Token::Str("Excluded"),
|
||||||
|
Token::U8(0),
|
||||||
|
],
|
||||||
|
}
|
||||||
test_path {
|
test_path {
|
||||||
Path::new("/usr/local/lib") => &[
|
Path::new("/usr/local/lib") => &[
|
||||||
Token::BorrowedStr("/usr/local/lib"),
|
Token::BorrowedStr("/usr/local/lib"),
|
||||||
|
@ -10,6 +10,7 @@ use std::path::{Path, PathBuf};
|
|||||||
use std::rc::{Rc, Weak as RcWeak};
|
use std::rc::{Rc, Weak as RcWeak};
|
||||||
use std::sync::{Arc, Weak as ArcWeak};
|
use std::sync::{Arc, Weak as ArcWeak};
|
||||||
use std::time::{Duration, UNIX_EPOCH};
|
use std::time::{Duration, UNIX_EPOCH};
|
||||||
|
use std::ops::Bound;
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
use std::str;
|
use std::str;
|
||||||
|
Loading…
Reference in New Issue
Block a user