Skip to content

Commit

Permalink
Merge #655
Browse files Browse the repository at this point in the history
655: Add support for core::ops::Bound r=jonasbb a=qsantos

I have encountered a case where I would like to use `Bound<Cow<'a, str>>` and borrow the string from the deserialized buffer instead of copying. To use `BorrowStr`, I had to add support for `core::ops::Bound` to `serde_with`.

Co-authored-by: Quentin Santos <qsantos@qsantos.fr>
  • Loading branch information
bors[bot] and qsantos authored Oct 14, 2023
2 parents f55d41d + e144133 commit e1657b4
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 0 deletions.
18 changes: 18 additions & 0 deletions serde_with/src/de/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,24 @@ where
}
}

impl<'de, T, U> DeserializeAs<'de, Bound<T>> for Bound<U>
where
U: DeserializeAs<'de, T>,
{
fn deserialize_as<D>(deserializer: D) -> Result<Bound<T>, D::Error>
where
D: Deserializer<'de>,
{
Ok(
match Bound::<DeserializeAsWrap<T, U>>::deserialize(deserializer)? {
Bound::Unbounded => Bound::Unbounded,
Bound::Included(v) => Bound::Included(v.into_inner()),
Bound::Excluded(v) => Bound::Excluded(v.into_inner()),
},
)
}
}

#[cfg(feature = "alloc")]
impl<'de, T, U> DeserializeAs<'de, Rc<T>> for Rc<U>
where
Expand Down
1 change: 1 addition & 0 deletions serde_with/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,7 @@ pub(crate) mod prelude {
fmt::{self, Display},
hash::{BuildHasher, Hash},
marker::PhantomData,
ops::Bound,
option::Option,
result::Result,
str::FromStr,
Expand Down
18 changes: 18 additions & 0 deletions serde_with/src/ser/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,24 @@ where
}
}

impl<T, U> SerializeAs<Bound<T>> for Bound<U>
where
U: SerializeAs<T>,
T: Sized,
{
fn serialize_as<S>(source: &Bound<T>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match source {
Bound::Unbounded => Bound::Unbounded,
Bound::Included(ref v) => Bound::Included(SerializeAsWrap::<T, U>::new(v)),
Bound::Excluded(ref v) => Bound::Excluded(SerializeAsWrap::<T, U>::new(v)),
}
.serialize(serializer)
}
}

#[cfg(feature = "alloc")]
impl<T, U> SerializeAs<Rc<T>> for Rc<U>
where
Expand Down
36 changes: 36 additions & 0 deletions serde_with/tests/serde_as/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ use alloc::{
sync::{Arc, Weak as ArcWeak},
};
use core::cell::{Cell, RefCell};
use core::ops::Bound;
use expect_test::expect;
use serde::{Deserialize, Serialize};
use serde_with::{
Expand Down Expand Up @@ -136,6 +137,41 @@ fn test_option() {
);
}

#[test]
fn test_bound() {
#[serde_as]
#[derive(Debug, Serialize, Deserialize, PartialEq)]
struct S(#[serde_as(as = "Bound<DisplayFromStr>")] Bound<u32>);

is_equal(S(Bound::Unbounded), expect![[r#""Unbounded""#]]);
is_equal(
S(Bound::Included(42)),
expect![[r#"
{
"Included": "42"
}"#]],
);
is_equal(
S(Bound::Excluded(42)),
expect![[r#"
{
"Excluded": "42"
}"#]],
);
check_error_deserialization::<S>(r#"{}"#, expect![[r#"expected value at line 1 column 2"#]]);

#[serde_as]
#[derive(Debug, Serialize, Deserialize, PartialEq)]
struct Struct {
#[serde_as(as = "Bound<DisplayFromStr>")]
value: Bound<u32>,
}
check_error_deserialization::<Struct>(
r#"{}"#,
expect![[r#"missing field `value` at line 1 column 2"#]],
);
}

#[test]
fn test_result() {
#[serde_as]
Expand Down

0 comments on commit e1657b4

Please sign in to comment.