#![doc = include_str!("readme.md")]
use core::{fmt, range::Range};
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct YamlRoot {
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
pub span: Range<usize>,
pub items: Vec<YamlValueNode>,
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum YamlValueNode {
Scalar(YamlScalar),
Sequence(YamlSequence),
Mapping(YamlMapping),
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct YamlScalar {
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
pub span: Range<usize>,
pub value: String,
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct YamlSequence {
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
pub span: Range<usize>,
pub items: Vec<YamlValueNode>,
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct YamlMapping {
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
pub span: Range<usize>,
pub entries: Vec<YamlMappingEntry>,
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct YamlMappingEntry {
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
pub span: Range<usize>,
pub key: YamlValueNode,
pub value: YamlValueNode,
}
impl fmt::Display for YamlValueNode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.fmt_with_indent(f, 0)
}
}
impl YamlValueNode {
fn fmt_with_indent(&self, f: &mut fmt::Formatter<'_>, indent: usize) -> fmt::Result {
let indent_str = " ".repeat(indent);
match self {
YamlValueNode::Scalar(scalar) => {
write!(f, "{}", scalar.value)
}
YamlValueNode::Sequence(seq) => {
for (i, item) in seq.items.iter().enumerate() {
if i > 0 {
writeln!(f)?;
}
write!(f, "{indent_str}-")?;
match item {
YamlValueNode::Scalar(_) => {
write!(f, " ")?;
item.fmt_with_indent(f, indent)
}
_ => {
writeln!(f)?;
item.fmt_with_indent(f, indent + 1)
}
}?;
}
Ok(())
}
YamlValueNode::Mapping(map) => {
for (i, entry) in map.entries.iter().enumerate() {
if i > 0 {
writeln!(f)?;
}
write!(f, "{indent_str}")?;
entry.key.fmt_with_indent(f, 0)?;
write!(f, ":")?;
match &entry.value {
YamlValueNode::Scalar(_) => {
write!(f, " ")?;
entry.value.fmt_with_indent(f, 0)
}
_ => {
writeln!(f)?;
entry.value.fmt_with_indent(f, indent + 1)
}
}?;
}
Ok(())
}
}
}
}