use std::borrow::Cow;
use hashlink::LinkedHashMap;
use saphyr_parser::{ScalarStyle, Span, Tag};
use crate::{LoadableYamlNode, ScalarOwned, Yaml, YamlDataOwned};
#[derive(Clone, Debug)]
pub struct MarkedYamlOwned {
pub span: Span,
pub data: YamlDataOwned<MarkedYamlOwned>,
}
impl MarkedYamlOwned {
#[must_use]
pub fn value_from_str(v: &str) -> Self {
Self::value_from_cow(v.into())
}
#[must_use]
pub fn scalar_from_string(v: String) -> Self {
Self::value_from_cow(v.into())
}
#[must_use]
pub fn value_from_cow(v: Cow<'_, str>) -> Self {
Self {
data: YamlDataOwned::Value(ScalarOwned::parse_from_cow(v)),
span: Span::default(),
}
}
#[must_use]
pub fn value_from_cow_and_metadata(
v: Cow<'_, str>,
style: ScalarStyle,
tag: Option<&Cow<'_, Tag>>,
) -> Self {
ScalarOwned::parse_from_cow_and_metadata(v, style, tag).map_or_else(
|| Self {
data: YamlDataOwned::BadValue,
span: Span::default(),
},
|v| Self {
data: YamlDataOwned::Value(v),
span: Span::default(),
},
)
}
}
impl super::AnnotatedNodeOwned for MarkedYamlOwned {
type HashKey = MarkedYamlOwned;
fn parse_representation_recursive(&mut self) -> bool {
self.data.parse_representation_recursive()
}
}
impl From<YamlDataOwned<MarkedYamlOwned>> for MarkedYamlOwned {
fn from(value: YamlDataOwned<MarkedYamlOwned>) -> Self {
Self {
span: Span::default(),
data: value,
}
}
}
impl PartialEq<MarkedYamlOwned> for MarkedYamlOwned {
fn eq(&self, other: &MarkedYamlOwned) -> bool {
self.data.eq(&other.data)
}
}
impl Eq for MarkedYamlOwned {}
impl std::hash::Hash for MarkedYamlOwned {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.data.hash(state);
}
}
impl LoadableYamlNode<'_> for MarkedYamlOwned {
type HashKey = MarkedYamlOwned;
fn from_bare_yaml(yaml: Yaml) -> Self {
Self {
span: Span::default(),
data: match yaml {
Yaml::Sequence(_) => YamlDataOwned::Sequence(vec![]),
Yaml::Mapping(_) => YamlDataOwned::Mapping(LinkedHashMap::new()),
Yaml::Alias(x) => YamlDataOwned::Alias(x),
Yaml::BadValue => YamlDataOwned::BadValue,
Yaml::Representation(v, style, tag) => {
YamlDataOwned::Representation(v.to_string(), style, tag.map(Cow::into_owned))
}
Yaml::Tagged(tag, node) => {
YamlDataOwned::Tagged(tag.into_owned(), Box::new(Self::from_bare_yaml(*node)))
}
Yaml::Value(x) => YamlDataOwned::Value(x.into_owned()),
},
}
}
fn is_sequence(&self) -> bool {
self.data.is_sequence()
}
fn is_mapping(&self) -> bool {
self.data.is_mapping()
}
fn is_badvalue(&self) -> bool {
self.data.is_badvalue()
}
fn into_tagged(self, tag: Cow<'_, Tag>) -> Self {
Self {
span: self.span,
data: YamlDataOwned::Tagged(tag.into_owned(), Box::new(self)),
}
}
fn sequence_mut(&mut self) -> &mut Vec<Self> {
self.data
.as_vec_mut()
.expect("Called sequence_mut on a non-array")
}
fn mapping_mut(&mut self) -> &mut LinkedHashMap<Self::HashKey, Self> {
self.data
.as_mapping_mut()
.expect("Called mapping_mut on a non-hash")
}
fn take(&mut self) -> Self {
let mut taken_out = MarkedYamlOwned {
span: Span::default(),
data: YamlDataOwned::BadValue,
};
std::mem::swap(&mut taken_out, self);
taken_out
}
fn with_span(mut self, span: Span) -> Self {
self.span = span;
self
}
}