Improved error handling.

[?]
CrEcTsRjb1hHQjHuumqRfqdbVV4X58iLEubi4noaDPFa
Aug 2, 2021, 2:49 AM
UIKYQQM27ZMSXVMJ6U6XLEKLDUGFMCUKWLS6Z5DBMKDNJN4PDN6QC

Dependencies

  • [2] 3K5KIVGX Cleaned up docs.
  • [3] UQP5MBQK Cleaned up error handling.
  • [4] 6ZJX2OQV First commit
  • [5] VDFODD2F Added line to BadIndent error.
  • [6] INHPVRSE Made some functions pub (crate). Added opt_vec_value() fn. Improved docs.
  • [7] 446EWE33 Added key_into() function.
  • [8] JUK3ONMU Fixed comment parsing bug.
  • [9] TMYMF5L6 temp
  • [10] RLK4BBWU Updated pijul repo.
  • [11] N467KW7J Refactored (simplified) errors.
  • [12] QMBJ2BAZ Can now handle FromStr.
  • [13] GS7AO747 Fixed line_incomplete error.
  • [14] BRO5BHI2 Added val() function to KeyTreeRef.
  • [15] WPR2A6Y7 Fixed bug in parser. Added opt_vec_at() fn.

Change contents

  • replacement in src/parser.rs at line 5
    [4.45][4.0:278](),[4.2330][4.0:278]()
    use crate::error::Error;
    use crate::error::{
    bad_indent,
    colon_before_key,
    empty_string,
    first_token_must_be_key,
    incomplete_comment_or_key,
    incomplete_line,
    no_colon_after_key,
    no_space_after_key,
    no_tokens,
    non_root_has_zero_indent,
    };
    [4.45]
    [4.278]
    use crate::error::*;
  • replacement in src/parser.rs at line 33
    [4.475][4.475:528]()
    bad_indent(&token.to_string(), line, self.0)
    [4.475]
    [4.528]
    err(file!(), line!(), &format!("Bad indent of {} at line {}.", self.0, line))
  • replacement in src/parser.rs at line 110
    [4.4577][4.0:161]()
    Err(first_token_must_be_key(
    file!(),
    line!(),
    &token.to_string()
    ))
    [4.4577]
    [4.4660]
    Err(
    err(
    file!(), line!(),
    &format!("First token {} must be key.", &token),
    )
    )
  • replacement in src/parser.rs at line 157
    [4.6106][4.601:658](),[4.658][4.162:228](),[4.228][4.658:702](),[4.658][4.658:702](),[4.702][4.6219:6256](),[4.6219][4.6219:6256](),[4.6256][4.620:643]()
    return Err(non_root_has_zero_indent(
    file!(),
    line!(),
    &token.to_string(),
    token.line()
    ))
    [4.6106]
    [4.6280]
    return Err(
    err(
    file!(), line!(),
    &format!("Non-root token {} cannot have zero indent at line {}.",
    &token,
    token.line(),
    ),
    )
    )
  • replacement in src/parser.rs at line 168
    [3.1][3.1:133](),[3.133][4.6299:6364](),[4.6299][4.6299:6364]()
    // TODO: Check indentation. The following line will error if indent suddenly shifts
    // from 1 to 3.
    let parent_ix = self.parents.parent(indent - 1);
    [3.1]
    [4.6364]
    let parent_ix = match self.parents.parent(indent - 1) {
    Some(ix) => ix,
    None => { return Err(
    err(
    file!(), line!(),
    &format!("Unexpected indent at line {}.", token.line()),
    )
    )},
    };
  • replacement in src/parser.rs at line 221
    [4.8072][4.644:695]()
    if s == "" { return Err(empty_string()) };
    [4.8072]
    [4.8143]
    if s == "" { return Err(err(file!(), line!(), "Empty string.")) };
  • replacement in src/parser.rs at line 385
    [4.797][4.797:841](),[4.841][4.291:365](),[4.365][4.123:213](),[4.841][4.123:213]()
    no_colon_after_key(
    file!(),
    line!(),
    &token_str.to_string(),
    line + 1,
    [4.797]
    [4.972]
    err(
    file!(), line!(),
    &format!("No colon after key {} at line {}.", &token_str, line + 1),
  • replacement in src/parser.rs at line 394
    [4.898][4.880:931](),[4.931][4.366:440](),[4.440][4.931:1021](),[4.931][4.931:1021]()
    incomplete_comment_or_key(
    file!(),
    line!(),
    &token_str.to_string(),
    line + 1,
    [4.898]
    [4.1175]
    err(
    file!(), line!(),
    &format!("Incomplete comment of key {} at {}.", &token_str, line + 1),
  • replacement in src/parser.rs at line 406
    [4.533][4.533:752]()
    return Err(no_space_after_key(
    file!(),
    line!(),
    &token_str.to_string(),
    line,
    ));
    [4.533]
    [4.14046]
    return Err(
    err(
    file!(), line!(),
    &format!("No space after key {} at line {}.", &token_str, line),
    )
    );
  • replacement in src/parser.rs at line 419
    [4.1010][4.1010:1051](),[4.1051][4.753:827](),[4.827][4.1077:1159](),[4.1051][4.1077:1159]()
    incomplete_line(
    file!(),
    line!(),
    &String::from("/"),
    line,
    [4.1010]
    [4.1485]
    err(
    file!(), line!(),
    &format!("Incomplete line {} at {}.", &String::from("/"), line),
  • replacement in src/parser.rs at line 429
    [4.1107][4.1107:1148](),[4.1148][4.828:902](),[4.902][4.1160:1246](),[4.1148][4.1160:1246]()
    incomplete_line(
    file!(),
    line!(),
    &token_str.to_string(),
    line,
    [4.1107]
    [4.1679]
    err(
    file!(), line!(),
    &format!("Incomplete line {} at {}.", &token_str, line),
  • replacement in src/parser.rs at line 441
    [4.995][4.995:1211]()
    return Err(colon_before_key(
    file!(),
    line!(),
    &token_str.to_string(),
    line,
    ))
    [4.995]
    [4.14732]
    return Err(
    err(
    file!(), line!(),
    &format!("Colon before key {} at {}.", &token_str, line),
    )
    )
  • replacement in src/parser.rs at line 451
    [4.1304][4.1304:1520]()
    return Err(colon_before_key(
    file!(),
    line!(),
    &token_str.to_string(),
    line,
    ))
    [4.1304]
    [4.14905]
    return Err(
    err(
    file!(), line!(),
    &format!("Colon before key {} at {}.", &token_str, line),
    )
    )
  • replacement in src/parser.rs at line 461
    [4.1613][4.1613:1831]()
    return Err(no_space_after_key(
    file!(),
    line!(),
    &token_str.to_string(),
    line,
    ))
    [4.1613]
    [4.15040]
    return Err(
    err(
    file!(), line!(),
    &format!("No space after key {} at {}.", &token_str, line),
    )
    )
  • replacement in src/parser.rs at line 474
    [4.1924][4.1924:2142]()
    return Err(no_space_after_key(
    file!(),
    line!(),
    &token_str.to_string(),
    line,
    ))
    [4.1924]
    [4.15457]
    return Err(
    err(
    file!(), line!(),
    &format!("No space after key {} at line {}.", &token_str, line),
    )
    )
  • replacement in src/parser.rs at line 493
    [4.1411][4.1411:1458](),[4.1458][4.2143:2209](),[4.2209][4.1301:1379](),[4.1458][4.1301:1379]()
    incomplete_comment_or_key(
    file!(),
    line!(),
    &token_str.to_string(),
    line,
    [4.1411]
    [4.2548]
    err(
    file!(), line!(),
    &format!("Incomplete comment or key {} at line {}.", &token_str, line),
  • replacement in src/parser.rs at line 503
    [4.1506][4.1506:1543](),[4.1543][4.2210:2276](),[4.2276][4.1380:1458](),[4.1543][4.1380:1458]()
    incomplete_line(
    file!(),
    line!(),
    &token_str.to_string(),
    line,
    [4.1506]
    [4.2723]
    err(
    file!(), line!(),
    &format!("Incomplete line {} at {}.", &token_str, line)
  • replacement in src/parser.rs at line 558
    [4.17635][4.2277:2369]()
    Err(no_tokens(
    file!(),
    line!(),
    ))
    [4.17635]
    [4.17684]
    Err(err(file!(), line!(), "No tokens"))
  • replacement in src/lib.rs at line 435
    [4.3514][4.3514:3632]()
    Err(expected_keyvalue_found_key(
    &format!("{}:", key),
    *line,
    [4.3514]
    [4.3632]
    Err(err(
    file!(), line!(),
    &format!("Expected keyvalue found key {} at {}.",
    key,
    line,
    )
  • replacement in src/lib.rs at line 450
    [4.4148][4.4148:4308]()
    Err(first_segment_mismatch(
    &self.top_token().to_string(),
    self.top_token().line(),
    parent_segment,
    [4.4148]
    [4.4308]
    Err(err(file!(), line!(),
    &format!("First segment mismatch {} {} at {}.",
    &self.top_token(),
    parent_segment,
    self.top_token().line(),
    )
  • replacement in src/lib.rs at line 477
    [4.4509][3.477:556]()
    .map_err(|_| parse_value_failed(&token.to_string(), token.line()))
    [4.4509]
    [4.4591]
    .map_err(|_| err(file!(), line!(),
    &format!("Failed to parse {} at {}.",
    token,
    token.line(),
    )
    ))
  • replacement in src/lib.rs at line 496
    [4.4819][4.2426:2514]()
    _ => Err(expected_unique_keyvalue_found_multi(file!(), line!(), key_path)),
    [4.4819]
    [4.23294]
    _ => Err(err(
    file!(),
    line!(),
    &format!("Expected unique keyvalue found multi at {}.", key_path),
    )),
  • replacement in src/lib.rs at line 513
    [4.5165][4.2515:2602]()
    0 => Err(expected_unique_keyvalue_found_none(file!(), line!(), key_path)),
    [4.5165]
    [4.5234]
    0 => Err(err(
    file!(),
    line!(),
    &format!("Expected unique keyvalue found none at {}.", key_path),
    )),
  • replacement in src/lib.rs at line 519
    [4.5275][4.2603:2691]()
    _ => Err(expected_unique_keyvalue_found_multi(file!(), line!(), key_path)),
    [4.5275]
    [4.5345]
    _ => Err(err(
    file!(),
    line!(),
    &format!("Expected unique keyvalue found multi at {}.", key_path),
    )),
  • replacement in src/lib.rs at line 572
    [4.5574][4.2692:2779]()
    0 => Err(expected_unique_keyvalue_found_none(file!(), line!(), key_path)),
    [4.5574]
    [4.5643]
    0 => Err(err(
    file!(),
    line!(),
    &format!("Expected unique keyvalue found none at {}.", key_path),
    )),
  • replacement in src/lib.rs at line 578
    [4.5689][4.2780:2868]()
    _ => Err(expected_unique_keyvalue_found_multi(file!(), line!(), key_path)),
    [4.5689]
    [4.5759]
    _ => Err(err(
    file!(),
    line!(),
    &format!("Expected unique keyvalue found multi at {}.", key_path),
    )),
  • replacement in src/lib.rs at line 597
    [4.6069][4.2869:2957]()
    _ => Err(expected_unique_keyvalue_found_multi(file!(), line!(), key_path)),
    [4.6069]
    [4.6139]
    _ => Err(err(
    file!(),
    line!(),
    &format!("Expected unique keyvalue found multi at {}.", key_path),
    )),
  • replacement in src/lib.rs at line 619
    [4.1872][4.1872:2016]()
    return Err(expected_non_empty_collection(
    file!(),
    line!(),
    key_path
    ))
    [4.1872]
    [4.2016]
    return Err(
    err(file!(), line!(), &format!("Expected non-empty collection at {}.", key_path))
    )
  • replacement in src/lib.rs at line 656
    [4.3290][4.3290:3434]()
    return Err(expected_non_empty_collection(
    file!(),
    line!(),
    key_path
    ))
    [4.3290]
    [4.3434]
    return Err(
    err(file!(), line!(), &format!("Expected non-empty collection at {}.", key_path))
    )
  • replacement in src/lib.rs at line 747
    [2.213][4.9272:9454](),[4.9272][4.9272:9454]()
    return Err(keypath_extends_beyond_keyvalue(
    &format!("{}: {}", key, value),
    *line,
    &key_path.to_string(),
    [2.213]
    [4.9454]
    return Err(err(file!(), line!(),
    &format!("Line {} keypath {}. Keypath_extends_beyond_keyvalue {}: {}.",
    *line,
    &key_path,
    key,
    value,
    )
  • edit in src/error.rs at line 1
    [4.36577][4.6272:6329](),[4.6329][4.36664:36665](),[4.36664][4.36664:36665](),[4.36665][4.6330:6368]()
    // `Token` is passed as a string to 'cut' the reference.
    // use std::error::Error as StdError;
  • edit in src/error.rs at line 5
    [4.2067][4.664:665](),[4.36956][4.664:665](),[4.665][4.6383:6407]()
    // TODO: impl StdError;
  • edit in src/error.rs at line 10
    [4.37428][4.37428:37431](),[4.37431][4.9507:9603](),[4.9603][3.557:623](),[3.623][4.9664:9717](),[4.3602][4.9664:9717](),[4.9664][4.9664:9717](),[4.2314][4.38892:38895](),[4.9717][4.38892:38895](),[4.38892][4.38892:38895](),[4.38895][4.9718:9807](),[4.9807][3.624:698](),[3.698][4.9876:9928](),[4.3680][4.9876:9928](),[4.9876][4.9876:9928](),[4.2435][4.39071:39074](),[4.9928][4.39071:39074](),[4.39071][4.39071:39074](),[4.39074][4.9929:10027](),[4.10027][3.699:777](),[3.777][4.10100:10136](),[4.3762][4.10100:10136](),[4.10100][4.10100:10136](),[4.2689][4.40365:40368](),[4.10136][4.40365:40368](),[4.40365][4.40365:40368](),[4.40368][4.3763:3871](),[4.3871][3.778:844](),[3.844][4.3940:4009](),[4.3940][4.3940:4009](),[4.4009][4.2834:2836](),[4.10224][4.2834:2836](),[4.2834][4.2834:2836](),[4.2836][4.43075:43076](),[4.43075][4.43075:43076](),[4.43076][4.10225:10256](),[4.10256][4.4010:4062](),[4.4062][4.10300:10336](),[4.10300][4.10300:10336](),[4.10336][4.4063:4128](),[4.4128][4.3058:3060](),[4.10393][4.3058:3060](),[4.3058][4.3058:3060](),[4.3060][4.43212:43213](),[4.43212][4.43212:43213](),[4.43213][4.10394:10485](),[4.10485][3.845:927](),[3.927][4.10562:10692](),[4.4214][4.10562:10692](),[4.10562][4.10562:10692](),[4.10692][3.928:1010](),[3.1010][4.10769:10808](),[4.4300][4.10769:10808](),[4.10769][4.10769:10808](),[4.10808][4.4301:4416](),[4.4416][3.1011:1077](),[3.1077][4.4485:4550](),[4.4485][4.4485:4550](),[4.4550][4.10808:10889](),[4.10808][4.10808:10889](),[4.10889][3.1078:1163](),[3.1163][4.10969:10994](),[4.4639][4.10969:10994](),[4.10969][4.10969:10994](),[4.10994][4.3191:3193](),[4.3191][4.3191:3193](),[4.3193][4.43461:43462](),[4.43461][4.43461:43462](),[4.43462][4.4640:4739](),[4.4739][4.11066:11085](),[4.11066][4.11066:11085](),[4.11085][3.1164:1262](),[3.1262][4.4841:4874](),[4.4841][4.4841:4874](),[4.4874][4.11172:11197](),[4.11172][4.11172:11197]()
    }
    pub fn bad_first_segment(token: &str, line: usize, segment: &str) -> Error {
    Error(format!(
    "[keytree] line {}, token [{}]. Bad first segment [{}].",
    line,
    token,
    segment,
    ))
    }
    pub fn bad_indent(token: &str, line: usize, indent: usize) -> Error {
    Error(format!(
    "[keytree] line {}, token [{}]. Indentation of {} is incorrect.",
    line,
    token,
    indent,
    ))
    }
    pub fn cannot_resolve_token_with_siblings(token: &str, line: usize) -> Error {
    Error(format!(
    "[keytree] line {}, token [{}]. Cannot resolve token with siblings.",
    line,
    token,
    ))
    }
    pub fn colon_before_key(file: &str, code_line: u32, token: &str, line: usize) -> Error {
    Error(format!(
    "[keytree:{}:{}] Line {}, token [{}]. Colon before key.",
    file,
    code_line,
    line,
    token,
    ))
    }
    pub fn empty_path() -> Error {
    Error(String::from("[keytree:05] Empty path."))
    }
    pub fn empty_string() -> Error {
    Error(String::from("[keytree:06] Keytree string is empty."))
    }
    pub fn expected_key_found_keyvalue(token: &str, line: usize) -> Error {
    Error(format!(
    "[keytree] line {}, token [{}]. Expected [key:] but found [key: value].",
    line,
    token,
    ))
    }
    pub fn expected_keyvalue_found_key(token: &str, line: usize) -> Error {
    Error(format!(
    "[keytree] line {}, token [{}]. Expected [key: value] but found [key:].",
    line,
    token,
    ))
    }
    pub fn expected_non_empty_collection(code_file: &str, code_line: u32, keypath: &str) -> Error {
    Error(format!(
    "[keytree:{}:{}] Expected non-empty collection at [{}].",
    code_file,
    code_line,
    keypath,
    ))
    }
    pub fn expected_unique_found_multi(key_path: &str) -> Error {
    Error(format!(
    "[keytree] keypath: [{}]. Expected unique token but found multiple tokens.",
    key_path,
    ))
    }
    pub fn expected_unique_keyvalue_found_multi(file: &str, code_line: u32, key_path: &str) -> Error {
    Error(format!(
    "[keytree:{}:{}] keypath: [{}]. Expected unique [key: value] but found multiple tokens.",
    file,
    code_line,
    key_path,
    ))
  • replacement in src/error.rs at line 12
    [4.43585][4.4875:4973]()
    pub fn expected_unique_keyvalue_found_none(file: &str, code_line: u32, key_path: &str) -> Error {
    [4.43585]
    [4.11268]
    pub fn err(code_file: &str, code_line: u32, msg: &str) -> Error {
  • replacement in src/error.rs at line 14
    [4.11287][3.1263:1349](),[3.1349][4.5063:5096](),[4.5063][4.5063:5096](),[4.5096][4.11363:11391](),[4.11363][4.11363:11391](),[4.11391][4.5097:5212](),[4.5212][3.1350:1435](),[3.1435][4.5300:5358](),[4.5300][4.5300:5358](),[4.5358][4.3515:3517](),[4.3515][4.3515:3517](),[4.3517][4.43698:43699](),[4.43698][4.43698:43699](),[4.43699][3.1436:1520](),[3.1520][4.11586:11605](),[4.11586][4.11586:11605](),[4.11605][3.1521:1569]()
    "[keytree:{}:{}] Keypath [{}]. Expected unique [key: value] but found none.",
    file,
    code_line,
    key_path,
    ))
    }
    pub fn expected_unique_token_found_multi(file: &str, code_line: u32, key_path: &str) -> Error {
    Error(format!(
    "[keytree:{}:{}] Keypath [{}]. Expected a unique token but found multiple.",
    file,
    code_line,
    key_path,
    ))
    }
    pub fn external(
    code_file: &str,
    code_line: u32,
    msg: &str) -> Error
    {
    Error(format!(
    "[keytree:{}:{}] External error [{}].",
    [4.11287]
    [3.1569]
    "[ui_data:{}:{}] {}",
  • edit in src/error.rs at line 18
    [3.1620][4.11694:11703](),[4.11694][4.11694:11703](),[4.11703][4.43813:43814](),[4.43813][4.43813:43814](),[4.43814][4.5428:5511](),[4.5511][4.11759:11778](),[4.11759][4.11759:11778](),[4.11778][3.1621:1686](),[3.1686][4.5580:5613](),[4.5580][4.5580:5613](),[4.5613][4.11832:11854](),[4.11832][4.11832:11854](),[4.3600][4.43830:43833](),[4.11854][4.43830:43833](),[4.43830][4.43830:43833](),[4.43833][4.11855:11957](),[4.11957][3.1687:1771](),[3.1771][4.12036:12090](),[4.5701][4.12036:12090](),[4.12036][4.12036:12090](),[4.7012][4.3711:3713](),[4.12090][4.3711:3713](),[4.3711][4.3711:3713](),[4.3713][4.43944:43945](),[4.43944][4.43944:43945](),[4.43945][4.5702:5800](),[4.5800][4.12091:12110](),[4.7083][4.12091:12110](),[4.12110][3.1772:1847](),[3.1847][4.5879:5912](),[4.5879][4.5879:5912](),[4.5912][4.12174:12210](),[4.12174][4.12174:12210](),[4.12210][4.3840:3842](),[4.3840][4.3840:3842](),[4.3842][4.43945:43946](),[4.43945][4.43945:43946](),[4.43946][4.5913:6001](),[4.6001][4.12211:12230](),[4.7144][4.12211:12230](),[4.12230][3.1848:1912](),[3.1912][4.6069:6102](),[4.6069][4.6069:6102](),[4.6102][4.12283:12433](),[4.12283][4.12283:12433](),[4.12433][3.1913:2001](),[3.2001][4.12517:12647](),[4.6194][4.12517:12647](),[4.12517][4.12517:12647](),[4.12647][4.6195:6284](),[4.6284][4.3949:3951](),[4.12728][4.3949:3951](),[4.3949][4.3949:3951](),[4.3951][4.44298:44299](),[4.44298][4.44298:44299](),[4.44299][4.12729:12842](),[4.12842][3.2002:2082](),[3.2082][4.12918:12971](),[4.6368][4.12918:12971](),[4.12918][4.12918:12971](),[4.7242][4.4050:4052](),[4.12971][4.4050:4052](),[4.4050][4.4050:4052](),[4.4052][4.12972:13069](),[4.13069][3.2083:2148](),[3.2148][4.13130:13179](),[4.6437][4.13130:13179](),[4.13130][4.13130:13179](),[4.7385][4.4197:4199](),[4.13179][4.4197:4199](),[4.45016][4.4197:4199](),[4.4199][4.350:351](),[4.45022][4.350:351](),[4.351][4.6438:6529](),[4.6529][4.13243:13262](),[4.13243][4.13243:13262](),[4.13262][3.2149:2216](),[3.2216][4.6600:6633](),[4.6600][4.6600:6633](),[4.6633][4.13319:13355](),[4.13319][4.13319:13355](),[4.13355][4.4341:4343](),[4.4341][4.4341:4343](),[4.4343][4.45248:45249](),[4.45248][4.45248:45249](),[4.45249][4.6634:6744](),[4.6744][3.2217:2284](),[3.2284][4.6814:6876](),[4.6814][4.6814:6876]()
    ))
    }
    pub fn first_token_must_be_key(file: &str, code_line: u32, token: &str) -> Error {
    Error(format!(
    "[keytree:{}:{}] token {}. First token must be [key:].",
    file,
    code_line,
    token,
    ))
    }
    pub fn first_segment_mismatch(token: &str, line: usize, key_path: &str) -> Error {
    Error(format!(
    "[keytree] line {}, token [{}]. The first segment of [{}] does not match.",
    line,
    token,
    key_path,
    ))
    }
    pub fn incomplete_comment_or_key(file: &str, code_line: u32, token: &str, line: usize) -> Error {
    Error(format!(
    "[keytree:{}:{}] line {}, token [{}]. Incomplete comment or key.",
    file,
    code_line,
    line,
    token,
    ))
    }
    pub fn incomplete_line(file: &str, code_line: u32, token: &str, line: usize) -> Error {
    Error(format!(
    "[keytree:{}:{}] line {}, token [{}]. Incomplete line.",
    file,
    code_line,
    line,
    token,
    ))
    }
    pub fn keypath_extends_beyond_keyvalue(token: &str, line: usize, key_path: &str) -> Error {
    Error(format!(
    "[keytree] 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!( "[keytree:19] Keypath {} must have two or more segments.", key_path))
    }
    pub fn keypath_segment_does_not_match_key(token: &str, segment: &str, line: usize) -> Error {
    Error(format!(
    "[keytree] line {} token [{}]. Keypath segment {} does not match key.",
    line,
    token,
    segment,
    ))
    }
    pub fn no_child_with_segment(token: &str, line: usize, key: &str) -> Error {
    Error(format!(
    "[keytree] line {} token [{}]. Failed to find key [{}]",
    line,
    token,
    key,
    ))
    }
    pub fn no_colon_after_key(file: &str, code_line: u32, token: &str, line: usize) -> Error {
    Error(format!(
    "[keytree:{}:{}] line {} token [{}], No colon after key.",
    file,
    code_line,
    line,
    token,
    ))
    }
    pub fn no_space_after_key(file: &str, code_line: u32, token: &str, line: usize) -> Error {
    Error(format!(
    "[keytree:{}:{}] line {} token [{}]. No space after key.",
    file,
    code_line,
    line,
    token,
  • edit in src/error.rs at line 20
    [4.4432][4.47289:47290](),[4.47289][4.47289:47290](),[4.47290][4.6884:6959](),[4.6959][3.2285:2341](),[3.2341][4.7018:7058](),[4.7018][4.7018:7058](),[4.4501][4.47727:47730](),[4.7058][4.47727:47730](),[4.13452][4.47727:47730](),[4.47727][4.47727:47730](),[4.47730][4.7059:7156](),[4.7156][4.13522:13541](),[4.13522][4.13522:13541](),[4.13541][3.2342:2434](),[3.2434][4.7252:7286](),[4.7252][4.7252:7286](),[4.7286][3.2435:2623](),[3.2623][4.13622:13658](),[4.7286][4.13622:13658](),[4.13622][4.13622:13658](),[4.13658][4.4572:4574](),[4.4572][4.4572:4574](),[4.4574][3.2624:2625]()
    pub fn no_tokens(file: &str, code_line: u32) -> Error {
    Error(format!(
    "[keytree:{}:{}] No tokens in parsed keytree.",
    file,
    code_line,
    ))
    }
    pub fn non_root_has_zero_indent(file: &str, code_line: u32, token: &str, line: usize) -> Error {
    Error(format!(
    "[keytree:{}:{}] line {}, token [{}]. Token other than root token as zero indent.",
    file,
    code_line,
    line,
    token,
    ))
    }
    pub fn parse_value_failed(token: &str, line: usize) -> Error {
    Error(format!(
    "[keytree] line [{}], token [{}]. Failed to parse value.",
    line,
    token,
    ))
    }
  • replacement in src/builder.rs at line 12
    [4.47991][4.47991:48042](),[4.48065][4.48065:48088]()
    pub fn parent(&self, indent: usize) -> usize {
    self.0[indent]
    [4.47991]
    [4.48088]
    pub fn parent(&self, indent: usize) -> Option<usize> {
    if indent >= self.0.len() {
    None
    } else {
    Some(self.0[indent])
    }
  • replacement in examples/hobbit/src/main.rs at line 41
    [4.49767][4.49767:49872]()
    let kt = KeyTree::parse(HOBBITS).unwrap();
    let hobbit: Hobbit = kt.to_ref().try_into().unwrap();
    [4.49767]
    [4.49872]
    let kt = &KeyTree::parse(HOBBITS).unwrap();
    let hobbit: Hobbit = kt.try_into().unwrap();
    &dbg!(&hobbit);
    }
    fn main() {
    let kt = &KeyTree::parse(HOBBITS).unwrap();
    let hobbit: Hobbit = kt.try_into().unwrap();