conjure_cp_core/ast/
records.rs1use super::Name;
2use crate::ast::literals::AbstractLiteralValue;
3use funcmap::{FuncMap, TryFuncMap};
4use polyquine::Quine;
5use serde::{Deserialize, Serialize};
6use std::cmp::Ordering;
7use std::collections::VecDeque;
8use std::fmt::{Display, Formatter};
9use uniplate::{Biplate, Uniplate};
10
11#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash, Quine, FuncMap, TryFuncMap)]
15#[path_prefix(conjure_cp::ast)]
16pub struct Field<T> {
17 pub name: Name,
18 pub value: T,
19}
20
21impl<T: Eq> PartialOrd<Self> for Field<T> {
22 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
23 Some(self.cmp(other))
24 }
25}
26
27impl<T: Eq> Ord for Field<T> {
28 fn cmp(&self, other: &Self) -> Ordering {
29 self.name.cmp(&other.name)
30 }
31}
32
33impl<T> Uniplate for Field<T>
38where
39 T: Biplate<Field<T>>,
40{
41 fn uniplate(
42 &self,
43 ) -> (
44 ::uniplate::Tree<Field<T>>,
45 Box<dyn Fn(::uniplate::Tree<Field<T>>) -> Field<T>>,
46 ) {
47 let _name_copy = self.name.clone();
48 let (tree_value, ctx_value) = <T as Biplate<Field<T>>>::biplate(&self.value);
49 let children = ::uniplate::Tree::Many(VecDeque::from([tree_value, ::uniplate::Tree::Zero]));
50 let ctx = Box::new(move |x: ::uniplate::Tree<Field<T>>| {
51 let ::uniplate::Tree::Many(xs) = x else {
52 panic!()
53 };
54 let tree_value = xs[0].clone();
55 let value = ctx_value(tree_value);
56 Field {
57 name: _name_copy.clone(),
58 value,
59 }
60 });
61 (children, ctx)
62 }
63}
64
65impl<To, U> Biplate<To> for Field<U>
68where
69 U: Biplate<Field<U>> + Biplate<To>,
70 To: Uniplate,
71{
72 fn biplate(&self) -> (uniplate::Tree<To>, Box<dyn Fn(uniplate::Tree<To>) -> Self>) {
73 use uniplate::Tree;
74
75 if std::any::TypeId::of::<To>() == std::any::TypeId::of::<Field<U>>() {
76 unsafe {
79 let self_to = std::mem::transmute::<&Field<U>, &To>(self).clone();
81 let tree = Tree::One(self_to);
82 let ctx = Box::new(move |x| {
83 let Tree::One(x) = x else {
84 panic!();
85 };
86
87 std::mem::transmute::<&To, &Field<U>>(&x).clone()
88 });
89
90 (tree, ctx)
91 }
92 } else if std::any::TypeId::of::<To>() == std::any::TypeId::of::<Name>() {
93 let self2: Field<U> = self.clone();
95 let f_name: Name = self2.name;
96 let f_val: U = self2.value;
97
98 let (tree_val, ctx_val) = <U as Biplate<To>>::biplate(&f_val);
99
100 unsafe {
101 let f_name_to = std::mem::transmute::<&Name, &To>(&f_name).clone();
103 let tree_name = Tree::One(f_name_to);
104 let tree = Tree::Many(VecDeque::from([tree_name, tree_val]));
105
106 let ctx = Box::new(move |x| {
107 let Tree::Many(xs) = x else {
109 panic!();
110 };
111
112 let tree_name = xs[0].clone();
113 let tree_val = xs[1].clone();
114
115 let Tree::One(name) = tree_name else {
116 panic!();
117 };
118
119 let name = std::mem::transmute::<&To, &Name>(&name).clone();
121 let value = ctx_val(tree_val);
122
123 Field { name, value }
125 });
126
127 (tree, ctx)
128 }
129 } else {
130 let self2: Field<U> = self.clone();
133 let f_name: Name = self2.name;
134 let f_val: U = self2.value;
135
136 let (tree_val, ctx_val) = <U as Biplate<To>>::biplate(&f_val);
137
138 let tree = Tree::Many(VecDeque::from([tree_val]));
139
140 let ctx = Box::new(move |x| {
141 let Tree::Many(xs) = x else {
143 panic!();
144 };
145
146 let tree_val = xs[0].clone();
147
148 Field {
150 name: f_name.clone(),
151 value: ctx_val(tree_val),
152 }
153 });
154
155 (tree, ctx)
156 }
157 }
158}
159
160impl<T> Display for Field<T>
161where
162 T: AbstractLiteralValue,
163{
164 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
165 write!(f, "{} = {}", self.name, self.value)
166 }
167}