Skip to content
This repository was archived by the owner on Sep 24, 2022. It is now read-only.

Commit 7c9b0a3

Browse files
est31alexcrichton
authored andcommitted
Support deserializing spanned keys (#333)
* Store key spans in the deserializer * Support deserializing spanned keys * Store key spans of the table header as well * Support nested table key spans as well
1 parent 029908c commit 7c9b0a3

File tree

3 files changed

+161
-36
lines changed

3 files changed

+161
-36
lines changed

src/de.rs

Lines changed: 87 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use crate::spanned;
2222
use crate::tokens::{Error as TokenError, Span, Token, Tokenizer};
2323

2424
/// Type Alias for a TOML Table pair
25-
type TablePair<'a> = (Cow<'a, str>, Value<'a>);
25+
type TablePair<'a> = ((Span, Cow<'a, str>), Value<'a>);
2626

2727
/// Deserializes a byte slice into a type.
2828
///
@@ -318,9 +318,16 @@ impl<'de, 'b> de::Deserializer<'de> for &'b mut Deserializer<'de> {
318318
}
319319
}
320320

321+
fn headers_equal<'a, 'b>(hdr_a: &[(Span, Cow<'a, str>)], hdr_b: &[(Span, Cow<'b, str>)]) -> bool {
322+
if hdr_a.len() != hdr_b.len() {
323+
return false;
324+
}
325+
hdr_a.iter().zip(hdr_b.iter()).all(|(h1, h2)| h1.1 == h2.1)
326+
}
327+
321328
struct Table<'a> {
322329
at: usize,
323-
header: Vec<Cow<'a, str>>,
330+
header: Vec<(Span, Cow<'a, str>)>,
324331
values: Option<Vec<TablePair<'a>>>,
325332
array: bool,
326333
}
@@ -351,7 +358,7 @@ impl<'de, 'b> de::MapAccess<'de> for MapVisitor<'de, 'b> {
351358
loop {
352359
assert!(self.next_value.is_none());
353360
if let Some((key, value)) = self.values.next() {
354-
let ret = seed.deserialize(StrDeserializer::new(key.clone()))?;
361+
let ret = seed.deserialize(StrDeserializer::spanned(key.clone()))?;
355362
self.next_value = Some((key, value));
356363
return Ok(Some(ret));
357364
}
@@ -366,7 +373,7 @@ impl<'de, 'b> de::MapAccess<'de> for MapVisitor<'de, 'b> {
366373
return false;
367374
}
368375
match t.header.get(..self.depth) {
369-
Some(header) => header == prefix,
376+
Some(header) => headers_equal(&header, &prefix),
370377
None => false,
371378
}
372379
})
@@ -382,9 +389,17 @@ impl<'de, 'b> de::MapAccess<'de> for MapVisitor<'de, 'b> {
382389
// Test to see if we're duplicating our parent's table, and if so
383390
// then this is an error in the toml format
384391
if self.cur_parent != pos {
385-
if self.tables[self.cur_parent].header == self.tables[pos].header {
392+
if headers_equal(
393+
&self.tables[self.cur_parent].header,
394+
&self.tables[pos].header,
395+
) {
386396
let at = self.tables[pos].at;
387-
let name = self.tables[pos].header.join(".");
397+
let name = self.tables[pos]
398+
.header
399+
.iter()
400+
.map(|k| k.1.to_owned())
401+
.collect::<Vec<_>>()
402+
.join(".");
388403
return Err(self.de.error(at, ErrorKind::DuplicateTable(name)));
389404
}
390405

@@ -408,7 +423,7 @@ impl<'de, 'b> de::MapAccess<'de> for MapVisitor<'de, 'b> {
408423
// decoding.
409424
if self.depth != table.header.len() {
410425
let key = &table.header[self.depth];
411-
let key = seed.deserialize(StrDeserializer::new(key.clone()))?;
426+
let key = seed.deserialize(StrDeserializer::spanned(key.clone()))?;
412427
return Ok(Some(key));
413428
}
414429

@@ -437,7 +452,7 @@ impl<'de, 'b> de::MapAccess<'de> for MapVisitor<'de, 'b> {
437452
match seed.deserialize(ValueDeserializer::new(v)) {
438453
Ok(v) => return Ok(v),
439454
Err(mut e) => {
440-
e.add_key_context(&k);
455+
e.add_key_context(&k.1);
441456
return Err(e);
442457
}
443458
}
@@ -458,7 +473,7 @@ impl<'de, 'b> de::MapAccess<'de> for MapVisitor<'de, 'b> {
458473
de: &mut *self.de,
459474
});
460475
res.map_err(|mut e| {
461-
e.add_key_context(&self.tables[self.cur - 1].header[self.depth]);
476+
e.add_key_context(&self.tables[self.cur - 1].header[self.depth].1);
462477
e
463478
})
464479
}
@@ -482,7 +497,10 @@ impl<'de, 'b> de::SeqAccess<'de> for MapVisitor<'de, 'b> {
482497
.iter()
483498
.enumerate()
484499
.skip(self.cur_parent + 1)
485-
.find(|&(_, table)| table.array && table.header == self.tables[self.cur_parent].header)
500+
.find(|&(_, table)| {
501+
let tables_eq = headers_equal(&table.header, &self.tables[self.cur_parent].header);
502+
table.array && tables_eq
503+
})
486504
.map(|p| p.0)
487505
.unwrap_or(self.max);
488506

