Skip to content

Instantly share code, notes, and snippets.

@killercup
Last active Jun 24, 2019
Embed
What would you like to do?
/target
**/*.rs.bk
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "dtoa"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "linked-hash-map"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "proc-macro2"
version = "0.4.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "quote"
version = "0.6.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde"
version = "1.0.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde_derive 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde-issue-1545"
version = "0.1.0"
dependencies = [
"serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_yaml 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)",
"unindent 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_derive"
version = "1.0.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.38 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_yaml"
version = "0.8.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)",
"yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "syn"
version = "0.15.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-xid"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unindent"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "yaml-rust"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[metadata]
"checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e"
"checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83"
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
"checksum quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db"
"checksum serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)" = "960e29cf7004b3b6e65fc5002981400eb3ccc017a08a2406940823e58e7179a9"
"checksum serde_derive 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)" = "c4cce6663696bd38272e90bf34a0267e1226156c33f52d3f3915a2dd5d802085"
"checksum serde_yaml 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)" = "38b08a9a90e5260fe01c6480ec7c811606df6d3a660415808c3c3fa8ed95b582"
"checksum syn 0.15.38 (registry+https://github.com/rust-lang/crates.io-index)" = "37ea458a750f59ab679b47fef9b6722c586c5742f4cfe18a120bbc807e5e01fd"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum unindent 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "834b4441326c660336850c5c0926cc20548e848967a5f57bc20c2b741c8d41f4"
"checksum yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "65923dd1784f44da1d2c3dbbc5e822045628c590ba72123e1c73d3c230c4434d"
[package]
name = "serde-issue-1545"
version = "0.1.0"
authors = ["Pascal Hertleif <pascal@technocreatives.com>"]
edition = "2018"
[[bin]]
name = "serde-issue-1545"
path = "main.rs"
[[test]]
name = "test_string"
path = "test_string.rs"
[[test]]
name = "test_status_code"
path = "test_status_code.rs"
[[test]]
name = "test_reference_enum"
path = "test_reference_enum.rs"
[dependencies]
serde = { version = "1.0.93", features = ["derive"] }
serde_yaml = "0.8.9"
unindent = "0.1.3"
fn main() {}
use serde::{Deserialize, Deserializer, de::{self, Unexpected, Visitor}};
use std::fmt;
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum StatusCode {
Code(u16),
Range(u16),
}
impl<'de> Deserialize<'de> for StatusCode {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct StatusCodeVisitor;
impl<'de> Visitor<'de> for StatusCodeVisitor {
type Value = StatusCode;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("A number between 100 and 999 (as string or integer) or a string that matches `\\dXX`")
}
fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
where
E: de::Error,
{
if value < 100 && value > 100 {
return Err(E::invalid_value(
Unexpected::Signed(value),
&"range 100..1000",
));
}
Ok(StatusCode::Code(value as u16))
}
fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
where
E: de::Error,
{
if value >= 100 && value < 1000 {
Ok(StatusCode::Code(value as u16))
} else {
Err(E::invalid_value(Unexpected::Unsigned(value), &self))
}
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
if value.len() != 3 {
return Err(E::invalid_value(Unexpected::Str(value), &"length 3"));
}
if let Ok(number) = value.parse::<i64>() {
return self.visit_i64(number);
}
if !value.is_ascii() {
return Err(E::invalid_value(
Unexpected::Str(value),
&"ascii, format `\\dXX`",
));
}
let v = value.as_bytes().to_ascii_uppercase();
match [v[0], v[1], v[2]] {
[n, b'X', b'X'] if n.is_ascii_digit() => {
Ok(StatusCode::Range((n - b'0') as u16))
}
_ => Err(E::invalid_value(Unexpected::Str(value), &"format `\\dXX`")),
}
}
}
deserializer.deserialize_any(StatusCodeVisitor)
}
}
use unindent::unindent;
#[test]
fn string_key() {
let item: Item = serde_yaml::from_str(&unindent(
r#"
responses:
"200":
description: All is well
"#,
))
.unwrap();
println!("{:?}", item);
}
#[test]
fn int_key() {
let item: Item = serde_yaml::from_str(&unindent(
"
responses:
200:
description: All is well
",
))
.unwrap();
println!("{:?}", item);
}
#[test]
fn mixed_keys() {
let item: Item = serde_yaml::from_str(&unindent(
r#"
responses:
200:
description: All is well
"404":
description: All is well
"#,
))
.unwrap();
println!("{:?}", item);
}
#[test]
fn default_key() {
let item: Item = serde_yaml::from_str(&unindent(
"
responses:
default:
description: All is well
",
))
.unwrap();
println!("{:?}", item);
}
#![allow(unused)]
use std::collections::BTreeMap;
mod status_code;
use status_code::StatusCode;
#[derive(serde::Deserialize, Clone, Debug, PartialEq)]
#[serde(untagged)]
pub enum ReferenceOr<T> {
Reference {
#[serde(rename = "$ref")]
reference: String
},
Item(T),
}
#[derive(Debug, serde::Deserialize)]
struct Item {
responses: ReferenceOr<Responses>,
}
#[derive(Debug, serde::Deserialize)]
struct Responses {
default: Option<ReferenceOr<Unimportant>>,
#[serde(flatten)]
#[serde(default)]
values: BTreeMap<StatusCode, Unimportant>,
}
#[derive(Debug, serde::Deserialize)]
struct Unimportant {
description: String,
}
include!("test_cases.rs");
#![allow(unused)]
mod status_code;
use status_code::StatusCode;
use std::collections::BTreeMap;
#[derive(Debug, serde::Deserialize)]
struct Item {
responses: Responses,
}
#[derive(Debug, serde::Deserialize)]
struct Responses {
default: Option<Unimportant>,
#[serde(flatten)]
#[serde(default)]
values: BTreeMap<StatusCode, Unimportant>,
}
#[derive(Debug, serde::Deserialize)]
struct Unimportant {
description: String,
}
include!("test_cases.rs");
#![allow(unused)]
use std::collections::BTreeMap;
#[derive(Debug, serde::Deserialize)]
struct Item {
responses: Responses,
}
#[derive(Debug, serde::Deserialize)]
struct Responses {
default: Option<Unimportant>,
#[serde(flatten)]
#[serde(default)]
values: BTreeMap<String, Unimportant>,
}
#[derive(Debug, serde::Deserialize)]
struct Unimportant {
description: String,
}
include!("test_cases.rs");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment