Skip to content

Commit

Permalink
Merge #228
Browse files Browse the repository at this point in the history
228: Fix parsing of borrowed strings r=kvark a=caelunshun

The implementation of `deserialize_str` would incorrectly call `Visitor::visit_str` when it should have called `Visitor::visit_borrowed_str`. As per https://serde.rs/lifetimes.html#transient-borrowed-and-owned-data, `visit_borrowed_str` should be called when the lifetime of the deserialized string is that of the input.

This should not be a breaking change, because it only extends the lifetime of the deserialized string. The default implementation of `Visitor::visit_borrowed_str` forwards to `visit_str`, meaning that this commit only enables more flexibility.

I added a test in `tests/borrowed_str.rs` which demonstrates this behavior. Prior to this change, the test would fail.

Co-authored-by: caelunshun <caelunshun@gmail.com>
  • Loading branch information
bors[bot] and caelunshun committed May 8, 2020
2 parents 82d97ce + 999c0ad commit 0a7d83d
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/de/mod.rs
Expand Up @@ -287,7 +287,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
{
match self.bytes.string()? {
ParsedStr::Allocated(s) => visitor.visit_string(s),
ParsedStr::Slice(s) => visitor.visit_str(s),
ParsedStr::Slice(s) => visitor.visit_borrowed_str(s),
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/parse.rs
Expand Up @@ -567,7 +567,7 @@ impl<'a> Bytes<'a> {
}
}

pub fn string(&mut self) -> Result<ParsedStr<'_>> {
pub fn string(&mut self) -> Result<ParsedStr<'a>> {
if self.consume("\"") {
self.escaped_string()
} else if self.consume("r") {
Expand All @@ -577,7 +577,7 @@ impl<'a> Bytes<'a> {
}
}

fn escaped_string(&mut self) -> Result<ParsedStr<'_>> {
fn escaped_string(&mut self) -> Result<ParsedStr<'a>> {
use std::iter::repeat;

let (i, end_or_escape) = self
Expand Down Expand Up @@ -632,7 +632,7 @@ impl<'a> Bytes<'a> {
}
}

fn raw_string(&mut self) -> Result<ParsedStr<'_>> {
fn raw_string(&mut self) -> Result<ParsedStr<'a>> {
let num_hashes = self.bytes.iter().take_while(|&&b| b == b'#').count();
let hashes = &self.bytes[..num_hashes];
let _ = self.advance(num_hashes);
Expand Down
16 changes: 16 additions & 0 deletions tests/borrowed_str.rs
@@ -0,0 +1,16 @@
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
struct Borrowed<'a> {
value: &'a str,
}

const BORROWED: &str = "Borrowed(value: \"test\")";

#[test]
fn borrowed_str() {
assert_eq!(
ron::de::from_str(BORROWED).ok(),
Some(Borrowed { value: "test" })
);
}

0 comments on commit 0a7d83d

Please sign in to comment.