diff --git a/src/key.rs b/src/key.rs index c9993499..d16df8b4 100644 --- a/src/key.rs +++ b/src/key.rs @@ -48,6 +48,13 @@ impl Key { } } + /// Parse a TOML key expression + /// + /// Unlike `"".parse()`, this supports dotted keys. + pub fn parse(repr: &str) -> Result, parser::TomlError> { + Self::try_parse_path(repr) + } + pub(crate) fn with_repr_unchecked(mut self, repr: Repr) -> Self { self.repr = Some(repr); self @@ -97,12 +104,12 @@ impl Key { self.decor.clear(); } - fn try_parse(s: &str) -> Result { + fn try_parse_simple(s: &str) -> Result { use combine::stream::position::{IndexPositioner, Positioner}; use combine::EasyParser; let b = s.as_bytes(); - let result = parser::key_parser().easy_parse(Stream::new(b)); + let result = parser::simple_key().easy_parse(Stream::new(b)); match result { Ok((_, ref rest)) if !rest.input.is_empty() => Err(parser::TomlError::from_unparsed( (&rest.positioner @@ -114,6 +121,24 @@ impl Key { Err(e) => Err(parser::TomlError::new(e, b)), } } + + fn try_parse_path(s: &str) -> Result, parser::TomlError> { + use combine::stream::position::{IndexPositioner, Positioner}; + use combine::EasyParser; + + let b = s.as_bytes(); + let result = parser::key_path().easy_parse(Stream::new(b)); + match result { + Ok((_, ref rest)) if !rest.input.is_empty() => Err(parser::TomlError::from_unparsed( + (&rest.positioner + as &dyn Positioner) + .position(), + b, + )), + Ok((keys, _)) => Ok(keys), + Err(e) => Err(parser::TomlError::new(e, b)), + } + } } impl std::ops::Deref for Key { @@ -158,7 +183,7 @@ impl FromStr for Key { /// if fails, tries as basic quoted key (surrounds with "") /// and then literal quoted key (surrounds with '') fn from_str(s: &str) -> Result { - Key::try_parse(s) + Key::try_parse_simple(s) } } diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 3e9e0e0e..1b9c0e0c 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -17,7 +17,8 @@ mod value; pub use self::errors::TomlError; pub(crate) use self::key::is_unquoted_char; -pub(crate) use self::key::simple_key as key_parser; +pub(crate) use self::key::key as key_path; +pub(crate) use self::key::simple_key; pub(crate) use self::value::value as value_parser; use self::table::duplicate_key;