diff --git a/src/document.rs b/src/document.rs index e9d5382..7287dd0 100644 --- a/src/document.rs +++ b/src/document.rs @@ -2,7 +2,7 @@ use miette::SourceSpan; use std::fmt::Display; -use crate::{KdlNode, KdlValue}; +use crate::{KdlNode, KdlParseFailure, KdlValue}; /// Represents a KDL /// [`Document`](https://github.com/kdl-org/kdl/blob/main/SPEC.md#document). @@ -311,6 +311,14 @@ impl KdlDocument { // } } +impl std::str::FromStr for KdlDocument { + type Err = KdlParseFailure; + + fn from_str(s: &str) -> Result { + crate::v2_parser::try_parse(crate::v2_parser::document, s) + } +} + impl Display for KdlDocument { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.stringify(f, 0) diff --git a/src/entry.rs b/src/entry.rs index e5869b6..ff15095 100644 --- a/src/entry.rs +++ b/src/entry.rs @@ -239,12 +239,7 @@ impl FromStr for KdlEntry { type Err = KdlParseFailure; fn from_str(s: &str) -> Result { - let (maybe_val, errs) = v2_parser::try_parse(v2_parser::padded_node_entry, s); - if let (Some(Some(v)), true) = (maybe_val, errs.is_empty()) { - Ok(v) - } else { - Err(v2_parser::failure_from_errs(errs, s)) - } + v2_parser::try_parse(v2_parser::padded_node_entry, s) } } diff --git a/src/identifier.rs b/src/identifier.rs index 6bb62c0..4395ee6 100644 --- a/src/identifier.rs +++ b/src/identifier.rs @@ -131,12 +131,7 @@ impl FromStr for KdlIdentifier { type Err = KdlParseFailure; fn from_str(s: &str) -> Result { - let (maybe_val, errs) = v2_parser::try_parse(v2_parser::identifier, s); - if let Some(v) = maybe_val { - Ok(v) - } else { - Err(v2_parser::failure_from_errs(errs, s)) - } + v2_parser::try_parse(v2_parser::identifier, s) } } diff --git a/src/node.rs b/src/node.rs index ccd6a83..a5cb63f 100644 --- a/src/node.rs +++ b/src/node.rs @@ -501,12 +501,7 @@ impl FromStr for KdlNode { type Err = KdlParseFailure; fn from_str(input: &str) -> Result { - let (maybe_val, errs) = v2_parser::try_parse(v2_parser::padded_node, input); - if let (Some(v), true) = (maybe_val, errs.is_empty()) { - Ok(v) - } else { - Err(v2_parser::failure_from_errs(errs, input)) - } + v2_parser::try_parse(v2_parser::padded_node, input) } } diff --git a/src/v2_parser.rs b/src/v2_parser.rs index 8a8b2b5..c8541f0 100644 --- a/src/v2_parser.rs +++ b/src/v2_parser.rs @@ -7,7 +7,9 @@ use miette::{Severity, SourceSpan}; use winnow::{ ascii::{digit1, hex_digit1, oct_digit1, Caseless}, - combinator::{alt, cut_err, eof, not, opt, peek, preceded, repeat, repeat_till, terminated}, + combinator::{ + alt, cut_err, eof, fail, not, opt, peek, preceded, repeat, repeat_till, terminated, + }, error::{ AddContext, ContextError, ErrorKind, FromExternalError, FromRecoverableError, ParserError, StrContext, StrContextValue, @@ -26,25 +28,16 @@ use crate::{ type Input<'a> = Recoverable, KdlParseError>; type PResult = winnow::PResult; -impl std::str::FromStr for KdlDocument { - type Err = KdlParseFailure; - - fn from_str(s: &str) -> Result { - let (maybe_val, errs) = try_parse(document, s); - if let (Some(v), true) = (maybe_val, errs.is_empty()) { - Ok(v) - } else { - Err(failure_from_errs(errs, s)) - } - } -} - pub(crate) fn try_parse<'a, P: Parser, T, KdlParseError>, T>( mut parser: P, input: &'a str, -) -> (Option, Vec) { +) -> Result { let (_, maybe_val, errs) = parser.recoverable_parse(Located::new(input)); - (maybe_val, errs) + if let (Some(v), true) = (maybe_val, errs.is_empty()) { + Ok(v) + } else { + Err(failure_from_errs(errs, input)) + } } pub(crate) fn failure_from_errs(errs: Vec, input: &str) -> KdlParseFailure { @@ -201,7 +194,7 @@ fn new_input(s: &str) -> Input<'_> { } /// `document := bom? nodes` -fn document(input: &mut Input<'_>) -> PResult { +pub(crate) fn document(input: &mut Input<'_>) -> PResult { let bom = opt(bom.take()).parse_next(input)?; let mut doc = nodes.parse_next(input)?; if let Some(bom) = bom { @@ -373,7 +366,7 @@ fn final_node(input: &mut Input<'_>) -> PResult { Ok(node) } -pub(crate) fn padded_node_entry(input: &mut Input<'_>) -> PResult> { +pub(crate) fn padded_node_entry(input: &mut Input<'_>) -> PResult { let ((leading, entry, trailing), _span) = ( repeat(0.., line_space).map(|_: ()| ()).take(), node_entry, @@ -383,7 +376,7 @@ pub(crate) fn padded_node_entry(input: &mut Input<'_>) -> PResult) -> PResult