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 miette::SourceSpan;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
|
||||||
use crate::{KdlNode, KdlValue};
|
use crate::{KdlNode, KdlParseFailure, KdlValue};
|
||||||
|
|
||||||
/// Represents a KDL
|
/// Represents a KDL
|
||||||
/// [`Document`](https://github.com/kdl-org/kdl/blob/main/SPEC.md#document).
|
/// [`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 {
|
impl Display for KdlDocument {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
self.stringify(f, 0)
|
self.stringify(f, 0)
|
||||||
|
|
|
||||||
|
|
@ -239,12 +239,7 @@ impl FromStr for KdlEntry {
|
||||||
type Err = KdlParseFailure;
|
type Err = KdlParseFailure;
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
let (maybe_val, errs) = v2_parser::try_parse(v2_parser::padded_node_entry, s);
|
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))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -131,12 +131,7 @@ impl FromStr for KdlIdentifier {
|
||||||
type Err = KdlParseFailure;
|
type Err = KdlParseFailure;
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
let (maybe_val, errs) = v2_parser::try_parse(v2_parser::identifier, s);
|
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))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -501,12 +501,7 @@ impl FromStr for KdlNode {
|
||||||
type Err = KdlParseFailure;
|
type Err = KdlParseFailure;
|
||||||
|
|
||||||
fn from_str(input: &str) -> Result<Self, Self::Err> {
|
fn from_str(input: &str) -> Result<Self, Self::Err> {
|
||||||
let (maybe_val, errs) = v2_parser::try_parse(v2_parser::padded_node, input);
|
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))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,9 @@ use miette::{Severity, SourceSpan};
|
||||||
|
|
||||||
use winnow::{
|
use winnow::{
|
||||||
ascii::{digit1, hex_digit1, oct_digit1, Caseless},
|
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::{
|
error::{
|
||||||
AddContext, ContextError, ErrorKind, FromExternalError, FromRecoverableError, ParserError,
|
AddContext, ContextError, ErrorKind, FromExternalError, FromRecoverableError, ParserError,
|
||||||
StrContext, StrContextValue,
|
StrContext, StrContextValue,
|
||||||
|
|
@ -26,25 +28,16 @@ use crate::{
|
||||||
type Input<'a> = Recoverable<Located<&'a str>, KdlParseError>;
|
type Input<'a> = Recoverable<Located<&'a str>, KdlParseError>;
|
||||||
type PResult<T> = winnow::PResult<T, 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>(
|
pub(crate) fn try_parse<'a, P: Parser<Input<'a>, T, KdlParseError>, T>(
|
||||||
mut parser: P,
|
mut parser: P,
|
||||||
input: &'a str,
|
input: &'a str,
|
||||||
) -> (Option<T>, Vec<KdlParseError>) {
|
) -> Result<T, KdlParseFailure> {
|
||||||
let (_, maybe_val, errs) = parser.recoverable_parse(Located::new(input));
|
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 {
|
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`
|
/// `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 bom = opt(bom.take()).parse_next(input)?;
|
||||||
let mut doc = nodes.parse_next(input)?;
|
let mut doc = nodes.parse_next(input)?;
|
||||||
if let Some(bom) = bom {
|
if let Some(bom) = bom {
|
||||||
|
|
@ -373,7 +366,7 @@ fn final_node(input: &mut Input<'_>) -> PResult<KdlNode> {
|
||||||
Ok(node)
|
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) = (
|
let ((leading, entry, trailing), _span) = (
|
||||||
repeat(0.., line_space).map(|_: ()| ()).take(),
|
repeat(0.., line_space).map(|_: ()| ()).take(),
|
||||||
node_entry,
|
node_entry,
|
||||||
|
|
@ -383,7 +376,7 @@ pub(crate) fn padded_node_entry(input: &mut Input<'_>) -> PResult<Option<KdlEntr
|
||||||
)
|
)
|
||||||
.with_span()
|
.with_span()
|
||||||
.parse_next(input)?;
|
.parse_next(input)?;
|
||||||
Ok(entry.map(|mut val| {
|
if let Some(entry) = entry.map(|mut val| {
|
||||||
if let Some(fmt) = val.format_mut() {
|
if let Some(fmt) = val.format_mut() {
|
||||||
fmt.leading = format!("{leading}{}", fmt.leading);
|
fmt.leading = format!("{leading}{}", fmt.leading);
|
||||||
fmt.trailing = format!("{}{trailing}", fmt.trailing);
|
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.span = _span.into();
|
||||||
}
|
}
|
||||||
val
|
val
|
||||||
}))
|
}) {
|
||||||
|
Ok(entry)
|
||||||
|
} else {
|
||||||
|
fail.parse_next(input)?
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `node-prop-or-arg := prop | value`
|
/// `node-prop-or-arg := prop | value`
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue