Skip to content

Commit c840b31

Browse files
committed
feat: Supprt parsing dotted keys
We support parsing a lot of expressions to help users to edit their toml document from real world code. One thing that was missing was dotted key parsing. Also, this will hopefully help with rust-lang/cargo#10176
1 parent eda875c commit c840b31

File tree

2 files changed

+30
-4
lines changed

2 files changed

+30
-4
lines changed

src/key.rs

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ impl Key {
4848
}
4949
}
5050

51+
/// Parse a TOML key expression
52+
///
53+
/// Unlike `"".parse<Key>()`, this supports dotted keys.
54+
pub fn parse(repr: &str) -> Result<Vec<Self>, parser::TomlError> {
55+
Self::try_parse_path(repr)
56+
}
57+
5158
pub(crate) fn with_repr_unchecked(mut self, repr: Repr) -> Self {
5259
self.repr = Some(repr);
5360
self
@@ -97,12 +104,12 @@ impl Key {
97104
self.decor.clear();
98105
}
99106

100-
fn try_parse(s: &str) -> Result<Key, parser::TomlError> {
107+
fn try_parse_simple(s: &str) -> Result<Key, parser::TomlError> {
101108
use combine::stream::position::{IndexPositioner, Positioner};
102109
use combine::EasyParser;
103110

104111
let b = s.as_bytes();
105-
let result = parser::key_parser().easy_parse(Stream::new(b));
112+
let result = parser::simple_key().easy_parse(Stream::new(b));
106113
match result {
107114
Ok((_, ref rest)) if !rest.input.is_empty() => Err(parser::TomlError::from_unparsed(
108115
(&rest.positioner
@@ -114,6 +121,24 @@ impl Key {
114121
Err(e) => Err(parser::TomlError::new(e, b)),
115122
}
116123
}
124+
125+
fn try_parse_path(s: &str) -> Result<Vec<Key>, parser::TomlError> {
126+
use combine::stream::position::{IndexPositioner, Positioner};
127+
use combine::EasyParser;
128+
129+
let b = s.as_bytes();
130+
let result = parser::key_path().easy_parse(Stream::new(b));
131+
match result {
132+
Ok((_, ref rest)) if !rest.input.is_empty() => Err(parser::TomlError::from_unparsed(
133+
(&rest.positioner
134+
as &dyn Positioner<usize, Position = usize, Checkpoint = IndexPositioner>)
135+
.position(),
136+
b,
137+
)),
138+
Ok((keys, _)) => Ok(keys),
139+
Err(e) => Err(parser::TomlError::new(e, b)),
140+
}
141+
}
117142
}
118143

119144
impl std::ops::Deref for Key {
@@ -158,7 +183,7 @@ impl FromStr for Key {
158183
/// if fails, tries as basic quoted key (surrounds with "")
159184
/// and then literal quoted key (surrounds with '')
160185
fn from_str(s: &str) -> Result<Self, Self::Err> {
161-
Key::try_parse(s)
186+
Key::try_parse_simple(s)
162187
}
163188
}
164189

src/parser/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ mod value;
1717

1818
pub use self::errors::TomlError;
1919
pub(crate) use self::key::is_unquoted_char;
20-
pub(crate) use self::key::simple_key as key_parser;
20+
pub(crate) use self::key::key as key_path;
21+
pub(crate) use self::key::simple_key;
2122
pub(crate) use self::value::value as value_parser;
2223

2324
use self::table::duplicate_key;

0 commit comments

Comments
 (0)