@@ -560,9 +578,9 @@ impl<'de, 'b> de::Deserializer<'de> for MapVisitor<'de, 'b> {
560578
if table.header.len() == 0 {
561579
return Err(self.de.error(self.cur, ErrorKind::EmptyTableKey));
562580
}
563-
let name = table.header[table.header.len() - 1].to_owned();
581+
let name = table.header[table.header.len() - 1].1.to_owned();
564582
visitor.visit_enum(DottedTableDeserializer {
565-
name: name,
583+
name,
566584
value: Value {
567585
e: E::DottedTable(values),
568586
start: 0,
@@ -579,12 +597,27 @@ impl<'de, 'b> de::Deserializer<'de> for MapVisitor<'de, 'b> {
579597
}
580598

581599
struct StrDeserializer<'a> {
600+
span: Option<Span>,
582601
key: Cow<'a, str>,
583602
}
584603

585604
impl<'a> StrDeserializer<'a> {
605+
fn spanned(inner: (Span, Cow<'a, str>)) -> StrDeserializer<'a> {
606+
StrDeserializer {
607+
span: Some(inner.0),
608+
key: inner.1,
609+
}
610+
}
586611
fn new(key: Cow<'a, str>) -> StrDeserializer<'a> {
587-
StrDeserializer { key }
612+
StrDeserializer { span: None, key }
613+
}
614+
}
615+
616+
impl<'a, 'b> de::IntoDeserializer<'a, Error> for StrDeserializer<'a> {
617+
type Deserializer = Self;
618+
619+
fn into_deserializer(self) -> Self::Deserializer {
620+
self
588621
}
589622
}
590623

@@ -601,9 +634,31 @@ impl<'de> de::Deserializer<'de> for StrDeserializer<'de> {
601634
}
602635
}
603636

637+
fn deserialize_struct<V>(
638+
self,
639+
name: &'static str,
640+
fields: &'static [&'static str],
641+
visitor: V,
642+
) -> Result<V::Value, Error>
643+
where
644+
V: de::Visitor<'de>,
645+
{
646+
if name == spanned::NAME && fields == [spanned::START, spanned::END, spanned::VALUE] {
647+
if let Some(span) = self.span {
648+
return visitor.visit_map(SpannedDeserializer {
649+
phantom_data: PhantomData,
650+
start: Some(span.start),
651+
value: Some(StrDeserializer::new(self.key)),
652+
end: Some(span.end),
653+
});
654+
}
655+
}
656+
self.deserialize_any(visitor)
657+
}
658+
604659
serde::forward_to_deserialize_any! {
605660
bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq
606-
bytes byte_buf map struct option unit newtype_struct
661+
bytes byte_buf map option unit newtype_struct
607662
ignored_any unit_struct tuple_struct tuple enum identifier
608663
}
609664
}
@@ -690,21 +745,21 @@ impl<'de> de::Deserializer<'de> for ValueDeserializer<'de> {
690745
.iter()
691746
.filter_map(|key_value| {
692747
let (ref key, ref _val) = *key_value;
693-
if !fields.contains(&&(**key)) {
748+
if !fields.contains(&&*(key.1)) {
694749
Some(key.clone())
695750
} else {
696751
None
697752
}
698753
})
699-
.collect::<Vec<Cow<'de, str>>>();
754+
.collect::<Vec<_>>();
700755

701756
if !extra_fields.is_empty() {
702757
return Err(Error::from_kind(
703758
Some(self.value.start),
704759
ErrorKind::UnexpectedKeys {
705760
keys: extra_fields
706761
.iter()
707-
.map(|k| k.to_string())
762+
.map(|k| k.1.to_string())
708763
.collect::<Vec<_>>(),
709764
available: fields,
710765
},
@@ -943,7 +998,7 @@ impl<'de> de::MapAccess<'de> for InlineTableDeserializer<'de> {
943998
None => return Ok(None),
944999
};
9451000
self.next_value = Some(value);
946-
seed.deserialize(StrDeserializer::new(key)).map(Some)
1001+
seed.deserialize(StrDeserializer::spanned(key)).map(Some)
9471002
}
9481003

9491004
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
@@ -976,7 +1031,7 @@ impl<'de> de::EnumAccess<'de> for InlineTableDeserializer<'de> {
9761031
}
9771032
};
9781033

