mirror of https://github.com/kdl-org/kdl-rs.git
refactor: clean up parser/FromStr toplevel stuff and add one for KdlIdentifier
This commit is contained in:
parent
8ed6a5cd06
commit
a1555949ed
|
|
@ -1,8 +1,6 @@
|
||||||
use std::{fmt::Display, str::FromStr};
|
use std::{fmt::Display, str::FromStr};
|
||||||
|
|
||||||
use nom::{combinator::all_consuming, Finish};
|
use crate::{parser, KdlError, KdlNode, KdlValue};
|
||||||
|
|
||||||
use crate::{parser::document, KdlError, KdlErrorKind, KdlNode, 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).
|
||||||
|
|
@ -13,7 +11,6 @@ use crate::{parser::document, KdlError, KdlErrorKind, KdlNode, KdlValue};
|
||||||
#[derive(Debug, Default, Clone, PartialEq)]
|
#[derive(Debug, Default, Clone, PartialEq)]
|
||||||
pub struct KdlDocument {
|
pub struct KdlDocument {
|
||||||
pub(crate) leading: Option<String>,
|
pub(crate) leading: Option<String>,
|
||||||
// TODO: Consider using `hashlink` for this, later?
|
|
||||||
pub(crate) nodes: Vec<KdlNode>,
|
pub(crate) nodes: Vec<KdlNode>,
|
||||||
pub(crate) trailing: Option<String>,
|
pub(crate) trailing: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
@ -209,34 +206,11 @@ impl IntoIterator for KdlDocument {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KdlDocument {
|
|
||||||
/// Parse a KDL document from a string into a [`KdlDocument`] object model.
|
|
||||||
fn parse(input: &str) -> Result<KdlDocument, KdlError> {
|
|
||||||
all_consuming(document)(input)
|
|
||||||
.finish()
|
|
||||||
.map(|(_, arg)| arg)
|
|
||||||
.map_err(|e| {
|
|
||||||
let prefix = &input[..(input.len() - e.input.len())];
|
|
||||||
KdlError {
|
|
||||||
input: input.into(),
|
|
||||||
offset: prefix.chars().count(),
|
|
||||||
kind: if let Some(kind) = e.kind {
|
|
||||||
kind
|
|
||||||
} else if let Some(ctx) = e.context {
|
|
||||||
KdlErrorKind::Context(ctx)
|
|
||||||
} else {
|
|
||||||
KdlErrorKind::Other
|
|
||||||
},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FromStr for KdlDocument {
|
impl FromStr for KdlDocument {
|
||||||
type Err = KdlError;
|
type Err = KdlError;
|
||||||
|
|
||||||
fn from_str(input: &str) -> Result<Self, Self::Err> {
|
fn from_str(input: &str) -> Result<Self, Self::Err> {
|
||||||
KdlDocument::parse(input)
|
parser::parse(input, parser::document)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
28
src/entry.rs
28
src/entry.rs
|
|
@ -1,8 +1,6 @@
|
||||||
use std::{fmt::Display, str::FromStr};
|
use std::{fmt::Display, str::FromStr};
|
||||||
|
|
||||||
use nom::{combinator::all_consuming, Finish};
|
use crate::{parser, KdlError, KdlIdentifier, KdlValue};
|
||||||
|
|
||||||
use crate::{KdlError, KdlErrorKind, KdlIdentifier, KdlValue};
|
|
||||||
|
|
||||||
/// KDL Entries are the "arguments" to KDL nodes: either a (positional)
|
/// KDL Entries are the "arguments" to KDL nodes: either a (positional)
|
||||||
/// [`Argument`](https://github.com/kdl-org/kdl/blob/main/SPEC.md#argument) or
|
/// [`Argument`](https://github.com/kdl-org/kdl/blob/main/SPEC.md#argument) or
|
||||||
|
|
@ -149,32 +147,10 @@ impl FromStr for KdlEntry {
|
||||||
type Err = KdlError;
|
type Err = KdlError;
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
KdlEntry::parse(s)
|
parser::parse(s, parser::entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KdlEntry {
|
|
||||||
/// Parse a KDL document from a string into a [`KdlDocument`] object model.
|
|
||||||
fn parse(input: &str) -> Result<KdlEntry, KdlError> {
|
|
||||||
all_consuming(crate::parser::entry)(input)
|
|
||||||
.finish()
|
|
||||||
.map(|(_, arg)| arg)
|
|
||||||
.map_err(|e| {
|
|
||||||
let prefix = &input[..(input.len() - e.input.len())];
|
|
||||||
KdlError {
|
|
||||||
input: input.into(),
|
|
||||||
offset: prefix.chars().count(),
|
|
||||||
kind: if let Some(kind) = e.kind {
|
|
||||||
kind
|
|
||||||
} else if let Some(ctx) = e.context {
|
|
||||||
KdlErrorKind::Context(ctx)
|
|
||||||
} else {
|
|
||||||
KdlErrorKind::Other
|
|
||||||
},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
use std::fmt::Display;
|
use std::{fmt::Display, str::FromStr};
|
||||||
|
|
||||||
|
use crate::{parser, KdlError};
|
||||||
|
|
||||||
/// Represents a KDL
|
/// Represents a KDL
|
||||||
/// [Identifier](https://github.com/kdl-org/kdl/blob/main/SPEC.md#identifier).
|
/// [Identifier](https://github.com/kdl-org/kdl/blob/main/SPEC.md#identifier).
|
||||||
|
|
@ -139,6 +141,14 @@ impl From<KdlIdentifier> for String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FromStr for KdlIdentifier {
|
||||||
|
type Err = KdlError;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
parser::parse(s, parser::identifier)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
||||||
29
src/node.rs
29
src/node.rs
|
|
@ -4,9 +4,7 @@ use std::{
|
||||||
str::FromStr,
|
str::FromStr,
|
||||||
};
|
};
|
||||||
|
|
||||||
use nom::{combinator::all_consuming, Finish};
|
use crate::{parser, KdlDocument, KdlEntry, KdlError, KdlIdentifier, KdlValue};
|
||||||
|
|
||||||
use crate::{KdlDocument, KdlEntry, KdlError, KdlErrorKind, KdlIdentifier, KdlValue};
|
|
||||||
|
|
||||||
/// Represents an individual KDL
|
/// Represents an individual KDL
|
||||||
/// [`Node`](https://github.com/kdl-org/kdl/blob/main/SPEC.md#node) inside a
|
/// [`Node`](https://github.com/kdl-org/kdl/blob/main/SPEC.md#node) inside a
|
||||||
|
|
@ -393,34 +391,11 @@ impl IndexMut<&str> for KdlNode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KdlNode {
|
|
||||||
/// Parse a KDL document from a string into a [`KdlDocument`] object model.
|
|
||||||
fn parse(input: &str) -> Result<KdlNode, KdlError> {
|
|
||||||
all_consuming(crate::parser::node)(input)
|
|
||||||
.finish()
|
|
||||||
.map(|(_, arg)| arg)
|
|
||||||
.map_err(|e| {
|
|
||||||
let prefix = &input[..(input.len() - e.input.len())];
|
|
||||||
KdlError {
|
|
||||||
input: input.into(),
|
|
||||||
offset: prefix.chars().count(),
|
|
||||||
kind: if let Some(kind) = e.kind {
|
|
||||||
kind
|
|
||||||
} else if let Some(ctx) = e.context {
|
|
||||||
KdlErrorKind::Context(ctx)
|
|
||||||
} else {
|
|
||||||
KdlErrorKind::Other
|
|
||||||
},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FromStr for KdlNode {
|
impl FromStr for KdlNode {
|
||||||
type Err = KdlError;
|
type Err = KdlError;
|
||||||
|
|
||||||
fn from_str(input: &str) -> Result<Self, Self::Err> {
|
fn from_str(input: &str) -> Result<Self, Self::Err> {
|
||||||
KdlNode::parse(input)
|
parser::parse(input, parser::node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,37 @@ use crate::nom_compat::{many0, many1, many_till};
|
||||||
use nom::branch::alt;
|
use nom::branch::alt;
|
||||||
use nom::bytes::complete::{tag, take_until, take_until1, take_while, take_while_m_n};
|
use nom::bytes::complete::{tag, take_until, take_until1, take_while, take_while_m_n};
|
||||||
use nom::character::complete::{anychar, char, none_of, one_of};
|
use nom::character::complete::{anychar, char, none_of, one_of};
|
||||||
use nom::combinator::{cut, eof, map, map_opt, map_res, opt, recognize};
|
use nom::combinator::{all_consuming, cut, eof, map, map_opt, map_res, opt, recognize};
|
||||||
use nom::error::{context, ParseError};
|
use nom::error::{context, ParseError};
|
||||||
use nom::sequence::{delimited, preceded, terminated, tuple};
|
use nom::sequence::{delimited, preceded, terminated, tuple};
|
||||||
use nom::{IResult, Offset, Parser, Slice};
|
use nom::{Finish, IResult, Offset, Parser, Slice};
|
||||||
|
|
||||||
use crate::{KdlDocument, KdlEntry, KdlIdentifier, KdlNode, KdlParseError, KdlValue};
|
use crate::{
|
||||||
|
KdlDocument, KdlEntry, KdlError, KdlErrorKind, KdlIdentifier, KdlNode, KdlParseError, KdlValue,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub(crate) fn parse<'a, T, P>(input: &'a str, parser: P) -> Result<T, KdlError>
|
||||||
|
where
|
||||||
|
P: Parser<&'a str, T, KdlParseError<&'a str>>,
|
||||||
|
{
|
||||||
|
all_consuming(parser)(input)
|
||||||
|
.finish()
|
||||||
|
.map(|(_, arg)| arg)
|
||||||
|
.map_err(|e| {
|
||||||
|
let prefix = &input[..(input.len() - e.input.len())];
|
||||||
|
KdlError {
|
||||||
|
input: input.into(),
|
||||||
|
offset: prefix.chars().count(),
|
||||||
|
kind: if let Some(kind) = e.kind {
|
||||||
|
kind
|
||||||
|
} else if let Some(ctx) = e.context {
|
||||||
|
KdlErrorKind::Context(ctx)
|
||||||
|
} else {
|
||||||
|
KdlErrorKind::Other
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn document(input: &str) -> IResult<&str, KdlDocument, KdlParseError<&str>> {
|
pub(crate) fn document(input: &str) -> IResult<&str, KdlDocument, KdlParseError<&str>> {
|
||||||
let (input, nodes) = many0(node)(input)?;
|
let (input, nodes) = many0(node)(input)?;
|
||||||
|
|
@ -51,7 +76,7 @@ pub(crate) fn node(input: &str) -> IResult<&str, KdlNode, KdlParseError<&str>> {
|
||||||
Ok((input, node))
|
Ok((input, node))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn identifier(input: &str) -> IResult<&str, KdlIdentifier, KdlParseError<&str>> {
|
pub(crate) fn identifier(input: &str) -> IResult<&str, KdlIdentifier, KdlParseError<&str>> {
|
||||||
alt((plain_identifier, quoted_identifier))(input)
|
alt((plain_identifier, quoted_identifier))(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue