use crate::tag::Tag;
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub struct NodeId(pub(crate) u32);
impl NodeId {
pub fn index(self) -> usize {
self.0 as usize
}
}
#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
pub enum ScalarStyle {
#[default]
Plain,
SingleQuoted,
DoubleQuoted,
Literal,
Folded,
}
impl ScalarStyle {
pub fn is_quoted(self) -> bool {
!matches!(self, ScalarStyle::Plain)
}
}
#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
pub enum CollectionStyle {
#[default]
Auto,
Flow,
Block,
}
#[derive(Clone, Debug, PartialEq)]
pub struct Entry {
pub key: NodeId,
pub value: NodeId,
}
#[derive(Clone, Debug, PartialEq)]
pub enum NodeData {
Scalar {
value: String,
style: ScalarStyle,
},
Sequence {
items: Vec<NodeId>,
style: CollectionStyle,
},
Mapping {
entries: Vec<Entry>,
style: CollectionStyle,
},
Alias(NodeId),
}
#[derive(Clone, Debug, PartialEq)]
pub struct Node {
pub tag: Option<Tag>,
pub anchor: Option<String>,
pub data: NodeData,
pub span: Option<Span>,
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct Span {
pub start: usize,
pub end: usize,
}
impl Node {
pub fn new(data: NodeData) -> Self {
Self { tag: None, anchor: None, data, span: None }
}
pub fn scalar(value: impl Into<String>) -> Self {
Self::new(NodeData::Scalar { value: value.into(), style: ScalarStyle::Plain })
}
pub fn scalar_styled(value: impl Into<String>, style: ScalarStyle) -> Self {
Self::new(NodeData::Scalar { value: value.into(), style })
}
pub fn sequence() -> Self {
Self::new(NodeData::Sequence { items: Vec::new(), style: CollectionStyle::Auto })
}
pub fn mapping() -> Self {
Self::new(NodeData::Mapping { entries: Vec::new(), style: CollectionStyle::Auto })
}
pub fn with_tag(mut self, tag: Tag) -> Self {
self.tag = Some(tag);
self
}
pub fn is_scalar(&self) -> bool {
matches!(self.data, NodeData::Scalar { .. })
}
pub fn is_sequence(&self) -> bool {
matches!(self.data, NodeData::Sequence { .. })
}
pub fn is_mapping(&self) -> bool {
matches!(self.data, NodeData::Mapping { .. })
}
pub fn is_alias(&self) -> bool {
matches!(self.data, NodeData::Alias(_))
}
pub fn as_str(&self) -> Option<&str> {
match &self.data {
NodeData::Scalar { value, .. } => Some(value),
_ => None,
}
}
pub fn scalar_style(&self) -> Option<ScalarStyle> {
match &self.data {
NodeData::Scalar { style, .. } => Some(*style),
_ => None,
}
}
}