conjure_core/ast/
records.rs1use std::collections::VecDeque;
2
3use super::literals::AbstractLiteralValue;
4use super::{Domain, Name};
5use serde::{Deserialize, Serialize};
6use uniplate::derive::Uniplate;
7use uniplate::{Biplate, Uniplate};
8
9#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Uniplate)]
10pub struct RecordEntry {
11 pub name: Name,
12 pub domain: Domain,
13}
14
15#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)]
16pub struct RecordValue<T: AbstractLiteralValue> {
17 pub name: Name,
18 pub value: T,
19}
20
21impl<T> Uniplate for RecordValue<T>
26where
27 T: AbstractLiteralValue,
28{
29 fn uniplate(
30 &self,
31 ) -> (
32 ::uniplate::Tree<RecordValue<T>>,
33 Box<dyn Fn(::uniplate::Tree<RecordValue<T>>) -> RecordValue<T>>,
34 ) {
35 let _name_copy = self.name.clone();
36 let (tree_value, ctx_value) = <T as Biplate<RecordValue<T>>>::biplate(&self.value);
37 let children = ::uniplate::Tree::Many(::std::collections::VecDeque::from([
38 tree_value,
39 ::uniplate::Tree::Zero,
40 ]));
41 let ctx = Box::new(move |x: ::uniplate::Tree<RecordValue<T>>| {
42 let ::uniplate::Tree::Many(xs) = x else {
43 panic!()
44 };
45 let tree_value = xs[0].clone();
46 let value = ctx_value(tree_value);
47 RecordValue {
48 name: _name_copy.clone(),
49 value,
50 }
51 });
52 (children, ctx)
53 }
54}
55
56impl<To, U> Biplate<To> for RecordValue<U>
59where
60 U: AbstractLiteralValue + Biplate<To>,
61 To: Uniplate,
62{
63 fn biplate(&self) -> (uniplate::Tree<To>, Box<dyn Fn(uniplate::Tree<To>) -> Self>) {
64 use uniplate::Tree;
65
66 if std::any::TypeId::of::<To>() == std::any::TypeId::of::<RecordValue<U>>() {
67 unsafe {
70 let self_to = std::mem::transmute::<&RecordValue<U>, &To>(self).clone();
72 let tree = Tree::One(self_to.clone());
73 let ctx = Box::new(move |x| {
74 let Tree::One(x) = x else {
75 panic!();
76 };
77
78 std::mem::transmute::<&To, &RecordValue<U>>(&x).clone()
79 });
80
81 (tree, ctx)
82 }
83 } else if std::any::TypeId::of::<To>() == std::any::TypeId::of::<Name>() {
84 let self2: RecordValue<U> = self.clone();
86 let f_name: Name = self2.name;
87 let f_val: U = self2.value;
88
89 let (tree_val, ctx_val) = <U as Biplate<To>>::biplate(&f_val);
90
91 unsafe {
92 let f_name_to = std::mem::transmute::<&Name, &To>(&f_name).clone();
94 let tree_name = Tree::One(f_name_to);
95 let tree = Tree::Many(VecDeque::from([tree_name, tree_val]));
96
97 let ctx = Box::new(move |x| {
98 let Tree::Many(xs) = x else {
100 panic!();
101 };
102
103 let tree_name = xs[0].clone();
104 let tree_val = xs[1].clone();
105
106 let Tree::One(name) = tree_name else {
107 panic!();
108 };
109
110 let name = std::mem::transmute::<&To, &Name>(&name).clone();
112 let value = ctx_val(tree_val);
113
114 RecordValue { name, value }
116 });
117
118 (tree, ctx)
119 }
120 } else {
121 let self2: RecordValue<U> = self.clone();
124 let f_name: Name = self2.name;
125 let f_val: U = self2.value;
126
127 let (tree_val, ctx_val) = <U as Biplate<To>>::biplate(&f_val);
128
129 let tree = Tree::Many(VecDeque::from([tree_val]));
130
131 let ctx = Box::new(move |x| {
132 let Tree::Many(xs) = x else {
134 panic!();
135 };
136
137 let tree_val = xs[0].clone();
138
139 RecordValue {
141 name: f_name.clone(),
142 value: ctx_val(tree_val),
143 }
144 });
145
146 (tree, ctx)
147 }
148 }
149}