feat(docs): Add documentation for the entire crate (#16)

This commit is contained in:
jam1garner 2021-05-08 17:31:58 -04:00 committed by Kat Marchán
parent 95a1ee3e57
commit 94190697d8
No known key found for this signature in database
GPG Key ID: AEB529C08A3C7E9E
4 changed files with 144 additions and 4 deletions

View File

@ -3,6 +3,14 @@ use std::num::{ParseFloatError, ParseIntError};
use nom::error::{ContextError, ErrorKind, FromExternalError, ParseError};
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)]
#[error("Error parsing document at line {line} column {column}. {kind}")]
pub struct KdlError {
@ -16,6 +24,7 @@ pub struct KdlError {
pub kind: KdlErrorKind,
}
/// A type reprenting additional information specific to the type of error being returned.
#[derive(Debug, Clone, Eq, PartialEq, Error)]
pub enum KdlErrorKind {
#[error(transparent)]
@ -28,6 +37,7 @@ pub enum KdlErrorKind {
Other,
}
/// Coversion errors for converting [`KdlNode`] to another type via [`TryFrom`] or [`TryInto`].
#[derive(Debug, Clone, Eq, PartialEq, Error)]
#[error("Failed to convert from KdlNodeValue::{variant} to {expected}.")]
pub struct TryFromKdlNodeValueError {

View File

@ -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::Finish;
@ -8,6 +68,28 @@ mod error;
mod node;
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>
where
I: AsRef<str>,

View File

@ -2,7 +2,52 @@ use std::{collections::HashMap, convert::TryFrom, fmt};
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 name: String,
pub values: Vec<KdlValue>,
@ -10,6 +55,7 @@ pub struct KdlNode {
pub children: Vec<KdlNode>,
}
/// A value present in either a node's values or in a node's properties.
#[derive(Debug, Clone, PartialEq)]
pub enum KdlValue {
Int(i64),

View File

@ -18,7 +18,7 @@ use crate::node::{KdlNode, KdlValue};
pub(crate) fn nodes(input: &str) -> IResult<&str, Vec<KdlNode>, KdlParseError<&str>> {
let (input, _) = many0(linespace)(input)?;
let (input, nodes) = map(many0(terminated(node, many0(linespace))), |nodes| {
nodes.into_iter().filter_map(|node| node).collect()
nodes.into_iter().flatten().collect()
})(input)?;
let (input, _) = many0(linespace)(input)?;
Ok((input, nodes))
@ -84,7 +84,7 @@ pub(crate) fn node(input: &str) -> IResult<&str, Option<KdlNode>, KdlParseError<
} else {
let (values, properties): (Vec<NodeArg>, Vec<NodeArg>) = args
.into_iter()
.filter_map(|n| n)
.flatten()
.partition(|arg| matches!(arg, NodeArg::Value(_)));
Ok((
input,
@ -308,7 +308,9 @@ fn integer(input: &str) -> IResult<&str, i64, KdlParseError<&str>> {
map_res(
recognize(many1(terminated(one_of("0123456789"), many0(char('_'))))),
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)
}