Compare commits

...

8 Commits

Author SHA1 Message Date
David Tolnay 44613c7d01 Release 1.0.193 2023-11-20 17:34:20 -08:00
David Tolnay c706281df3 Merge pull request #2655 from dtolnay/rangestartend
Add RangeFrom and RangeTo tests
2023-11-20 17:33:42 -08:00
David Tolnay 65d75b8fe3 Add RangeFrom and RangeTo tests 2023-11-20 17:28:38 -08:00
David Tolnay 332b0cba40 Merge pull request #2654 from dtolnay/rangestartend
Fix more RangeFrom / RangeEnd mixups
2023-11-20 17:27:31 -08:00
David Tolnay 8c4af41296 Fix more RangeFrom / RangeEnd mixups 2023-11-20 17:21:59 -08:00
David Tolnay 24a78f071b Merge pull request #2653 from emilbonnek/fix/range-to-from-de-mixup
Fix Range{From,To} deserialize mixup
2023-11-20 17:20:04 -08:00
Emil Bonne Kristiansen c91c33436d Fix Range{From,To} deserialize mixup 2023-11-21 02:13:18 +01:00
David Tolnay 2083f43a28 Update ui test suite to nightly-2023-11-19 2023-11-18 18:13:57 -08:00
8 changed files with 222 additions and 145 deletions
+2 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "serde"
version = "1.0.192"
version = "1.0.193"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
build = "build.rs"
categories = ["encoding", "no-std", "no-std::no-alloc"]
@@ -37,7 +37,7 @@ rustdoc-args = ["--cfg", "doc_cfg", "--generate-link-to-definition"]
# is compatible with exactly one serde release because the generated code
# involves nonpublic APIs which are not bound by semver.
[target.'cfg(any())'.dependencies]
serde_derive = { version = "=1.0.192", path = "../serde_derive" }
serde_derive = { version = "=1.0.193", path = "../serde_derive" }
### FEATURES #################################################################
+140 -140
View File
@@ -2526,144 +2526,6 @@ mod range_from {
use crate::de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
pub const FIELDS: &[&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 = crate::__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 tri!(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) = tri!(map.next_key()) {
match key {
Field::End => {
if end.is_some() {
return Err(<A::Error as Error>::duplicate_field("end"));
}
end = Some(tri!(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 = tri!(deserializer.deserialize_struct(
"RangeTo",
range_to::FIELDS,
range_to::RangeToVisitor {
expecting: "struct RangeTo",
phantom: PhantomData,
},
));
Ok(..end)
}
}
mod range_to {
use crate::lib::*;
use crate::de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
pub const FIELDS: &[&str] = &["start"];
// If this were outside of the serde crate, it would just use:
@@ -2716,12 +2578,12 @@ mod range_to {
}
}
pub struct RangeToVisitor<Idx> {
pub struct RangeFromVisitor<Idx> {
pub expecting: &'static str,
pub phantom: PhantomData<Idx>,
}
impl<'de, Idx> Visitor<'de> for RangeToVisitor<Idx>
impl<'de, Idx> Visitor<'de> for RangeFromVisitor<Idx>
where
Idx: Deserialize<'de>,
{
@@ -2770,6 +2632,144 @@ mod range_to {
////////////////////////////////////////////////////////////////////////////////
// Similar to:
//
// #[derive(Deserialize)]
// #[serde(deny_unknown_fields)]
// struct RangeTo<Idx> {
// end: 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 = tri!(deserializer.deserialize_struct(
"RangeTo",
range_to::FIELDS,
range_to::RangeToVisitor {
expecting: "struct RangeTo",
phantom: PhantomData,
},
));
Ok(..end)
}
}
mod range_to {
use crate::lib::*;
use crate::de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
pub const FIELDS: &[&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 = crate::__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 end: Idx = match tri!(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) = tri!(map.next_key()) {
match key {
Field::End => {
if end.is_some() {
return Err(<A::Error as Error>::duplicate_field("end"));
}
end = Some(tri!(map.next_value()));
}
}
}
let end = match end {
Some(end) => end,
None => return Err(<A::Error as Error>::missing_field("end")),
};
Ok(end)
}
}
}
////////////////////////////////////////////////////////////////////////////////
impl<'de, T> Deserialize<'de> for Bound<T>
where
T: Deserialize<'de>,
+1 -1
View File
@@ -95,7 +95,7 @@
////////////////////////////////////////////////////////////////////////////////
// Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.192")]
#![doc(html_root_url = "https://docs.rs/serde/1.0.193")]
// Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)]
// Show which crate feature enables conditionally compiled APIs in documentation.
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_derive"
version = "1.0.192"
version = "1.0.193"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
categories = ["no-std", "no-std::no-alloc"]
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
+1 -1
View File
@@ -13,7 +13,7 @@
//!
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.192")]
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.193")]
// Ignored clippy lints
#![allow(
// clippy false positive: https://github.com/rust-lang/rust-clippy/issues/7054
+40
View File
@@ -1898,6 +1898,46 @@ fn test_range_inclusive() {
);
}
#[test]
fn test_range_from() {
test(
1u32..,
&[
Token::Struct {
name: "RangeFrom",
len: 1,
},
Token::Str("start"),
Token::U32(1),
Token::StructEnd,
],
);
test(
1u32..,
&[Token::Seq { len: Some(1) }, Token::U32(1), Token::SeqEnd],
);
}
#[test]
fn test_range_to() {
test(
..2u32,
&[
Token::Struct {
name: "RangeTo",
len: 1,
},
Token::Str("end"),
Token::U32(2),
Token::StructEnd,
],
);
test(
..2u32,
&[Token::Seq { len: Some(1) }, Token::U32(2), Token::SeqEnd],
);
}
#[test]
fn test_bound() {
test(
+32
View File
@@ -500,6 +500,38 @@ fn test_range_inclusive() {
);
}
#[test]
fn test_range_from() {
assert_ser_tokens(
&(1u32..),
&[
Token::Struct {
name: "RangeFrom",
len: 1,
},
Token::Str("start"),
Token::U32(1),
Token::StructEnd,
],
);
}
#[test]
fn test_range_to() {
assert_ser_tokens(
&(..2u32),
&[
Token::Struct {
name: "RangeTo",
len: 1,
},
Token::Str("end"),
Token::U32(2),
Token::StructEnd,
],
);
}
#[test]
fn test_bound() {
assert_ser_tokens(
@@ -3,6 +3,11 @@ error[E0609]: no field `b` on type `&remote::S`
|
12 | b: u8,
| ^ unknown field
|
help: a field with a similar name exists
|
12 | a: u8,
| ~
error[E0560]: struct `remote::S` has no field named `b`
--> tests/ui/remote/unknown_field.rs:12:5