apollo_saphyr/annotated/
yaml_data_owned.rs1use alloc::{
2 boxed::Box,
3 string::{String, ToString},
4 vec::Vec,
5};
6use core::{
7 hash::{BuildHasher, Hasher},
8 ops::{Index, IndexMut},
9};
10
11use hashlink::LinkedHashMap;
12use saphyr_parser::{ScalarStyle, Tag};
13
14use crate::{annotated::AnnotatedNodeOwned, ScalarOwned};
15
16#[derive(Clone, PartialEq, PartialOrd, Debug, Eq, Ord, Hash)]
22pub enum YamlDataOwned<Node>
23where
24 Node: core::hash::Hash + Eq + From<Self> + AnnotatedNodeOwned,
25{
26 Representation(String, ScalarStyle, Option<Tag>),
32 Value(ScalarOwned),
38 Sequence(AnnotatedSequenceOwned<Node>),
44 Mapping(AnnotatedMappingOwned<Node>),
50 Tagged(Tag, Box<Node>),
56 Alias(usize),
62 BadValue,
68}
69
70define_yaml_object_impl!(
72 YamlDataOwned<Node>,
73 < Node>,
74 where {
75 Node: core::hash::Hash
76 + Eq
77 + From<Self>
78 + AnnotatedNodeOwned
79 + PartialEq<Node::HashKey>,
80 },
81 mappingtype = AnnotatedMappingOwned<Node>,
82 sequencetype = AnnotatedSequenceOwned<Node>,
83 nodetype = Node,
84 scalartype = { ScalarOwned },
85 selfname = "YamlDataOwned",
86 owned
87);
88
89impl<Node> YamlDataOwned<Node>
90where
91 Node: core::hash::Hash + Eq + From<Self> + AnnotatedNodeOwned + PartialEq<Node::HashKey>,
92{
93 #[must_use]
95 fn take(&mut self) -> Self {
96 core::mem::replace(self, Self::BadValue)
97 }
98
99 fn as_mapping_get_impl(&self, key: &str) -> Option<&Node> {
101 use core::hash::Hash;
102
103 match self {
104 Self::Mapping(mapping) => {
105 let needle =
106 Node::HashKey::from(YamlDataOwned::Value(ScalarOwned::String(key.into())));
107
108 let mut hasher = mapping.hasher().build_hasher();
112 needle.hash(&mut hasher);
113 let hash = hasher.finish();
114
115 mapping
116 .raw_entry()
117 .from_hash(hash, |candidate| *candidate == needle)
118 .map(|(_, v)| v)
119 }
120 _ => None,
121 }
122 }
123
124 #[must_use]
126 fn as_mapping_get_mut_impl(&mut self, key: &str) -> Option<&mut Node> {
127 match self.as_mapping_mut() {
128 Some(mapping) => {
129 use core::hash::Hash;
130 use hashlink::linked_hash_map::RawEntryMut::{Occupied, Vacant};
131
132 let needle =
136 Node::HashKey::from(YamlDataOwned::Value(ScalarOwned::String(key.to_string())));
137 let mut hasher = mapping.hasher().build_hasher();
138 needle.hash(&mut hasher);
139 let hash = hasher.finish();
140
141 match mapping
142 .raw_entry_mut()
143 .from_hash(hash, |candidate| *candidate == needle)
144 {
145 Occupied(entry) => Some(entry.into_mut()),
146 Vacant(_) => None,
147 }
148 }
149 _ => None,
150 }
151 }
152}
153
154impl<Node> IntoIterator for YamlDataOwned<Node>
155where
156 Node: core::hash::Hash + Eq + From<Self> + AnnotatedNodeOwned + PartialEq<Node::HashKey>,
157{
158 type Item = Node;
159 type IntoIter = AnnotatedYamlOwnedIter<Node>;
160
161 fn into_iter(self) -> Self::IntoIter {
162 Self::IntoIter {
163 yaml: self.into_vec().unwrap_or_default().into_iter(),
164 }
165 }
166}
167
168#[allow(clippy::module_name_repetitions)]
170pub struct AnnotatedYamlOwnedIter<Node>
171where
172 Node: core::hash::Hash + Eq + From<YamlDataOwned<Node>> + AnnotatedNodeOwned,
173{
174 yaml: alloc::vec::IntoIter<Node>,
175}
176
177impl<Node> Iterator for AnnotatedYamlOwnedIter<Node>
178where
179 Node: core::hash::Hash + Eq + From<YamlDataOwned<Node>> + AnnotatedNodeOwned,
180{
181 type Item = Node;
182
183 fn next(&mut self) -> Option<Node> {
184 self.yaml.next()
185 }
186}
187
188#[allow(clippy::module_name_repetitions)]
190pub type AnnotatedSequenceOwned<Node> = Vec<Node>;
191#[allow(clippy::module_name_repetitions)]
193pub type AnnotatedMappingOwned<Node> = LinkedHashMap<Node, Node>;