mirror of https://github.com/kdl-org/kdl-rs.git
refactor(parser): refactor try_parse to be lift more weight
This commit is contained in:
parent
5eb9442297
commit
a641995293
|
|
@ -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<Self, Self::Err> {
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -239,12 +239,7 @@ impl FromStr for KdlEntry {
|
|||
type Err = KdlParseFailure;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -131,12 +131,7 @@ impl FromStr for KdlIdentifier {
|
|||
type Err = KdlParseFailure;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -501,12 +501,7 @@ impl FromStr for KdlNode {
|
|||
type Err = KdlParseFailure;
|
||||
|
||||
fn from_str(input: &str) -> Result<Self, Self::Err> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<Located<&'a str>, KdlParseError>;
|
||||
type PResult<T> = winnow::PResult<T, KdlParseError>;
|
||||
|
||||
impl std::str::FromStr for KdlDocument {
|
||||
type Err = KdlParseFailure;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
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<Input<'a>, T, KdlParseError>, T>(
|
||||
mut parser: P,
|
||||
input: &'a str,
|
||||
) -> (Option<T>, Vec<KdlParseError>) {
|
||||
) -> Result<T, KdlParseFailure> {
|
||||
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<KdlParseError>, input: &str) -> KdlParseFailure {
|
||||
|
|
@ -201,7 +194,7 @@ fn new_input(s: &str) -> Input<'_> {
|
|||
}
|
||||
|
||||
/// `document := bom? nodes`
|
||||
fn document(input: &mut Input<'_>) -> PResult<KdlDocument> {
|
||||
pub(crate) fn document(input: &mut Input<'_>) -> PResult<KdlDocument> {
|
||||
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<KdlNode> {
|
|||
Ok(node)
|
||||
}
|
||||
|
||||
pub(crate) fn padded_node_entry(input: &mut Input<'_>) -> PResult<Option<KdlEntry>> {
|
||||
pub(crate) fn padded_node_entry(input: &mut Input<'_>) -> PResult<KdlEntry> {
|
||||
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<Option<KdlEntr
|
|||
)
|
||||
.with_span()
|
||||
.parse_next(input)?;
|
||||
Ok(entry.map(|mut val| {
|
||||
if let Some(entry) = entry.map(|mut val| {
|
||||
if let Some(fmt) = val.format_mut() {
|
||||
fmt.leading = format!("{leading}{}", fmt.leading);
|
||||
fmt.trailing = format!("{}{trailing}", fmt.trailing);
|
||||
|
|
@ -393,7 +386,11 @@ pub(crate) fn padded_node_entry(input: &mut Input<'_>) -> PResult<Option<KdlEntr
|
|||
val.span = _span.into();
|
||||
}
|
||||
val
|
||||
}))
|
||||
}) {
|
||||
Ok(entry)
|
||||
} else {
|
||||
fail.parse_next(input)?
|
||||
}
|
||||
}
|
||||
|
||||
/// `node-prop-or-arg := prop | value`
|
||||
|
|
|
|||
Loading…
Reference in New Issue