1use crate::BitArrayValue;
2use ecow::EcoString;
3use num_bigint::BigInt;
4use std::marker::PhantomData;
5
6pub struct HostValue<'call, Type> {
11 pub(crate) token: HostValueToken,
12 marker: PhantomData<&'call Type>,
13}
14
15pub struct HostList<'call, Item> {
17 pub(crate) token: HostListToken,
18 marker: PhantomData<&'call Item>,
19}
20
21pub struct HostTuple<'call, Elements> {
23 pub(crate) token: HostTupleToken,
24 marker: PhantomData<&'call Elements>,
25}
26
27pub struct HostCustom<'call, Custom> {
29 pub(crate) token: HostCustomToken,
30 marker: PhantomData<&'call Custom>,
31}
32
33pub struct HostExternal<'call, Type> {
45 pub(crate) token: HostExternalToken,
46 marker: PhantomData<&'call Type>,
47}
48
49pub struct HostCallable<'call, Arguments, Return> {
65 pub(crate) token: HostFunctionToken,
66 marker: PhantomData<&'call (Arguments, Return)>,
67}
68
69pub struct HostCallCompletion<'call, Return> {
85 pub(crate) token: HostValueToken,
86 call: PhantomData<&'call mut ()>,
87 return_: PhantomData<fn() -> Return>,
88}
89
90#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
91pub(crate) struct HostValueToken {
92 pub family: HostValueFamily,
93 pub index: usize,
94}
95
96#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
97pub(crate) enum HostValueFamily {
98 Int,
99 Float,
100 String,
101 BitArray,
102 UtfCodepoint,
103 Bool,
104 Nil,
105 List,
106 Tuple,
107 Custom,
108 External,
109 Function,
110 SymbolicFunction,
111}
112
113#[derive(Debug, Clone, Copy, PartialEq, Eq)]
114pub(crate) enum HostListToken {
115 Parameter(usize),
116 Stored(usize),
117}
118
119#[derive(Debug, Clone, Copy, PartialEq, Eq)]
120pub(crate) struct HostTupleToken(pub usize);
121
122#[derive(Debug, Clone, Copy, PartialEq, Eq)]
123pub(crate) struct HostCustomToken(pub usize);
124
125#[derive(Debug, Clone, Copy, PartialEq, Eq)]
126pub(crate) struct HostExternalToken(pub usize);
127
128#[derive(Debug, Clone, Copy, PartialEq, Eq)]
129pub(crate) struct HostFunctionToken(pub usize);
130
131#[derive(Debug, PartialEq)]
132pub(crate) enum HostScopedValue {
133 Int(BigInt),
134 Float(f64),
135 String(EcoString),
136 BitArray(BitArrayValue),
137 UtfCodepoint(char),
138 Bool(bool),
139 Nil,
140 Value(HostValueToken),
141 List(HostListToken),
142 Tuple(HostTupleToken),
143 Custom(HostCustomToken),
144 External(HostExternalToken),
145 Function(HostFunctionToken),
146}
147
148impl<'call, Type> HostValue<'call, Type> {
149 pub(crate) fn new(token: HostValueToken) -> Self {
150 Self {
151 token,
152 marker: PhantomData,
153 }
154 }
155}
156
157impl<Type> Clone for HostValue<'_, Type> {
158 fn clone(&self) -> Self {
159 *self
160 }
161}
162
163impl<Type> Copy for HostValue<'_, Type> {}
164
165impl<'call, Item> HostList<'call, Item> {
166 pub(crate) fn new(token: HostListToken) -> Self {
167 Self {
168 token,
169 marker: PhantomData,
170 }
171 }
172}
173
174impl<Item> Clone for HostList<'_, Item> {
175 fn clone(&self) -> Self {
176 *self
177 }
178}
179
180impl<Item> Copy for HostList<'_, Item> {}
181
182impl<'call, Elements> HostTuple<'call, Elements> {
183 pub(crate) fn new(token: HostTupleToken) -> Self {
184 Self {
185 token,
186 marker: PhantomData,
187 }
188 }
189}
190
191impl<Elements> Clone for HostTuple<'_, Elements> {
192 fn clone(&self) -> Self {
193 *self
194 }
195}
196
197impl<Elements> Copy for HostTuple<'_, Elements> {}
198
199impl<'call, Custom> HostCustom<'call, Custom> {
200 pub(crate) fn new(token: HostCustomToken) -> Self {
201 Self {
202 token,
203 marker: PhantomData,
204 }
205 }
206}
207
208impl<Custom> Clone for HostCustom<'_, Custom> {
209 fn clone(&self) -> Self {
210 *self
211 }
212}
213
214impl<Custom> Copy for HostCustom<'_, Custom> {}
215
216impl<'call, Type> HostExternal<'call, Type> {
217 pub(crate) fn new(token: HostExternalToken) -> Self {
218 Self {
219 token,
220 marker: PhantomData,
221 }
222 }
223}
224
225impl<Type> Clone for HostExternal<'_, Type> {
226 fn clone(&self) -> Self {
227 *self
228 }
229}
230
231impl<Type> Copy for HostExternal<'_, Type> {}
232
233impl<'call, Arguments, Return> HostCallable<'call, Arguments, Return> {
234 pub(crate) fn new(token: HostFunctionToken) -> Self {
235 Self {
236 token,
237 marker: PhantomData,
238 }
239 }
240}
241
242impl<Arguments, Return> Clone for HostCallable<'_, Arguments, Return> {
243 fn clone(&self) -> Self {
244 *self
245 }
246}
247
248impl<Arguments, Return> Copy for HostCallable<'_, Arguments, Return> {}
249
250impl<'call, Return> HostCallCompletion<'call, Return> {
251 pub(crate) fn new(token: HostValueToken) -> Self {
252 Self {
253 token,
254 call: PhantomData,
255 return_: PhantomData,
256 }
257 }
258}
259
260#[cfg(test)]
261mod tests {
262 use super::{
263 HostCallable, HostCustom, HostCustomToken, HostExternal, HostExternalToken,
264 HostFunctionToken, HostList, HostListToken, HostTuple, HostTupleToken, HostValue,
265 HostValueFamily, HostValueToken,
266 };
267
268 #[test]
269 fn scoped_handles_preserve_only_the_call_owned_token() {
270 fn clone_handle<Handle: Clone>(handle: &Handle) -> Handle {
271 handle.clone()
272 }
273
274 let value = HostValue::<bool>::new(HostValueToken {
275 family: HostValueFamily::Bool,
276 index: 1,
277 });
278 let list = HostList::<bool>::new(HostListToken::Stored(2));
279 let tuple = HostTuple::<bool>::new(HostTupleToken(3));
280 let custom = HostCustom::<bool>::new(HostCustomToken(4));
281 let external = HostExternal::<bool>::new(HostExternalToken(5));
282 let callable = HostCallable::<bool, bool>::new(HostFunctionToken(6));
283 let copied = value;
284 let cloned_value = clone_handle(&value);
285 let cloned_list = clone_handle(&list);
286 let cloned_tuple = clone_handle(&tuple);
287 let cloned_custom = clone_handle(&custom);
288 let cloned_external = clone_handle(&external);
289 let cloned_callable = clone_handle(&callable);
290
291 assert_eq!(
292 value.token,
293 HostValueToken {
294 family: HostValueFamily::Bool,
295 index: 1,
296 },
297 );
298 assert_eq!(copied.token, value.token);
299 assert_eq!(cloned_value.token, value.token);
300 assert_eq!(list.token, HostListToken::Stored(2));
301 assert_eq!(cloned_list.token, list.token);
302 assert_eq!(tuple.token, HostTupleToken(3));
303 assert_eq!(cloned_tuple.token, tuple.token);
304 assert_eq!(custom.token, HostCustomToken(4));
305 assert_eq!(cloned_custom.token, custom.token);
306 assert_eq!(external.token, HostExternalToken(5));
307 assert_eq!(cloned_external.token, external.token);
308 assert_eq!(callable.token, HostFunctionToken(6));
309 assert_eq!(cloned_callable.token, callable.token);
310 }
311}