mirror of https://github.com/kdl-org/kdl-rs.git
feat(docs): Add documentation for the entire crate (#16)
This commit is contained in:
parent
95a1ee3e57
commit
94190697d8
10
src/error.rs
10
src/error.rs
|
|
@ -3,6 +3,14 @@ use std::num::{ParseFloatError, ParseIntError};
|
||||||
use nom::error::{ContextError, ErrorKind, FromExternalError, ParseError};
|
use nom::error::{ContextError, ErrorKind, FromExternalError, ParseError};
|
||||||
|
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[cfg(doc)]
|
||||||
|
use {
|
||||||
|
crate::KdlNode,
|
||||||
|
std::convert::{TryFrom, TryInto},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// An error that occurs when parsing a KDL document.
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, Error)]
|
#[derive(Debug, Clone, Eq, PartialEq, Error)]
|
||||||
#[error("Error parsing document at line {line} column {column}. {kind}")]
|
#[error("Error parsing document at line {line} column {column}. {kind}")]
|
||||||
pub struct KdlError {
|
pub struct KdlError {
|
||||||
|
|
@ -16,6 +24,7 @@ pub struct KdlError {
|
||||||
pub kind: KdlErrorKind,
|
pub kind: KdlErrorKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A type reprenting additional information specific to the type of error being returned.
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, Error)]
|
#[derive(Debug, Clone, Eq, PartialEq, Error)]
|
||||||
pub enum KdlErrorKind {
|
pub enum KdlErrorKind {
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
|
|
@ -28,6 +37,7 @@ pub enum KdlErrorKind {
|
||||||
Other,
|
Other,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Coversion errors for converting [`KdlNode`] to another type via [`TryFrom`] or [`TryInto`].
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, Error)]
|
#[derive(Debug, Clone, Eq, PartialEq, Error)]
|
||||||
#[error("Failed to convert from KdlNodeValue::{variant} to {expected}.")]
|
#[error("Failed to convert from KdlNodeValue::{variant} to {expected}.")]
|
||||||
pub struct TryFromKdlNodeValueError {
|
pub struct TryFromKdlNodeValueError {
|
||||||
|
|
|
||||||
82
src/lib.rs
82
src/lib.rs
|
|
@ -1,3 +1,63 @@
|
||||||
|
#![doc(html_logo_url = "https://kdl.dev/logo.svg")]
|
||||||
|
//! KDL is a document language with xml-like semantics that looks like you're invoking a bunch of
|
||||||
|
//! CLI commands! It's meant to be used both as a serialization format and a configuration language,
|
||||||
|
//! much like JSON, YAML, or XML.
|
||||||
|
//!
|
||||||
|
//! There's a [living specification], as well as [various implementations]. You can also check out the
|
||||||
|
//! [language FAQ] to answer all your burning questions!
|
||||||
|
//!
|
||||||
|
//! This crate is the official/reference implementation of the KDL document language.
|
||||||
|
//!
|
||||||
|
//! [living specification]: https://github.com/kdl-org/kdl/blob/main/SPEC.md
|
||||||
|
//! [various implementations]: https://kdl.dev/#implementations
|
||||||
|
//! [language FAQ]: https://kdl.dev/#faq
|
||||||
|
//!
|
||||||
|
//! ## License
|
||||||
|
//!
|
||||||
|
//! The code in this crate is covered by the [Parity License], a strong copyleft license. That
|
||||||
|
//! means that you can only use this project if you're working on an open source-licensed product
|
||||||
|
//! (MIT/Apache projects are ok!)
|
||||||
|
//!
|
||||||
|
//! [Parity License]: https://github.com/kdl-org/kdl-rs/blob/main/LICENSE.md
|
||||||
|
//!
|
||||||
|
//! ## Example KDL File
|
||||||
|
//!
|
||||||
|
//! ```text
|
||||||
|
//! author "Alex Monad" email="alex@example.com" active=true
|
||||||
|
//!
|
||||||
|
//! contents {
|
||||||
|
//! section "First section" {
|
||||||
|
//! paragraph "This is the first paragraph"
|
||||||
|
//! paragraph "This is the second paragraph"
|
||||||
|
//! }
|
||||||
|
//! }
|
||||||
|
//!
|
||||||
|
//! // unicode! comments!
|
||||||
|
//! π 3.14159
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! ## Basic Library Example
|
||||||
|
//!
|
||||||
|
//! ```
|
||||||
|
//! use kdl::{KdlNode, KdlValue};
|
||||||
|
//! use std::collections::HashMap;
|
||||||
|
//!
|
||||||
|
//! assert_eq!(
|
||||||
|
//! kdl::parse_document("node 1 key=true").unwrap(),
|
||||||
|
//! vec![
|
||||||
|
//! KdlNode {
|
||||||
|
//! name: String::from("node"),
|
||||||
|
//! values: vec![KdlValue::Int(1)],
|
||||||
|
//! properties: {
|
||||||
|
//! let mut temp = HashMap::new();
|
||||||
|
//! temp.insert(String::from("key"), KdlValue::Boolean(true));
|
||||||
|
//! temp
|
||||||
|
//! },
|
||||||
|
//! children: vec![],
|
||||||
|
//! }
|
||||||
|
//! ]
|
||||||
|
//! )
|
||||||
|
//! ```
|
||||||
use nom::combinator::all_consuming;
|
use nom::combinator::all_consuming;
|
||||||
use nom::Finish;
|
use nom::Finish;
|
||||||
|
|
||||||
|
|
@ -8,6 +68,28 @@ mod error;
|
||||||
mod node;
|
mod node;
|
||||||
mod parser;
|
mod parser;
|
||||||
|
|
||||||
|
/// Parse a KDL document from a string into a list of [`KdlNode`]s.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use kdl::{KdlNode, KdlValue};
|
||||||
|
/// use std::collections::HashMap;
|
||||||
|
///
|
||||||
|
/// assert_eq!(
|
||||||
|
/// kdl::parse_document("node 1 key=true").unwrap(),
|
||||||
|
/// vec![
|
||||||
|
/// KdlNode {
|
||||||
|
/// name: String::from("node"),
|
||||||
|
/// values: vec![KdlValue::Int(1)],
|
||||||
|
/// properties: {
|
||||||
|
/// let mut temp = HashMap::new();
|
||||||
|
/// temp.insert(String::from("key"), KdlValue::Boolean(true));
|
||||||
|
/// temp
|
||||||
|
/// },
|
||||||
|
/// children: vec![],
|
||||||
|
/// }
|
||||||
|
/// ]
|
||||||
|
/// )
|
||||||
|
/// ```
|
||||||
pub fn parse_document<I>(input: I) -> Result<Vec<KdlNode>, KdlError>
|
pub fn parse_document<I>(input: I) -> Result<Vec<KdlNode>, KdlError>
|
||||||
where
|
where
|
||||||
I: AsRef<str>,
|
I: AsRef<str>,
|
||||||
|
|
|
||||||
48
src/node.rs
48
src/node.rs
|
|
@ -2,7 +2,52 @@ use std::{collections::HashMap, convert::TryFrom, fmt};
|
||||||
|
|
||||||
use crate::TryFromKdlNodeValueError;
|
use crate::TryFromKdlNodeValueError;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
/// A node representing the smallest unit of a KDL document.
|
||||||
|
///
|
||||||
|
/// The anatomy of a node:
|
||||||
|
/// ```text
|
||||||
|
/// name "value" property_key="property value" {
|
||||||
|
/// child
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ## Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use kdl::{KdlNode, KdlValue};
|
||||||
|
/// use std::collections::HashMap;
|
||||||
|
///
|
||||||
|
/// const DOCUMENT: &str = r#"
|
||||||
|
/// name "value" property_key="property value" {
|
||||||
|
/// child
|
||||||
|
/// }
|
||||||
|
/// "#;
|
||||||
|
///
|
||||||
|
/// assert_eq!(
|
||||||
|
/// kdl::parse_document(DOCUMENT).unwrap(),
|
||||||
|
/// vec![
|
||||||
|
/// KdlNode {
|
||||||
|
/// name: String::from("name"),
|
||||||
|
/// values: vec![KdlValue::String("value".into())],
|
||||||
|
/// properties: {
|
||||||
|
/// let mut temp = HashMap::new();
|
||||||
|
/// temp.insert(
|
||||||
|
/// String::from("property_key"),
|
||||||
|
/// KdlValue::String("property value".into())
|
||||||
|
/// );
|
||||||
|
/// temp
|
||||||
|
/// },
|
||||||
|
/// children: vec![
|
||||||
|
/// KdlNode {
|
||||||
|
/// name: String::from("child"),
|
||||||
|
/// ..Default::default()
|
||||||
|
/// }
|
||||||
|
/// ],
|
||||||
|
/// }
|
||||||
|
/// ]
|
||||||
|
/// )
|
||||||
|
/// ```
|
||||||
|
#[derive(Default, Debug, Clone, PartialEq)]
|
||||||
pub struct KdlNode {
|
pub struct KdlNode {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub values: Vec<KdlValue>,
|
pub values: Vec<KdlValue>,
|
||||||
|
|
@ -10,6 +55,7 @@ pub struct KdlNode {
|
||||||
pub children: Vec<KdlNode>,
|
pub children: Vec<KdlNode>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A value present in either a node's values or in a node's properties.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum KdlValue {
|
pub enum KdlValue {
|
||||||
Int(i64),
|
Int(i64),
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ use crate::node::{KdlNode, KdlValue};
|
||||||
pub(crate) fn nodes(input: &str) -> IResult<&str, Vec<KdlNode>, KdlParseError<&str>> {
|
pub(crate) fn nodes(input: &str) -> IResult<&str, Vec<KdlNode>, KdlParseError<&str>> {
|
||||||
let (input, _) = many0(linespace)(input)?;
|
let (input, _) = many0(linespace)(input)?;
|
||||||
let (input, nodes) = map(many0(terminated(node, many0(linespace))), |nodes| {
|
let (input, nodes) = map(many0(terminated(node, many0(linespace))), |nodes| {
|
||||||
nodes.into_iter().filter_map(|node| node).collect()
|
nodes.into_iter().flatten().collect()
|
||||||
})(input)?;
|
})(input)?;
|
||||||
let (input, _) = many0(linespace)(input)?;
|
let (input, _) = many0(linespace)(input)?;
|
||||||
Ok((input, nodes))
|
Ok((input, nodes))
|
||||||
|
|
@ -84,7 +84,7 @@ pub(crate) fn node(input: &str) -> IResult<&str, Option<KdlNode>, KdlParseError<
|
||||||
} else {
|
} else {
|
||||||
let (values, properties): (Vec<NodeArg>, Vec<NodeArg>) = args
|
let (values, properties): (Vec<NodeArg>, Vec<NodeArg>) = args
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|n| n)
|
.flatten()
|
||||||
.partition(|arg| matches!(arg, NodeArg::Value(_)));
|
.partition(|arg| matches!(arg, NodeArg::Value(_)));
|
||||||
Ok((
|
Ok((
|
||||||
input,
|
input,
|
||||||
|
|
@ -308,7 +308,9 @@ fn integer(input: &str) -> IResult<&str, i64, KdlParseError<&str>> {
|
||||||
map_res(
|
map_res(
|
||||||
recognize(many1(terminated(one_of("0123456789"), many0(char('_'))))),
|
recognize(many1(terminated(one_of("0123456789"), many0(char('_'))))),
|
||||||
move |out: &str| {
|
move |out: &str| {
|
||||||
i64::from_str_radix(&str::replace(&out, "_", ""), 10).map(move |x| x * mult)
|
str::replace(&out, "_", "")
|
||||||
|
.parse::<i64>()
|
||||||
|
.map(move |x| x * mult)
|
||||||
},
|
},
|
||||||
)(input)
|
)(input)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue