Skip to content

Commit 36d6fd3

Browse files
committed
Support string prefix parsing
This adds support for parsing json from the prefix of a string. It does so via two small api additions: - Deserializer now has the `into_reader` associated function, which consume the deserializer and returns reader it has been using. - StrRead and SliceRead now have the `index` assocaited function, which reports the byte index of the data which will be read next. These can be used to parse a single value (or multiple values) from an input string or buffer, and then recover the next byte position from the reader. It allows the json parser to be easily integrated into an outer parser, where the JSON data is sitting inside some larger non-JSON context.
1 parent a15bd09 commit 36d6fd3

File tree

3 files changed

+34
-0
lines changed

3 files changed

+34
-0
lines changed

src/de.rs

+5
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ where
6060
disable_recursion_limit: false,
6161
}
6262
}
63+
64+
/// Consume the deserializer and return its inner reader.
65+
pub fn into_reader(self) -> R {
66+
self.read
67+
}
6368
}
6469

6570
#[cfg(feature = "std")]

src/read.rs

+10
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,11 @@ impl<'a> SliceRead<'a> {
412412
}
413413
}
414414

415+
/// Get the byte index of the data that will be read next
416+
pub fn index(&self) -> usize {
417+
self.index
418+
}
419+
415420
fn position_of_index(&self, i: usize) -> Position {
416421
let mut position = Position { line: 1, column: 0 };
417422
for ch in &self.slice[..i] {
@@ -623,6 +628,11 @@ impl<'a> StrRead<'a> {
623628
data: s,
624629
}
625630
}
631+
632+
/// Get the byte index of the data that will be read next
633+
pub fn index(&self) -> usize {
634+
self.delegate.index()
635+
}
626636
}
627637

628638
impl<'a> private::Sealed for StrRead<'a> {}

tests/test.rs

+19
Original file line numberDiff line numberDiff line change
@@ -2407,3 +2407,22 @@ fn hash_positive_and_negative_zero() {
24072407
assert_eq!(hash(k1), hash(k2));
24082408
}
24092409
}
2410+
2411+
#[test]
2412+
fn parse_string_prefix() {
2413+
#[derive(PartialEq, Deserialize, Debug)]
2414+
struct S {
2415+
a: u32
2416+
}
2417+
2418+
let data = "{\"a\": 42} tail";
2419+
2420+
let mut de = serde_json::Deserializer::from_str(data);
2421+
let val = S::deserialize(&mut de).unwrap();
2422+
2423+
assert_eq!(val, S { a: 42 });
2424+
2425+
let str_read = de.into_reader();
2426+
let tail = &data[(str_read.index()..)];
2427+
assert_eq!(tail, " tail");
2428+
}

0 commit comments

Comments
 (0)