Can now handle FromStr.
[?]
Jul 2, 2021, 11:01 PM
QMBJ2BAZHDVFT2GHOOXRGNOEXUOQ7JAX5M7LCEEULDHKIHXX6YZQCDependencies
- [2]
N467KW7JRefactored (simplified) errors. - [3]
6ZJX2OQVFirst commit - [4]
TMYMF5L6temp - [5]
VDFODD2FAdded line to BadIndent error. - [6]
446EWE33Added key_into() function. - [7]
BRO5BHI2Added val() function to KeyTreeRef. - [8]
JUK3ONMUFixed comment parsing bug. - [9]
YJVNXWNHminor - [10]
K5VHGRGGAdd serialization.
Change contents
- file deletion: path.rs
use std::fmt;use std::cmp::Ordering;use std::fmt::Display;/// A KeyPath it used to follow keys into a keytree.#[derive(Clone, Eq, Hash, PartialEq)]pub(crate) struct KeyPath(pub Vec<String>);impl KeyPath {// pub (crate) fn new() -> Self {// KeyPath(Vec::new())// }// pub (crate) fn truncate(&mut self, len: usize) {// self.0.truncate(len);// }// pub (crate) fn append(&mut self, other: &mut KeyPath) {// self.0.append(&mut other.0);// }// pub (crate) fn len(&self) -> usize {// self.0.len()// }pub(crate) fn from_str(s: &str) -> Self {let v = s.split(':').filter(|s| !s.is_empty()).map(|s| String::from(s)).collect::<Vec<String>>();KeyPath(v)}}impl fmt::Debug for KeyPath {fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {write!(f, "{}", self.to_string())}}impl Display for KeyPath {fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {for (i, segment) in self.0.iter().enumerate() {write!(f, "{}", segment)?;if i < self.0.len() - 1 { write!(f, "::")? };};Ok(())}}impl Ord for KeyPath {fn cmp(&self, other: &Self) -> Ordering {for n in 0..self.0.len() {match self.0[n].cmp(&other.0[n]) {Ordering::Less => return Ordering::Less,Ordering::Greater => return Ordering::Greater,Ordering::Equal => {},}}Ordering::Equal}}impl PartialOrd for KeyPath {fn partial_cmp(&self, other: &Self) -> Option<Ordering> {Some(self.0.cmp(&other.0))}}//! A path such as `hobbit::friend`, used to select a key in//! the tree. - file deletion: into.rs
use core::convert::TryInto;use core::num::{NonZeroI128,NonZeroI16,NonZeroI32,NonZeroI64,NonZeroI8,NonZeroIsize,NonZeroU128,NonZeroU16,NonZeroU32,NonZeroU64,NonZeroU8,NonZeroUsize,};use crate::{KeyTreeRef, Token};use crate::Result;// use std::iter::FromIterator;use std::net::{IpAddr,Ipv4Addr,Ipv6Addr,SocketAddr,SocketAddrV4,SocketAddrV6,};use std::path::PathBuf;use std::str::FromStr;impl<'a> KeyTreeRef<'a> {pub fn from_str<T: FromStr>(&self, into_type: &str) -> Result<T> {match self.top_token() {Token::KeyValue {next,value,..} => {match next {None => {match T::from_str(value) {Err(_) => {},Ok(t) => Ok(t),}}}},}}}impl<'a> TryInto<IpAddr> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<IpAddr> {self.from_str("IP address")}}impl<'a> TryInto<SocketAddr> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<SocketAddr> {self.from_str("socket address")}}impl<'a> TryInto<bool> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<bool> {self.from_str("bool")}}impl<'a> TryInto<char> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<char> {self.from_str("char")}}impl<'a> TryInto<f32> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<f32> {self.from_str("f32")}}impl<'a> TryInto<f64> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<f64> {self.from_str("f64")}}impl<'a> TryInto<i128> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<i128> {self.from_str("i128")}}impl<'a> TryInto<i16> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<i16> {self.from_str("i16")}}impl<'a> TryInto<i32> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<i32> {self.from_str("i32")}}impl<'a> TryInto<i64> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<i64> {self.from_str("i64")}}impl<'a> TryInto<i8> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<i8> {self.from_str("i8")}}impl<'a> TryInto<isize> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<isize> {self.from_str("isize")}}impl<'a> TryInto<u128> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<u128> {self.from_str("u128")}}impl<'a> TryInto<u16> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<u16> {self.from_str("u16")}}impl<'a> TryInto<u32> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<u32> {self.from_str("u32")}}impl<'a> TryInto<u64> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<u64> {self.from_str("u64")}}impl<'a> TryInto<u8> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<u8> {self.from_str("u8")}}impl<'a> TryInto<usize> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<usize> {self.from_str("usize")}}impl<'a> TryInto<Ipv4Addr> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<Ipv4Addr> {self.from_str("IPv4 address")}}impl<'a> TryInto<Ipv6Addr> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<Ipv6Addr> {self.from_str("IPv6 address")}}impl<'a> TryInto<SocketAddrV4> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<SocketAddrV4> {self.from_str("IPv4 address")}}impl<'a> TryInto<SocketAddrV6> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<SocketAddrV6> {self.from_str("IPv6 address")}}impl<'a> TryInto<NonZeroI128> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<NonZeroI128> {self.from_str("non-zero i128")}}impl<'a> TryInto<NonZeroI16> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<NonZeroI16> {self.from_str("non-zero i16")}}impl<'a> TryInto<NonZeroI32> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<NonZeroI32> {self.from_str("non-zero i32")}}impl<'a> TryInto<NonZeroI64> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<NonZeroI64> {self.from_str("non-zero i64")}}impl<'a> TryInto<NonZeroI8> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<NonZeroI8> {self.from_str("non-zero i8")}}impl<'a> TryInto<NonZeroIsize> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<NonZeroIsize> {self.from_str("non-zero isize")}}impl<'a> TryInto<NonZeroU128> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<NonZeroU128> {self.from_str("non-zero u128")}}impl<'a> TryInto<NonZeroU16> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<NonZeroU16> {self.from_str("non-zero u16")}}impl<'a> TryInto<NonZeroU32> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<NonZeroU32> {self.from_str("non-zero u32")}}impl<'a> TryInto<NonZeroU64> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<NonZeroU64> {self.from_str("non-zero u64")}}impl<'a> TryInto<NonZeroU8> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<NonZeroU8> {self.from_str("non-zero u8")}}impl<'a> TryInto<NonZeroUsize> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<NonZeroUsize> {self.from_str("non-zero usize")}}impl<'a> TryInto<PathBuf> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<PathBuf> {self.from_str("path")}}impl<'a> TryInto<String> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<String> {self.from_str("string")}}Token::Key { .. } => Err(expected_keyvalue_found_key()),Err(failed_to_parse_value(&self.top_token().to_string(),self.top_token().line(),))Some(i) => Err(expected_unique_found_multi(&String::from("todo"), *i)),use crate::error::Error;use crate::error::{expected_unique_found_multi,expected_keyvalue_found_key,failed_to_parse_value,};//! Conversions from the value of a key/value pair.//!//! Conversions can be implemented by the client.//! `from_str` is a helper function that takes a description//! of the type being converted into, for use in error//! messages.//!//! ```//! impl<'a> TryInto<f32> for KeyTreeRef<'a> {//! type Error = Error;//!//! fn try_into(self) -> Result<f32> {//! self.from_str("f32")//! }//! }//! ``` - replacement in src/parser.rs at line 4
use crate::builder::{Parents, SNSibs};use crate::builder::{Parents, SameNameSibs}; - replacement in src/parser.rs at line 77
snsibs: SNSibs,snsibs: SameNameSibs, - replacement in src/parser.rs at line 87
snsibs: SNSibs::new(),snsibs: SameNameSibs::new(), - replacement in src/parser.rs at line 379
&token_str.to_string()&token_str.to_string(),line + 1, - edit in src/lib.rs at line 1
// #![deny(missing_docs)] - edit in src/lib.rs at line 5
use std::fmt::Display; - edit in src/lib.rs at line 11
cannot_resolve_token_with_siblings, - edit in src/lib.rs at line 14
expected_keyvalue_found_key,expected_unique_keyvalue_found_multi,expected_unique_keyvalue_found_none, - edit in src/lib.rs at line 19
first_segment_mismatch,keypath_extends_beyond_keyvalue,keypath_segment_does_not_match_key, - edit in src/lib.rs at line 24
use crate::path::KeyPath; - edit in src/lib.rs at line 28
pub mod into; - edit in src/lib.rs at line 29
pub(crate) mod path; - edit in src/lib.rs at line 32
// There are three classes of behaviour, depending on whether the segment is the first, mid, or// last, so we classify these on construction./// A KeyPath it used to follow keys into a keytree.#[derive(Clone, Debug, Eq, Hash, PartialEq)]pub struct KeyPath {segments: Vec<String>,counter: usize,}impl KeyPath {pub (crate) fn segment(&self) -> String {self.segments[self.counter].clone()}pub (crate) fn is_last(&self) -> bool {self.counter == self.segments.len() - 2} - edit in src/lib.rs at line 53
pub (crate) fn advance(&mut self) {self.counter += 1;if self.counter >= self.segments.len() {println!("Keypath has exceeded end.");panic!()};}pub (crate) fn parent_segment(&self) -> String {self.segments[self.counter].clone()}pub (crate) fn child_segment(&self) -> String {self.segments[self.counter + 1].clone()}pub(crate) fn from_str(s: &str) -> Self {let v = s.split(':').filter(|s| !s.is_empty()).map(|s| String::from(s)).collect::<Vec<String>>();KeyPath {segments: v,counter: 0,}}}impl Display for KeyPath {fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {let mut s = String::new();for segment in &self.segments {s.push_str(&segment);s.push_str("::");}s.pop();s.pop();write!(f, "{}", s)}} - replacement in src/lib.rs at line 121
pub fn get_child(&self, key: &str) -> Option<usize> {pub fn key(&self) -> &'a str { - replacement in src/lib.rs at line 123
Token::KeyValue {..} => None,Token::Key { children, .. } => {children.iter().find(|(k, _)| &key == k).map(|(_, ix)| *ix)},Token::Key {key, ..} => key,Token::KeyValue {key, ..} => key, - replacement in src/lib.rs at line 128
pub fn key(&self) -> &'a str {// Will panic if called on a Token::Key. Always check before invoking this function.pub fn value(&self) -> &'a str { - replacement in src/lib.rs at line 131
Token::Key {key, ..} => key,Token::KeyValue {key, ..} => key,} }Token::Key {..} => panic!(),Token::KeyValue { value, ..} => value,}} - replacement in src/lib.rs at line 160
Token::KeyValue {..}=> { panic!() },Token::KeyValue {..} => { panic!() }, - edit in src/lib.rs at line 199
pub fn siblings(&self, index: usize) -> Vec<usize> {let token = self.tokens[index].clone();let mut v = vec!(index);let mut tok = token;while let Some(ix) = tok.next() {v.push(ix);tok = self.tokens[ix].clone();}v} - edit in src/lib.rs at line 212
- edit in src/lib.rs at line 222
}// Return child of the top token. If the top token is a Token::KeyValue then panic.pub (crate) fn top_child(&self, key: &str) -> Option<usize> {let top_token = self.top_token();match top_token {Token::KeyValue {..} => panic!(),Token::Key { children, .. } => {for (k, ix) in children {if &key == k {return Some(*ix)}}return None},} - replacement in src/lib.rs at line 246
fn next(&mut self) -> Option<()> {match self.top_token().next() {Some(ix) => {self.1 = ix;Some(())pub (crate) fn assert_top_token_is_keyvalue(&self) -> Result<()> {match self.top_token() {Token::KeyValue {..} => Ok(()),Token::Key { key, line, .. } => {Err(expected_keyvalue_found_key(&format!("{}:", key),*line,)) - edit in src/lib.rs at line 255
None => None, - replacement in src/lib.rs at line 258
fn peek(&self) -> Option<()> {match self.top_token().next() {Some(_) => Some(()),None => None,pub (crate) fn assert_top_token_has_no_siblings(&self) -> Result<()> {if self.top_token().next().is_none() {Ok(())} else {Err(cannot_resolve_token_with_siblings(&self.top_token().to_string(),self.top_token().line(),)) - replacement in src/lib.rs at line 269
pub fn assert_unique_top_token(&self) -> Result<()> {match self.peek() {None => Ok(()),_ => Err(expected_unique_token_found_multi()),pub (crate) fn assert_top_token_is_segment(&self, parent_segment: &str) -> Result<()> {if self.top_token().key() == parent_segment {Ok(())} else {Err(first_segment_mismatch(&self.top_token().to_string(),self.top_token().line(),parent_segment,)) - edit in src/lib.rs at line 289
// pub fn keyvalue_into<T>(&self) -> Result<T>// where// T: FromStr// {// match T::from_str(self.top_value().value) {// Ok(t) => Ok(t),// Err(err) => {// Err(failed_to_parse_value(// &format!("{}: {}", key, value),// kt.1,// ))// },// }// } - replacement in src/lib.rs at line 290
pub fn val<T>(&self, key_path: &str) -> Result<T>wherepub fn keyvalue_into<T>(&self) -> Result<T>where - edit in src/lib.rs at line 293
{self.assert_top_token_is_keyvalue()?;let token = self.top_token();T::from_str(token.value()).map_err(|_| failed_to_parse_value(&token.to_string(), token.line()))}pub fn opt_at<T>(&self, key_path: &str) -> Result<Option<T>>where - replacement in src/lib.rs at line 307[3.680]→[3.680:954](∅→∅),[3.954]→[2.2493:2665](∅→∅),[2.2665]→[3.1149:1190](∅→∅),[3.1149]→[3.1149:1190](∅→∅),[3.1190]→[3.23246:23261](∅→∅),[3.23246]→[3.23246:23261](∅→∅),[3.23261]→[2.2666:2725](∅→∅)
let kt = self.recurse(&path)?;kt.assert_unique_top_token()?;match kt.top_token() {Token::KeyValue { key, value, .. } => {match T::from_str(value) {Ok(t) => Ok(t),Err(err) => {Err(failed_to_parse_value(&format!("{}: {}", key, value),kt.1,))},}},_ => Err(expected_unique_token_found_multi()),let kts = self.resolve_path(&path)?;match kts.len() {0 => Ok(None),1 => Ok(Some(kts[0].key_into()?)),_ => Err(expected_unique_keyvalue_found_multi(key_path)), - edit in src/lib.rs at line 315
pub fn at<T>(&self, key_path: &str) -> Result<T>whereKeyTreeRef<'a>: TryInto<T>,KeyTreeRef<'a>: TryInto<T, Error = Error>,{let path = KeyPath::from_str(key_path);let kts = self.resolve_path(&path)?;match kts.len() {0 => Err(expected_unique_keyvalue_found_none(key_path)),1 => Ok(kts[0].key_into()?),_ => Err(expected_unique_keyvalue_found_multi(key_path)),}} - replacement in src/lib.rs at line 329[3.1257]→[3.4102:4213](∅→∅),[3.23311]→[3.4102:4213](∅→∅),[3.4213]→[3.23422:23475](∅→∅),[3.23422]→[3.23422:23475](∅→∅)
/// Coerces the value at key_path from a string to the/// receiver type. See top page for an example.pub fn at<T>(&self, key_path: &str) -> Result<T>pub fn value<T>(&self, key_path: &str) -> Result<T>whereT: FromStr,{let path = KeyPath::from_str(key_path);let kts = self.resolve_path(&path)?;match kts.len() {0 => Err(expected_unique_keyvalue_found_none(key_path)),1 => Ok(kts[0].keyvalue_into()?),_ => Err(expected_unique_keyvalue_found_multi(key_path)),}}pub fn opt_value<T>(&self, key_path: &str) -> Result<Option<T>> - edit in src/lib.rs at line 344
T: FromStr,{let path = KeyPath::from_str(key_path);let kts = self.resolve_path(&path)?;match kts.len() {0 => Ok(None),1 => Ok(Some(kts[0].keyvalue_into()?)),_ => Err(expected_unique_keyvalue_found_multi(key_path)),}}pub fn vec_value<T>(&self, key_path: &str) -> Result<Vec<T>>whereT: FromStr,{let path = KeyPath::from_str(key_path);let kts = self.resolve_path(&path)?;let mut v = Vec::new();for kt in kts {v.push(kt.keyvalue_into()?)}Ok(v)}pub fn vec_at<T>(&self, key_path: &str) -> Result<Vec<T>>where - replacement in src/lib.rs at line 375
let kt = self.recurse(&path)?;kt.assert_unique_top_token()?;kt.try_into()let kts = self.resolve_path(&path)?;let mut v = Vec::new();for kt in kts {v.push(kt.key_into()?)}Ok(v) - replacement in src/lib.rs at line 384
// /// Coerces the value at key_path from a string to// /// Some` of the receiver type, or None if there is// /// nothing at key_path. See top page for example.// pub fn op<T>(&self, key_path: &str) -> Result<Option<T>>// where// KeyTreeRef<'a>: TryInto<T>,// KeyTreeRef<'a>: TryInto<T, Error = Error>,// {// let path = KeyPath::from_str(key_path);// let kt = match self.op_recurse(&path)? {// Some(kt) => kt,// None => return Ok(None),// };// Takes a `KeyPath` and follows it through the tree, returning a Vec of `KeyTreeRef`s.pub fn resolve_path(self, key_path: &KeyPath) -> Result<Vec<Self>> { - replacement in src/lib.rs at line 387
// // Check that top token is unique.// match kt.top_token().next() {// None => {// // re-wrap// match kt.try_into() {// Ok(t_item) => Ok(Some(t_item)),// Err(e) => Err(e),// }// },// _ => Err(expected_unique_token_found_multi()),// }// }// Keypaths are unique and keypaths cannot resolve on multiple siblings. We keep following// a path until we run out of segments. The we find the siblings of that unique path. - replacement in src/lib.rs at line 390
// /// Coerces the values at key_path from strings to a `Vec` of the receiver// /// type, or an empty `Vec` if there is nothing at key_path. See top page// /// for example.// pub fn vec<T>(&self, key_path: &str) -> Result<Vec<T>>// where// KeyTreeRef<'a>: TryInto<T>,// KeyTreeRef<'a>: TryInto<T, Error = Error>,// {// let path = KeyPath::from_str(key_path);// match self.op_recurse(&path)? {// Some(mut kt) => {match (self.top_token(), key_path.is_last()) { - replacement in src/lib.rs at line 392
// let mut v = vec!(kt.clone().try_into()?);//// while let Some(_) = kt.next() {// v.push(kt.clone().try_into()?);// };// Ok(v)// },// None => Ok(Vec::new()),// }// }(Token::Key {..}, true) => {let parent_segment = key_path.parent_segment();let child_segment = key_path.child_segment();self.assert_top_token_is_segment(&parent_segment)?; - replacement in src/lib.rs at line 399[3.25528]→[3.25528:25576](∅→∅),[3.25576]→[3.4689:4789](∅→∅),[3.4789]→[3.25654:25730](∅→∅),[3.25654]→[3.25654:25730](∅→∅)
// Follow the path and return the sub-tree.pub (crate) fn recurse(&self,path: &KeyPath) -> Result<KeyTreeRef<'a>>{let mut kt = (*self).clone();let mut iter = path.0.iter();// Get the child, and then get the siblings of that child - replacement in src/lib.rs at line 401
// Check that the first segment in the path equals the key of the// current top token.match iter.next() {Some(key) => {if key != self.top_token().key() {return Err(bad_first_segment(&self.top_token().to_string(),self.top_token().line(),&path.to_string(),))match self.top_child(&child_segment) {None => Ok(Vec::new()),Some(ix) => {let mut v = Vec::new();let mut kt = self.clone();for sibling_ix in self.0.siblings(ix) {kt.set_cursor(sibling_ix);v.push(kt);}Ok(v)}, - edit in src/lib.rs at line 414[3.26225]→[2.4703:4753](∅→∅),[2.4753]→[3.26295:26508](∅→∅),[3.26295]→[3.26295:26508](∅→∅),[3.26508]→[2.4754:4862](∅→∅),[2.4862]→[3.26577:26783](∅→∅),[3.4905]→[3.26577:26783](∅→∅),[3.26577]→[3.26577:26783](∅→∅),[3.26783]→[2.4863:5153](∅→∅),[2.5153]→[3.5212:5246](∅→∅),[3.5212]→[3.5212:5246](∅→∅),[3.5246]→[2.5154:5184](∅→∅),[2.5184]→[3.27076:27189](∅→∅),[3.5277]→[3.27076:27189](∅→∅),[3.27076]→[3.27076:27189](∅→∅)
None => { return Err(empty_path()) },};// Iterate through the rest of the path and follow the children.while let Some(key) = iter.next() {match kt.top_token() {Token::KeyValue {..} => {return Err(expected_key_found_keyvalue())},token @ Token::Key {..} => {match token.get_child(key) {Some(ix) => { kt.set_cursor(ix) },None => {return Err(no_child_with_segment(&self.top_token().to_string(),&self.top_token().line().to_string(),&key.to_string(),))},}}}};Ok(kt)} - replacement in src/lib.rs at line 415
// pub (crate) fn op_recurse(// &self,// path: &KeyPath) -> Result<Option<KeyTreeRef<'a>>>// {// match self.recurse(path) {// Ok(kt) => Ok(Some(kt)),// Err(err) => {// match err.kind() {// ErrorKind::NoChildWithSegment(_, _, _)// | ErrorKind::Expected_key_found_keyvalue => {// Ok(None)// },// _ => Err(err),// }// }// }// }}(token @ Token::Key {..}, false) => { - replacement in src/lib.rs at line 417
#[cfg(test)]mod test {use std::convert::TryInto;let mut path = key_path.clone();let child_segment = path.child_segment();let parent_segment = path.parent_segment();self.assert_top_token_is_segment(&parent_segment)?; - replacement in src/lib.rs at line 423
use super::*;use crate::{KeyTree, KeyTreeRef};use crate::error::Error;use crate::path::KeyPath;// dbg!(&self);// dbg!(&path);// self.assert_top_token_has_no_siblings()?; - replacement in src/lib.rs at line 427
static HOBBITS: &'static str = r#"hobbit:name: Frodo Bagginsage: 60friends:hobbit:name: Bilbo Bagginsage: 111hobbit:name: Samwise Gamgeeage: 38nick: Sam"#;#[derive(Debug)]struct Hobbit {name: String,age: u32,friends: Vec<Hobbit>,nick: Option<String>,}impl<'a> TryInto<Hobbit> for KeyTreeRef<'a> {type Error = Error;fn try_into(self) -> Result<Hobbit> {Ok(Hobbit {name: self.at("hobbit::name")?,age: self.at("hobbit::age")?,friends: self.vec("hobbit::friends::hobbit")?,nick: self.op("hobbit::nick")?,// Get the child, and then call resolve on that child.match self.top_child(&child_segment) {None => {Ok(Vec::new()) // Option},Some(ix) => {let mut kt = self.clone();kt.set_cursor(ix);path.advance();kt.resolve_path(&path)},}},(Token::KeyValue { .. }, true) => {let mut kt = self.clone();let mut v = Vec::new();for sibling_ix in self.0.siblings(self.1) {kt.set_cursor(sibling_ix);v.push(kt); - replacement in src/lib.rs at line 450
)Ok(v)},(Token::KeyValue { key, value, line, .. }, false) => {dbg!();return Err(keypath_extends_beyond_keyvalue(&format!("{}: {}", key, value),*line,&key_path.to_string(),))}, - edit in src/lib.rs at line 462
}#[test]fn recurse() {let keytree = KeyTree::parse(HOBBITS).unwrap();let kt = keytree.to_ref();let kt2 = kt.recurse(&KeyPath::from_str("hobbit::age")).unwrap();assert_eq!(kt2.top_token().key(),"age");}#[test]fn at() {// let kt = KeyTree::parse(HOBBITS).unwrap();// let hobbit: Hobbit = kt.to_ref().try_into().unwrap();// assert_eq!(// hobbit.name,// "Frodo Baggins",// );// assert_eq!(// hobbit.nick,// None,// ); - edit in src/lib.rs at line 464
- edit in src/error.rs at line 6
#[derive(Debug)] - replacement in src/error.rs at line 17
pub fn expected_key_found_keyvalue() -> Error {Error(String::from("[01] Expected [key:] but found [key: value]."))pub fn bad_first_segment(token: &str, line: usize, segment: &str) -> Error {Error(format!("[01] line {}, token [{}]. Bad first segment [{}].",line,token,segment,)) - replacement in src/error.rs at line 26
pub fn expected_keyvalue_found_key() -> Error {Error(String::from("[02] Expected [key: value] but found [key:]."))pub fn bad_indent(token: &str, line: usize, indent: usize) -> Error {Error(format!("[02] line {}, token [{}]. Indentation of {} is incorrect.",line,token,indent,)) - replacement in src/error.rs at line 35[3.39074]→[2.6408:6480](∅→∅),[2.6480]→[3.2509:2537](∅→∅),[3.2509]→[3.2509:2537](∅→∅),[3.2537]→[2.6481:6588](∅→∅),[2.6588]→[3.2642:2689](∅→∅),[3.2642]→[3.2642:2689](∅→∅)
pub fn expected_unique_found_multi(token: &str, line: usize) -> Error {Error(format!("[03] usize {}, token {}. Expected unique token but found multiple tokens.",line,token.to_string(),))pub fn cannot_resolve_token_with_siblings(token: &str, line: usize) -> Error {Error(format!("[03] line {}, token [{}], Cannot resolve token with siblings.",line,token,)) - replacement in src/error.rs at line 43
pub fn expected_unique_token_found_multi() -> Error {Error(String::from("[04] Expected a unique token but found multiple."))pub fn colon_before_key() -> Error {Error(String::from("[03] Colon before key.")) - replacement in src/error.rs at line 47[3.43076]→[2.6589:6655](∅→∅),[2.6655]→[3.2904:2932](∅→∅),[3.2904]→[3.2904:2932](∅→∅),[3.2932]→[2.6656:6737](∅→∅),[2.6737]→[3.3011:3058](∅→∅),[3.3011]→[3.3011:3058](∅→∅)
pub fn failed_to_parse_value(token: &str, line: usize) -> Error {Error(format!("[05] usize {}, token {}. Failed to parse value.",line,token.to_string(),))pub fn empty_path() -> Error {Error(String::from("[04] Empty path."))}pub fn empty_string() -> Error {Error(String::from("[05] Keytree string is empty.")) - replacement in src/error.rs at line 55
pub fn no_child_with_segment(a: &str, b: &str, c: &str) -> Error {Error(format!("[06]"))pub fn expected_key_found_keyvalue(token: &str, line: usize) -> Error {Error(format!("[06] line {}, token [{}]. Expected [key:] but found [key: value].",line,token,))}pub fn expected_keyvalue_found_key(token: &str, line: usize) -> Error {Error(format!("[07] line {}, token [{}]. Expected [key: value] but found [key:].",line,token,))}pub fn expected_unique_found_multi(key_path: &str) -> Error {Error(format!("[08] keypath: [{}]. Expected unique token but found multiple tokens.",key_path,)) - replacement in src/error.rs at line 78
pub fn empty_string() -> Error {Error(String::from("String is empty."))pub fn expected_unique_keyvalue_found_multi(key_path: &str) -> Error {Error(format!("[09] keypath: [{}]. Expected unique [key: value] but found multiple tokens.",key_path,)) - replacement in src/error.rs at line 85
pub fn bad_indent(token: &str, line: usize, indent: usize) -> Error {pub fn expected_unique_keyvalue_found_none(key_path: &str) -> Error {Error(format!("[10] keypath: [{}]. Expected unique [key: value] but found none.",key_path,))}pub fn expected_unique_token_found_multi() -> Error { - replacement in src/error.rs at line 94[3.3356]→[3.3356:3373](∅→∅),[3.3373]→[2.6809:6881](∅→∅),[2.6881]→[3.3444:3462](∅→∅),[3.3444]→[3.3444:3462](∅→∅),[3.3462]→[2.6882:6901](∅→∅),[2.6901]→[3.3479:3509](∅→∅),[3.3479]→[3.3479:3509](∅→∅)
format!("[07] usize {}, token {}. Indentation of {} is incorrect.",line,token,indent,)String::from("[11] Expected a unique token but found multiple.") - edit in src/error.rs at line 98
pub fn failed_to_parse_value(token: &str, line: usize) -> Error {Error(format!("[12] line {}, token [{}]. Failed to parse value.",line,token,))} - replacement in src/error.rs at line 106
pub fn colon_before_key() -> Error {Error(String::from("Colon before key."))pub fn first_token_must_be_key(token: &str) -> Error {Error(format!("[13] token {}. First token must be [key:].",token,)) - replacement in src/error.rs at line 113
pub fn first_token_must_be_key(token: &str) -> Error {Error(String::from("First token must be [key:]."))pub fn first_segment_mismatch(token: &str, line: usize, key_path: &str) -> Error {Error(format!("[14] line {}, token [{}]. The first segment of [{}] does not match.",line,token,key_path,)) - replacement in src/error.rs at line 123
Error(String::from("Incomplete comment or key."))Error(format!("[15] line {}, token [{}]. Incomplete comment or key.",line,token,)) - replacement in src/error.rs at line 131
Error(String::from("Incomplete line."))Error(format!("[16] line {}, token [{}]. Incomplete line.",line,token,))}pub fn keypath_extends_beyond_keyvalue(token: &str, line: usize, key_path: &str) -> Error {Error(format!("[17] line {}, token [{}], keypath [{}]. Keypath extends beyond keyvalue.",line,token,key_path,))}pub fn keypath_must_have_two_or_more_segments(key_path: &str) -> Error {Error(format!( "[18] Keypath {} must have two or more segments.", key_path)) - replacement in src/error.rs at line 151
pub fn no_colon_after_key(token: &str) -> Error {Error(String::from("No colon after key."))pub fn keypath_segment_does_not_match_key(token: &str, segment: &str, line: usize) -> Error {Error(format!("[19] line {}, token [{}]. Keypath segment {} does not match key.",line,token,segment,)) - replacement in src/error.rs at line 159[3.4052]→[2.7243:7378](∅→∅),[2.7378]→[3.4136:4196](∅→∅),[3.4136]→[3.4136:4196](∅→∅),[3.229]→[3.45006:45016](∅→∅),[3.4196]→[3.45006:45016](∅→∅),[3.45006]→[3.45006:45016](∅→∅),[3.45016]→[2.7379:7385](∅→∅)
pub fn bad_first_segment(token: &str, line: usize, key_path: &str) -> Error {Error(format!("Bad first segment"))pub fn no_child_with_segment(token: &str, line: usize, key: &str) -> Error {Error(format!("[20] line {}, token [{}]. Failed to find key [{}]",line,token,key,)) - replacement in src/error.rs at line 169
pub fn non_root_has_zero_indent(token: &str, line: usize) -> Error {Error(String::from("Token other than root token as zero indent."))pub fn no_colon_after_key(token: &str, line: usize) -> Error {Error(format!("[21] line {}, token [{}], No colon after key.",line,token,)) - replacement in src/error.rs at line 178
Error(String::from("No space after key."))Error(String::from("[22] No space after key.")) - replacement in src/error.rs at line 182
Error(String::from("No tokens."))Error(String::from("[23] No tokens.")) - replacement in src/error.rs at line 185
pub fn empty_path() -> Error {Error(String::from("Empty path."))pub fn non_root_has_zero_indent(token: &str, line: usize) -> Error {Error(format!("[24] line {}, token [{}]. Token other than root token as zero indent.",line,token,)) - replacement in src/builder.rs at line 27
pub (crate) struct SNSibs(pub Vec<usize>);pub (crate) struct SameNameSibs(pub Vec<usize>); - replacement in src/builder.rs at line 29
impl SNSibs {impl SameNameSibs { - replacement in src/builder.rs at line 31
SNSibs(Vec::new())SameNameSibs(Vec::new()) - replacement in examples/hobbit/src/main.rs at line 31
name: self.val("hobbit::name")?,age: self.val("hobbit::age")?,friends: self.vec("hobbit::friends::hobbit")?,nick: self.op("hobbit::nick")?,name: self.value("hobbit::name")?,age: self.value("hobbit::age")?,friends: self.vec_at("hobbit::friends::hobbit")?,nick: self.opt_value("hobbit::nick")?,