979-
seed.deserialize(StrDeserializer::new(key))
1034+
seed.deserialize(StrDeserializer::new(key.1))
9801035
.map(|val| (val, TableEnumDeserializer { value }))
9811036
}
9821037
}
@@ -1027,13 +1082,13 @@ impl<'de> de::VariantAccess<'de> for TableEnumDeserializer<'de> {
10271082
let tuple_values = values
10281083
.into_iter()
10291084
.enumerate()
1030-
.map(|(index, (key, value))| match key.parse::<usize>() {
1085+
.map(|(index, (key, value))| match key.1.parse::<usize>() {
10311086
Ok(key_index) if key_index == index => Ok(value),
10321087
Ok(_) | Err(_) => Err(Error::from_kind(
1033-
Some(value.start),
1088+
Some(key.0.start),
10341089
ErrorKind::ExpectedTupleIndex {
10351090
expected: index,
1036-
found: key.to_string(),
1091+
found: key.1.to_string(),
10371092
},
10381093
)),
10391094
})
@@ -1350,14 +1405,14 @@ impl<'a> Deserializer<'a> {
13501405
.as_ref()
13511406
.and_then(|values| values.last())
13521407
.map(|&(_, ref val)| val.end)
1353-
.unwrap_or_else(|| header.len());
1408+
.unwrap_or_else(|| header.1.len());
13541409
Ok((
13551410
Value {
13561411
e: E::DottedTable(table.values.unwrap_or_else(Vec::new)),
13571412
start,
13581413
end,
13591414
},
1360-
Some(header.clone()),
1415+
Some(header.1.clone()),
13611416
))
13621417
}
13631418
Some(_) => self.value().map(|val| (val, None)),
@@ -1672,14 +1727,11 @@ impl<'a> Deserializer<'a> {
16721727
Ok((span, ret))
16731728
}
16741729

1675-
fn table_key(&mut self) -> Result<Cow<'a, str>, Error> {
1676-
self.tokens
1677-
.table_key()
1678-
.map(|t| t.1)
1679-
.map_err(|e| self.token_error(e))
1730+
fn table_key(&mut self) -> Result<(Span, Cow<'a, str>), Error> {
1731+
self.tokens.table_key().map_err(|e| self.token_error(e))
16801732
}
16811733

1682-
fn dotted_key(&mut self) -> Result<Vec<Cow<'a, str>>, Error> {
1734+
fn dotted_key(&mut self) -> Result<Vec<(Span, Cow<'a, str>)>, Error> {
16831735
let mut result = Vec::new();
16841736
result.push(self.table_key()?);
16851737
self.eat_whitespace()?;
@@ -1705,7 +1757,7 @@ impl<'a> Deserializer<'a> {
17051757
/// * `values`: The `Vec` to store the value in.
17061758
fn add_dotted_key(
17071759
&self,
1708-
mut key_parts: Vec<Cow<'a, str>>,
1760+
mut key_parts: Vec<(Span, Cow<'a, str>)>,
17091761
value: Value<'a>,
17101762
values: &mut Vec<TablePair<'a>>,
17111763
) -> Result<(), Error> {
@@ -1714,7 +1766,7 @@ impl<'a> Deserializer<'a> {
17141766
values.push((key, value));
17151767
return Ok(());
17161768
}
1717-
match values.iter_mut().find(|&&mut (ref k, _)| *k == key) {
1769+
match values.iter_mut().find(|&&mut (ref k, _)| *k.1 == key.1) {
17181770
Some(&mut (
17191771
_,
17201772
Value {
@@ -2038,7 +2090,7 @@ enum Line<'a> {
20382090
header: Header<'a>,
20392091
array: bool,
20402092
},
2041-
KeyValue(Vec<Cow<'a, str>>, Value<'a>),
2093+
KeyValue(Vec<(Span, Cow<'a, str>)>, Value<'a>),
20422094
}
20432095

20442096
struct Header<'a> {
@@ -2058,13 +2110,13 @@ impl<'a> Header<'a> {
20582110
}
20592111
}
20602112

2061-
fn next(&mut self) -> Result<Option<Cow<'a, str>>, TokenError> {
2113+
fn next(&mut self) -> Result<Option<(Span, Cow<'a, str>)>, TokenError> {
20622114
self.tokens.eat_whitespace()?;
20632115

20642116
if self.first || self.tokens.eat(Token::Period)? {
20652117
self.first = false;
20662118
self.tokens.eat_whitespace()?;
2067-
self.tokens.table_key().map(|t| t.1).map(Some)
2119+
self.tokens.table_key().map(|t| t).map(Some)
20682120
} else {
20692121
self.tokens.expect(Token::RightBracket)?;
20702122
if self.array {

src/spanned.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ pub(crate) const VALUE: &str = "$__toml_private_value";
2828
/// assert_eq!(u.s.into_inner(), String::from("value"));
2929
/// }
3030
/// ```
31-
#[derive(Clone, Debug, PartialEq)]
31+
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
3232
pub struct Spanned<T> {
3333
/// The start range.
3434
start: usize,

0 commit comments

Comments
 (0)