Skip to main content

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}