1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
//! A YAML 1.2 parser using a greedy parsing algorithm with PEG atoms.
//!
//! The major purpose of this crate is to let the user build their own YAML reader/builder/validator.
//!
//! This parser is not ensuring about YAML spec but almost functions are well-implemented.
//!
//! The buffer reader has also not been implemented, but sub-parsers can read the chunks.
//!
//! WARN: YAML 1.2 is compatible with [JSON (JavaScript Object Notation) format](https://www.json.org/),
//! but not in strict mode.
//!
//! # Parser
//!
//! Function [`parse`] is used to parse YAML string into [`Node`] data structure,
//! which has a data holder [`Yaml`].
//! There also has a multiple-threaded version corresponding to [`NodeRc`]/[`NodeArc`] and [`YamlRc`]/[`YamlArc`].
//! To get back as string, please use [`dump`] function.
//!
//! There are also have some macros for building [`Node`] structure from Rust data.
//! Especially [`node!`] macro, almost data can be built by the macro literally.
//!
//! If you went to rise your own error message, [`indicated_msg`] might be a good choice.
//!
//! # Anchors
//!
//! The parser will replace the anchors during parsing.
//!
//! # Serialization and Deserialization
//!
//! Enable `serde`/`serde-std` feature to use `serde` crate,
//! which provides a set of protocol traits to convert between custom Rust data.
//! Please be aware that the additional fields will be discarded when convert to a fix-sized structure.
//! For example, the structure fields can be turned into map keys as well.
//!
//! On the other hand, the primitive types are still able to transform to YAML data without serialization,
//! according to built-in `From` and `Into` traits.
#![cfg_attr(doc_cfg, feature(doc_cfg))]
#![cfg_attr(not(feature = "serde-std"), no_std)]
#![warn(missing_docs)]
extern crate alloc;
pub use crate::{dumper::dump, indicator::*, node::*, parser::parse, yaml::*};
/// Create [`Node`] items literally.
///
/// Literals and expressions will be transformed to [`Yaml`] automatically by calling [`Into::into`].
///
/// ```
/// use yaml_peg::{node, NodeRc};
///
/// let k = "a";
/// assert_eq!(node!(k), node!("a"));
/// assert_eq!(node!(()), NodeRc::from(()));
/// ```
///
/// Arrays and maps can be created from this macro directly through brackets (`[]`, `{}`).
///
/// ```
/// use yaml_peg::{node, NodeRc};
///
/// let v = vec![NodeRc::from(1), NodeRc::from(2)];
/// assert_eq!(node!([1, 2]), v.into_iter().collect());
/// let m = vec![(NodeRc::from(1), NodeRc::from(2))];
/// assert_eq!(node!({1 => 2}), m.into_iter().collect());
/// ```
#[macro_export]
macro_rules! node {
(@[$v:expr; $n:expr]) => {{
extern crate alloc;
let v = alloc::vec![$crate::node!(@$v); $n];
$crate::node!(@$crate::Yaml::Seq(v))
}};
(@[$($v:expr),* $(,)?]) => {{
extern crate alloc;
let v = alloc::vec![$($crate::node!(@$v)),*];
$crate::node!(@$crate::Yaml::Seq(v))
}};
(@{$($k:expr => $v:expr),* $(,)?}) => {{
extern crate alloc;
let m = alloc::vec![$(($crate::node!(@$k), $crate::node!(@$v))),*];
$crate::node!(@$crate::Yaml::Map(m.into_iter().collect()))
}};
(@*$anchor:expr) => {
$crate::node!(@$crate::Yaml::Alias($anchor.into()))
};
(@$yaml:expr) => {
$crate::Node::from($yaml)
};
(arc $($tt:tt)+) => {
$crate::NodeArc::from($crate::node!(@$($tt)+))
};
(rc $($tt:tt)+) => {
$crate::NodeRc::from($crate::node!(@$($tt)+))
};
($($tt:tt)+) => {
$crate::node!(rc $($tt)+)
};
}
pub mod dumper;
mod indicator;
mod node;
pub mod parser;
pub mod repr;
#[cfg(feature = "serde")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))]
pub mod serde;
#[cfg(test)]
mod tests;
mod yaml;