conjure_cp_core/ast/
moo.rs1use polyquine::Quine;
14use proc_macro2::TokenStream;
15use serde::{Deserialize, Serialize};
16use std::hash::{Hash, Hasher};
17use std::ops::DerefMut;
18use std::{collections::VecDeque, fmt::Display, ops::Deref, sync::Arc};
19use uniplate::{
20 Biplate, Tree, Uniplate,
21 impl_helpers::{transmute_if_same_type, try_transmute_if_same_type},
22 spez::try_biplate_to,
23};
24
25#[derive(PartialEq, Eq, Clone, Debug)]
39pub struct Moo<T> {
40 inner: Arc<T>,
41}
42
43impl<T: Quine> Quine for Moo<T> {
44 fn ctor_tokens(&self) -> TokenStream {
45 let inner = self.inner.as_ref().ctor_tokens();
46 quote::quote! { ::conjure_cp::ast::Moo::new(#inner) }
47 }
48}
49
50impl<T> Moo<T> {
51 pub fn new(value: T) -> Moo<T> {
53 Moo {
54 inner: Arc::new(value),
55 }
56 }
57}
58
59impl<T: Clone> Moo<T> {
60 pub fn make_mut(this: &mut Moo<T>) -> &mut T {
66 Arc::make_mut(&mut this.inner)
67 }
68
69 pub fn unwrap_or_clone(this: Moo<T>) -> T {
74 Arc::unwrap_or_clone(this.inner)
75 }
76}
77
78impl<T> AsRef<T> for Moo<T> {
79 fn as_ref(&self) -> &T {
80 self.inner.as_ref()
81 }
82}
83
84impl<T> Deref for Moo<T> {
85 type Target = T;
86
87 fn deref(&self) -> &Self::Target {
88 self.inner.deref()
89 }
90}
91
92impl<T: Clone> DerefMut for Moo<T> {
93 fn deref_mut(&mut self) -> &mut Self::Target {
94 Moo::make_mut(self)
95 }
96}
97
98impl<T> Uniplate for Moo<T>
99where
100 T: Uniplate,
101{
102 fn uniplate(
103 &self,
104 ) -> (
105 uniplate::Tree<Self>,
106 Box<dyn Fn(uniplate::Tree<Self>) -> Self>,
107 ) {
108 let this = Moo::clone(self);
109
110 let (tree, ctx) = try_biplate_to!((**self).clone(), Moo<T>);
113 (
114 Tree::Many(VecDeque::from([tree.clone()])),
115 Box::new(move |x| {
116 let Tree::Many(trees) = x else { panic!() };
117 let new_tree = trees.into_iter().next().unwrap();
118 let mut this = Moo::clone(&this);
119
120 if new_tree != tree {
124 let this = Moo::make_mut(&mut this);
125 *this = ctx(new_tree)
126 }
127
128 this
129 }),
130 )
131 }
132}
133
134impl<To, U> Biplate<To> for Moo<U>
135where
136 To: Uniplate,
137 U: Uniplate + Biplate<To>,
138{
139 fn biplate(&self) -> (Tree<To>, Box<dyn Fn(Tree<To>) -> Self>) {
140 if let Some(self_as_to) = transmute_if_same_type::<Self, To>(self) {
141 let tree = Tree::One(self_as_to.clone());
143 let ctx = Box::new(move |x| {
144 let Tree::One(self_as_to) = x else { panic!() };
145
146 let self_as_self = try_transmute_if_same_type::<To, Self>(&self_as_to);
147
148 Moo::clone(self_as_self)
149 });
150
151 (tree, ctx)
152 } else {
153 let this = Moo::clone(self);
156
157 let (tree, ctx) = try_biplate_to!((**self).clone(), To);
160 (
161 Tree::Many(VecDeque::from([tree.clone()])),
162 Box::new(move |x| {
163 let Tree::Many(trees) = x else { panic!() };
164 let new_tree = trees.into_iter().next().unwrap();
165 let mut this = Moo::clone(&this);
166
167 if new_tree != tree {
171 let this = Moo::make_mut(&mut this);
172 *this = ctx(new_tree)
173 }
174
175 this
176 }),
177 )
178 }
179 }
180}
181
182impl<'de, T: Deserialize<'de>> Deserialize<'de> for Moo<T> {
183 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
184 where
185 D: serde::Deserializer<'de>,
186 {
187 Ok(Moo::new(T::deserialize(deserializer)?))
188 }
189}
190
191impl<T: Serialize> Serialize for Moo<T> {
192 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
193 where
194 S: serde::Serializer,
195 {
196 T::serialize(&**self, serializer)
197 }
198}
199
200impl<T: Display> Display for Moo<T> {
201 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
202 (**self).fmt(f)
203 }
204}
205
206impl<T: Hash> Hash for Moo<T> {
207 fn hash<H: Hasher>(&self, state: &mut H) {
208 (**self).hash(state);
209 }
210}
211
212impl<T> From<T> for Moo<T> {
213 fn from(value: T) -> Self {
214 Moo::new(value)
215 }
216}