use crate::nodes::node::Node;
pub use crate::nodes::node_utils::make_mapping_node;
use crate::parser::utils::helpers::node_to_inline_string;
pub fn normalize_node_to_str(node: &Node) -> Node {
use crate::nodes::node::{BlockStyle, NodeStringConvert, QuoteType};
use crate::nodes::node_utils::{
is_boolean_node, is_number_node, is_string_node, normalize_node,
};
let normalized = normalize_node(node);
match &normalized {
n if is_string_node(n) => n.clone(),
n if is_number_node(n) || is_boolean_node(n) => {
let inline = n.to_string_lossy();
Node::Str(inline, QuoteType::Double, BlockStyle::None)
}
Node::Array(items) => {
let mut s = String::from("[");
for (i, item) in items.iter().enumerate() {
if i > 0 {
s.push_str(", ");
}
if let Some(str_val) = item.as_str() {
s.push_str(str_val);
} else {
s.push_str(&item.to_string_lossy());
}
}
s.push(']');
Node::Str(s, QuoteType::Double, BlockStyle::None)
}
Node::Mapping(_) => {
let inline = normalized.to_string_lossy();
Node::Str(inline, QuoteType::Double, BlockStyle::None)
}
other => {
let inline = other.to_string_lossy();
Node::Str(inline, QuoteType::Double, BlockStyle::None)
}
}
}
pub fn force_key_to_string(key: Node) -> Node {
use crate::nodes::node::{BlockStyle, NodeStringConvert, QuoteType};
use crate::nodes::node_utils::{
is_boolean_node, is_number_node, is_string_node, normalize_node,
};
let normalized = normalize_node(&key);
if is_string_node(&normalized) {
normalized
} else if is_number_node(&normalized) || is_boolean_node(&normalized) {
let inline = normalized.to_string_lossy();
Node::Str(inline, QuoteType::Double, BlockStyle::None)
} else if let Node::Array(items) = &normalized {
let mut s = String::from("[");
for (i, item) in items.iter().enumerate() {
if i > 0 {
s.push_str(", ");
}
let inline = item.to_string_lossy();
s.push_str(&inline);
}
s.push(']');
Node::Str(s, QuoteType::Double, BlockStyle::None)
} else if let Node::Mapping(_) = &normalized {
let inline = normalized.to_string_lossy();
Node::Str(inline, QuoteType::Double, BlockStyle::None)
} else if let Node::Tagged(inner, tag) = &normalized {
if matches!(**inner, Node::Str(ref s, _, _) if s.is_empty()) {
Node::Tagged(inner.clone(), tag.clone())
} else {
Node::Tagged(
Box::new(force_key_to_string((**inner).clone())),
tag.clone(),
)
}
} else if let Node::Anchored(inner, name) = &normalized {
if matches!(**inner, Node::Str(ref s, _, _) if s.is_empty()) {
Node::Anchored(inner.clone(), name.clone())
} else {
Node::Anchored(
Box::new(force_key_to_string((**inner).clone())),
name.clone(),
)
}
} else {
let inline = normalized.to_string_lossy();
Node::Str(inline, QuoteType::Double, BlockStyle::None)
}
}
#[allow(dead_code)]
pub fn dedupe_mapping_pairs_by_last_occurrence(pairs: Vec<(Node, Node)>) -> Vec<(Node, Node)> {
use std::collections::HashMap as Map;
let mut last_index: Map<String, usize> = Map::new();
for (idx, (k, _v)) in pairs.iter().enumerate() {
let key_s = node_to_inline_string(k);
last_index.insert(key_s, idx);
}
let mut rebuilt: Vec<(Node, Node)> = Vec::new();
for (idx, (k, v)) in pairs.into_iter().enumerate() {
let key_s = node_to_inline_string(&k);
if let Some(&last) = last_index.get(&key_s) {
if last == idx {
rebuilt.push((k, v));
}
}
}
rebuilt
}
pub fn pairs_to_set_items_if_all_none(pairs: &[(Node, Node)]) -> Option<Vec<Node>> {
let mut items = Vec::new();
for (k, v) in pairs.iter() {
if matches!(v, Node::None) {
items.push(k.clone());
} else {
return None;
}
}
Some(items)
}
#[inline]
pub fn resolved_is_set(tag: &str) -> bool {
tag == "!!set" || tag == "tag:yaml.org,2002:set"
}
#[inline]
pub fn resolved_is_seq(tag: &str) -> bool {
tag == "!!seq" || tag == "tag:yaml.org,2002:seq"
}
#[inline]
pub fn resolved_is_map(tag: &str) -> bool {
tag == "!!map" || tag == "tag:yaml.org,2002:map"
}