Skip to content
This repository has been archived by the owner on Mar 25, 2024. It is now read-only.

Commit

Permalink
Support deserializing tagged literal scalar into primitive
Browse files Browse the repository at this point in the history
  • Loading branch information
dtolnay committed Sep 14, 2022
1 parent f41036c commit bfff6c1
Showing 1 changed file with 44 additions and 6 deletions.
50 changes: 44 additions & 6 deletions src/de.rs
Expand Up @@ -1149,6 +1149,26 @@ where
}
}

fn is_plain_or_tagged_literal_scalar(
expected: &str,
scalar: &Scalar,
tagged_already: bool,
) -> bool {
if scalar.style == ScalarStyle::Plain {
return true;
}
if tagged_already {
return false;
}
if scalar.style != ScalarStyle::Literal {
return false;
}
if let Some(tag) = &scalar.tag {
return tag == expected;
}
false
}

fn invalid_type(event: &Event, exp: &dyn Expected) -> Error {
enum Void {}

Expand Down Expand Up @@ -1250,11 +1270,14 @@ impl<'de, 'document> de::Deserializer<'de> for &mut DeserializerFromEvents<'de,
where
V: Visitor<'de>,
{
let tagged_already = self.current_enum.is_some();
let (next, mark) = self.next_event_mark()?;
loop {
match next {
Event::Alias(mut pos) => break self.jump(&mut pos)?.deserialize_bool(visitor),
Event::Scalar(scalar) if scalar.style == ScalarStyle::Plain => {
Event::Scalar(scalar)
if is_plain_or_tagged_literal_scalar(Tag::BOOL, scalar, tagged_already) =>
{
if let Ok(value) = str::from_utf8(&scalar.value) {
if let Some(boolean) = parse_bool(value) {
break visitor.visit_bool(boolean);
Expand Down Expand Up @@ -1293,11 +1316,14 @@ impl<'de, 'document> de::Deserializer<'de> for &mut DeserializerFromEvents<'de,
where
V: Visitor<'de>,
{
let tagged_already = self.current_enum.is_some();
let (next, mark) = self.next_event_mark()?;
loop {
match next {
Event::Alias(mut pos) => break self.jump(&mut pos)?.deserialize_i64(visitor),
Event::Scalar(scalar) if scalar.style == ScalarStyle::Plain => {
Event::Scalar(scalar)
if is_plain_or_tagged_literal_scalar(Tag::INT, scalar, tagged_already) =>
{
if let Ok(value) = str::from_utf8(&scalar.value) {
if let Some(int) = parse_signed_int(value, i64::from_str_radix) {
break visitor.visit_i64(int);
Expand All @@ -1315,11 +1341,14 @@ impl<'de, 'document> de::Deserializer<'de> for &mut DeserializerFromEvents<'de,
where
V: Visitor<'de>,
{
let tagged_already = self.current_enum.is_some();
let (next, mark) = self.next_event_mark()?;
loop {
match next {
Event::Alias(mut pos) => break self.jump(&mut pos)?.deserialize_i128(visitor),
Event::Scalar(scalar) if scalar.style == ScalarStyle::Plain => {
Event::Scalar(scalar)
if is_plain_or_tagged_literal_scalar(Tag::INT, scalar, tagged_already) =>
{
if let Ok(value) = str::from_utf8(&scalar.value) {
if let Some(int) = parse_signed_int(value, i128::from_str_radix) {
break visitor.visit_i128(int);
Expand Down Expand Up @@ -1358,11 +1387,14 @@ impl<'de, 'document> de::Deserializer<'de> for &mut DeserializerFromEvents<'de,
where
V: Visitor<'de>,
{
let tagged_already = self.current_enum.is_some();
let (next, mark) = self.next_event_mark()?;
loop {
match next {
Event::Alias(mut pos) => break self.jump(&mut pos)?.deserialize_u64(visitor),
Event::Scalar(scalar) if scalar.style == ScalarStyle::Plain => {
Event::Scalar(scalar)
if is_plain_or_tagged_literal_scalar(Tag::INT, scalar, tagged_already) =>
{
if let Ok(value) = str::from_utf8(&scalar.value) {
if let Some(int) = parse_unsigned_int(value, u64::from_str_radix) {
break visitor.visit_u64(int);
Expand All @@ -1380,11 +1412,14 @@ impl<'de, 'document> de::Deserializer<'de> for &mut DeserializerFromEvents<'de,
where
V: Visitor<'de>,
{
let tagged_already = self.current_enum.is_some();
let (next, mark) = self.next_event_mark()?;
loop {
match next {
Event::Alias(mut pos) => break self.jump(&mut pos)?.deserialize_u128(visitor),
Event::Scalar(scalar) if scalar.style == ScalarStyle::Plain => {
Event::Scalar(scalar)
if is_plain_or_tagged_literal_scalar(Tag::INT, scalar, tagged_already) =>
{
if let Ok(value) = str::from_utf8(&scalar.value) {
if let Some(int) = parse_unsigned_int(value, u128::from_str_radix) {
break visitor.visit_u128(int);
Expand All @@ -1409,11 +1444,14 @@ impl<'de, 'document> de::Deserializer<'de> for &mut DeserializerFromEvents<'de,
where
V: Visitor<'de>,
{
let tagged_already = self.current_enum.is_some();
let (next, mark) = self.next_event_mark()?;
loop {
match next {
Event::Alias(mut pos) => break self.jump(&mut pos)?.deserialize_f64(visitor),
Event::Scalar(scalar) if scalar.style == ScalarStyle::Plain => {
Event::Scalar(scalar)
if is_plain_or_tagged_literal_scalar(Tag::FLOAT, scalar, tagged_already) =>
{
if let Ok(value) = str::from_utf8(&scalar.value) {
if let Some(float) = parse_f64(value) {
break visitor.visit_f64(float);
Expand Down

0 comments on commit bfff6c1

Please sign in to comment.