geam_core/host/construction.rs
1use crate::host::{HostType, HostTypeAt, HostTypeSequence};
2use std::marker::PhantomData;
3
4type CallScopedMarker<'call, Type> = PhantomData<fn(&'call ()) -> (&'call (), Type)>;
5
6/// Call-scoped construction capabilities registered for one host function.
7///
8/// Select an exact registered type with [`HostConstructions::at`] and pass the
9/// resulting token to the corresponding [`crate::HostCall`] construction
10/// method.
11///
12/// Construction tokens cannot be created directly.
13///
14/// ```compile_fail
15/// use geam_core::{HostConstruction, HostListType};
16/// use num_bigint::BigInt;
17///
18/// let _ = HostConstruction::<'static, HostListType<BigInt>>::new();
19/// ```
20///
21/// An index selects exactly the type registered at that position.
22///
23/// ```compile_fail
24/// use ecow::EcoString;
25/// use geam_core::{
26/// HostConstruction, HostConstructions, HostListType, HostTypeIndex0, HostTypeList,
27/// HostTypeListEnd,
28/// };
29/// use num_bigint::BigInt;
30///
31/// type Types = HostTypeList<HostListType<EcoString>, HostTypeListEnd>;
32///
33/// fn wrong<'call>(
34/// constructions: HostConstructions<'call, Types>,
35/// ) -> HostConstruction<'call, HostListType<BigInt>> {
36/// constructions.at::<HostTypeIndex0>()
37/// }
38/// ```
39///
40/// An unregistered position cannot be selected.
41///
42/// ```compile_fail
43/// use geam_core::{HostConstructions, HostTypeIndex0, HostTypeListEnd};
44///
45/// fn undeclared(constructions: HostConstructions<'_, HostTypeListEnd>) {
46/// let _ = constructions.at::<HostTypeIndex0>();
47/// }
48/// ```
49pub struct HostConstructions<'call, Types: HostTypeSequence> {
50 marker: CallScopedMarker<'call, Types>,
51}
52
53/// Permission to construct one exact host type during the active host call.
54///
55/// The token cannot escape the call lifetime that granted it.
56///
57/// ```compile_fail
58/// use ecow::EcoString;
59/// use geam_core::{
60/// HostConstruction, HostConstructions, HostListType, HostTypeIndex0, HostTypeList,
61/// HostTypeListEnd,
62/// };
63///
64/// type List = HostListType<EcoString>;
65/// type Types = HostTypeList<List, HostTypeListEnd>;
66///
67/// fn escape<'call>(
68/// constructions: HostConstructions<'call, Types>,
69/// ) -> HostConstruction<'static, List> {
70/// constructions.at::<HostTypeIndex0>()
71/// }
72/// ```
73pub struct HostConstruction<'call, Type: HostType> {
74 marker: CallScopedMarker<'call, Type>,
75}
76
77impl<'call, Types: HostTypeSequence> HostConstructions<'call, Types> {
78 pub(crate) fn new() -> Self {
79 Self {
80 marker: PhantomData,
81 }
82 }
83
84 /// Selects the exact construction type registered at `Index`.
85 pub fn at<Index>(&self) -> HostConstruction<'call, <Types as HostTypeAt<Index>>::Type>
86 where
87 Types: HostTypeAt<Index>,
88 {
89 HostConstruction {
90 marker: PhantomData,
91 }
92 }
93}