jsonld_core/object/
dismantle.rs1use super::{IndexedNode, List, Node, Object};
11use crate::IndexedObject;
12use std::mem;
13
14pub(crate) enum Pending<T, B> {
16 Object(IndexedObject<T, B>),
18 Node(IndexedNode<T, B>),
20}
21
22pub(crate) fn dismantle<T, B>(pending: &mut Vec<Pending<T, B>>) {
24 while let Some(descendant) = pending.pop() {
25 match descendant {
26 Pending::Object(mut object) => match object.inner_mut() {
27 Object::Node(node) => node.release_children(pending),
28 Object::List(list) => release_list(list, pending),
29 Object::Value(_) => {}
30 },
31 Pending::Node(mut node) => node.inner_mut().release_children(pending),
32 }
33 }
34}
35
36pub(crate) fn release_list<T, B>(list: &mut List<T, B>, pending: &mut Vec<Pending<T, B>>) {
39 pending.extend(list.take_entries().into_iter().filter(owns_objects).map(Pending::Object));
40}
41
42fn owns_objects<T, B>(object: &IndexedObject<T, B>) -> bool {
46 match object.inner() {
47 Object::Node(_) => true,
48 Object::List(list) => !list.is_empty(),
49 Object::Value(_) => false,
50 }
51}
52
53impl<T, B> Node<T, B> {
54 pub(crate) fn release_children(&mut self, pending: &mut Vec<Pending<T, B>>) {
58 if let Some(graph) = self.graph.take() {
59 pending.extend(graph.into_iter().filter(owns_objects).map(Pending::Object));
60 }
61 if let Some(included) = self.included.take() {
62 pending.extend(included.into_iter().map(Pending::Node));
63 }
64 if !self.properties.is_empty() {
65 pending.extend(
66 mem::take(&mut self.properties)
67 .into_iter()
68 .flat_map(|(_, objects)| objects)
69 .filter(owns_objects)
70 .map(Pending::Object),
71 );
72 }
73 if let Some(reverse) = self.reverse_properties.take() {
74 pending.extend(reverse.into_iter().flat_map(|(_, nodes)| nodes).map(Pending::Node));
75 }
76 }
77}
78
79impl<T, B> Drop for Node<T, B> {
80 fn drop(&mut self) {
85 let mut pending = Vec::new();
86 self.release_children(&mut pending);
87 dismantle(&mut pending);
88 }
89}
90
91impl<T, B> Drop for List<T, B> {
92 fn drop(&mut self) {
94 let mut pending = Vec::new();
95 release_list(self, &mut pending);
96 dismantle(&mut pending);
97 }
98}