1*f6775a33SAlex Crichton /// A trait used as part of [`bindgen!`] to indicate a `Data<'_>` payload that
2*f6775a33SAlex Crichton /// implements some host bindings traits.
3*f6775a33SAlex Crichton ///
4*f6775a33SAlex Crichton /// The purpose of the [`bindgen!`] macro is to define Rust traits that the host
5*f6775a33SAlex Crichton /// can implement to fulfill WIT functions imported from the host into a
6*f6775a33SAlex Crichton /// component. The [`bindgen!`] macro then additionally generates a function
7*f6775a33SAlex Crichton /// which takes a [`Linker`] and an implementation of the traits and fills out
8*f6775a33SAlex Crichton /// the [`Linker`]. This trait, [`HasData`], is used in this process of filling
9*f6775a33SAlex Crichton /// out the [`Linker`] for some WIT interfaces.
10*f6775a33SAlex Crichton ///
11*f6775a33SAlex Crichton /// Wasmtime's [`Store<T>`] type is the home for all per-instance state.
12*f6775a33SAlex Crichton /// Notably the `T` here is generic (the Wasmtime library allows any type to be
13*f6775a33SAlex Crichton /// placed here) and it's also instance-specific as a [`Store<T>`] is typically
14*f6775a33SAlex Crichton /// allocated one-per-instance. Implementations of host APIs, however, often
15*f6775a33SAlex Crichton /// want to live in a library and not be tied to any particular `T`. For example
16*f6775a33SAlex Crichton /// Wasmtime provides the `wasmtime-wasi` crates as an implementation of
17*f6775a33SAlex Crichton /// standard WASI APIs as a library, but they don't want to fix a particular `T`
18*f6775a33SAlex Crichton /// in [`Store<T>`] as embedders should be able to fill out their own `T` for
19*f6775a33SAlex Crichton /// their needs. The purpose of this trait is to enable this situation.
20*f6775a33SAlex Crichton ///
21*f6775a33SAlex Crichton /// This trait is used in `add_to_linker` functions generated by [`bindgen!`] in
22*f6775a33SAlex Crichton /// conjunction with a function pointer. It looks something along the lines of:
23*f6775a33SAlex Crichton ///
24*f6775a33SAlex Crichton /// ```
25*f6775a33SAlex Crichton /// use wasmtime::component::{Linker, HasData};
26*f6775a33SAlex Crichton ///
27*f6775a33SAlex Crichton /// // generated by bindgen!
28*f6775a33SAlex Crichton /// trait Host {
29*f6775a33SAlex Crichton ///     // ..
30*f6775a33SAlex Crichton /// }
31*f6775a33SAlex Crichton ///
32*f6775a33SAlex Crichton /// fn add_to_linker<T, D>(linker: &mut Linker<T>, getter: fn(&mut T) -> D::Data<'_>)
33*f6775a33SAlex Crichton ///     where D: HasData,
34*f6775a33SAlex Crichton ///           for<'a> D::Data<'a>: Host,
35*f6775a33SAlex Crichton /// {
36*f6775a33SAlex Crichton ///     // ...
37*f6775a33SAlex Crichton /// # let _ = (linker, getter);
38*f6775a33SAlex Crichton /// }
39*f6775a33SAlex Crichton /// ```
40*f6775a33SAlex Crichton ///
41*f6775a33SAlex Crichton /// Here the `D` type parameter, bounded by [`HasData`], is used to specify
42*f6775a33SAlex Crichton /// the return type of the `getter` function provided here. The `getter`
43*f6775a33SAlex Crichton /// "projects" from `&mut T` to `D::Data<'_>`, notably enabling it to capture
44*f6775a33SAlex Crichton /// the lifetime of the `&mut T` passed in as well.
45*f6775a33SAlex Crichton ///
46*f6775a33SAlex Crichton /// The `Data` associated type here is further bounded in `add_to_linker` above
47*f6775a33SAlex Crichton /// as it must implement the traits generated by [`bindgen!`]. This means that
48*f6775a33SAlex Crichton /// `linker` is filled out with functions that, when called, first `getter` is
49*f6775a33SAlex Crichton /// invoked and then the actual function delegates to the `Host` trait
50*f6775a33SAlex Crichton /// implementation in this case.
51*f6775a33SAlex Crichton ///
52*f6775a33SAlex Crichton /// The `D` type parameter here isn't actually a runtime value, nor is it stored
53*f6775a33SAlex Crichton /// anywhere. It's purely used as a means of projecting a "generic associated
54*f6775a33SAlex Crichton /// type", here where `<'a>` is the generic argument, a lifetime. This means
55*f6775a33SAlex Crichton /// that the choice of `D` is disconnected from both `T` and `D::Data<'_>` and
56*f6775a33SAlex Crichton /// can be whatever you like. Sometimes you might need to define an empty struct
57*f6775a33SAlex Crichton /// in your project to use this, but Wasmtime also provides a convenience
58*f6775a33SAlex Crichton /// [`HasSelf`] type to avoid the need for this in some common use cases.
59*f6775a33SAlex Crichton ///
60*f6775a33SAlex Crichton /// # Example: `Host for T` using `Store<T>`
61*f6775a33SAlex Crichton ///
62*f6775a33SAlex Crichton /// Let's say you wanted to invoke the above `add_to_linker` function where the
63*f6775a33SAlex Crichton /// `T` in [`Store<T>`] directly implements the `Host` trait itself:
64*f6775a33SAlex Crichton ///
65*f6775a33SAlex Crichton /// ```
66*f6775a33SAlex Crichton /// use wasmtime::component::{Linker, HasSelf};
67*f6775a33SAlex Crichton /// # use wasmtime::component::HasData;
68*f6775a33SAlex Crichton /// #
69*f6775a33SAlex Crichton /// # trait Host { }
70*f6775a33SAlex Crichton /// # impl<T: Host + ?Sized> Host for &mut T {}
71*f6775a33SAlex Crichton /// #
72*f6775a33SAlex Crichton /// # fn add_to_linker<T, D>(linker: &mut Linker<T>, getter: fn(&mut T) -> D::Data<'_>)
73*f6775a33SAlex Crichton /// #     where D: HasData,
74*f6775a33SAlex Crichton /// #           for<'a> D::Data<'a>: Host,
75*f6775a33SAlex Crichton /// # {
76*f6775a33SAlex Crichton /// # let _ = (linker, getter);
77*f6775a33SAlex Crichton /// # }
78*f6775a33SAlex Crichton ///
79*f6775a33SAlex Crichton /// struct MyStoreState { /* ... */ }
80*f6775a33SAlex Crichton ///
81*f6775a33SAlex Crichton /// impl Host for MyStoreState {
82*f6775a33SAlex Crichton ///     // ..
83*f6775a33SAlex Crichton /// }
84*f6775a33SAlex Crichton ///
85*f6775a33SAlex Crichton /// fn fill_out_my_linker(linker: &mut Linker<MyStoreState>) {
86*f6775a33SAlex Crichton ///     add_to_linker::<_, HasSelf<_>>(linker, |x| x)
87*f6775a33SAlex Crichton /// }
88*f6775a33SAlex Crichton /// ```
89*f6775a33SAlex Crichton ///
90*f6775a33SAlex Crichton /// Here the `add_to_linker` invocation is annotated with `<_, HasSelf<_>>`. The
91*f6775a33SAlex Crichton /// first argument gets inferred to `MyStoreState`, and the second argument gets
92*f6775a33SAlex Crichton /// inferred to `HasSelf<MyStoreState>` This means that the projection function
93*f6775a33SAlex Crichton /// in this case, here the identity `|x| x`, is typed as
94*f6775a33SAlex Crichton /// `fn(&mut MyStoreState) -> &mut MyStoreState`. This is because the `HasData`
95*f6775a33SAlex Crichton /// implementation for `HasSelf<T>` means that we have
96*f6775a33SAlex Crichton /// `type Data<'a> = &'a mut T`.
97*f6775a33SAlex Crichton ///
98*f6775a33SAlex Crichton /// # Example: `Host for MyLibraryState` using `Store<T>`
99*f6775a33SAlex Crichton ///
100*f6775a33SAlex Crichton /// Let's say though that you instead are writing a library like WASI where you
101*f6775a33SAlex Crichton /// don't know the `T` of [`Store<T>`] ahead of time. In such a case you might
102*f6775a33SAlex Crichton /// hand-write your own `add_to_linker` wrapper that looks like this:
103*f6775a33SAlex Crichton ///
104*f6775a33SAlex Crichton /// ```
105*f6775a33SAlex Crichton /// use wasmtime::component::{Linker, HasData};
106*f6775a33SAlex Crichton /// #
107*f6775a33SAlex Crichton /// # trait Host { }
108*f6775a33SAlex Crichton /// # impl<T: Host + ?Sized> Host for &mut T {}
109*f6775a33SAlex Crichton /// #
110*f6775a33SAlex Crichton /// # fn add_to_linker<T, D>(linker: &mut Linker<T>, getter: fn(&mut T) -> D::Data<'_>)
111*f6775a33SAlex Crichton /// #     where D: HasData,
112*f6775a33SAlex Crichton /// #           for<'a> D::Data<'a>: Host,
113*f6775a33SAlex Crichton /// # {
114*f6775a33SAlex Crichton /// # let _ = (linker, getter);
115*f6775a33SAlex Crichton /// # }
116*f6775a33SAlex Crichton ///
117*f6775a33SAlex Crichton /// // publicly exposed per-instance state for your library, users will
118*f6775a33SAlex Crichton /// // construct this and store it within the `T` in `Store<T>`
119*f6775a33SAlex Crichton /// pub struct MyLibraryState { /* ... */ }
120*f6775a33SAlex Crichton ///
121*f6775a33SAlex Crichton /// impl Host for MyLibraryState {
122*f6775a33SAlex Crichton ///     // ..
123*f6775a33SAlex Crichton /// }
124*f6775a33SAlex Crichton ///
125*f6775a33SAlex Crichton /// // hand-written publicly exposed convenience function to add this crate's
126*f6775a33SAlex Crichton /// // component functionality to the provided linker.
127*f6775a33SAlex Crichton /// pub fn add_my_library_to_linker<T>(
128*f6775a33SAlex Crichton ///     linker: &mut Linker<T>,
129*f6775a33SAlex Crichton ///     f: fn(&mut T) -> &mut MyLibraryState,
130*f6775a33SAlex Crichton /// ) {
131*f6775a33SAlex Crichton ///     // invoke the bindgen!-generated `add_to_linker`
132*f6775a33SAlex Crichton ///     add_to_linker::<_, MyLibrary>(linker, f);
133*f6775a33SAlex Crichton /// }
134*f6775a33SAlex Crichton ///
135*f6775a33SAlex Crichton /// // Note this need not be publicly exposed, it's just a private internal
136*f6775a33SAlex Crichton /// // detail.
137*f6775a33SAlex Crichton /// struct MyLibrary;
138*f6775a33SAlex Crichton ///
139*f6775a33SAlex Crichton /// impl HasData for MyLibrary {
140*f6775a33SAlex Crichton ///     type Data<'a> = &'a mut MyLibraryState;
141*f6775a33SAlex Crichton /// }
142*f6775a33SAlex Crichton /// ```
143*f6775a33SAlex Crichton ///
144*f6775a33SAlex Crichton /// Here the `MyLibrary` type, private to this crate, has a `HasData`
145*f6775a33SAlex Crichton /// implementation which indicates that implementations of the
146*f6775a33SAlex Crichton /// `bindgen!`-generated APIs are done in terms of `MyLibraryState`
147*f6775a33SAlex Crichton /// specifically. The `add_my_library_to_linker` takes an externally-provided
148*f6775a33SAlex Crichton /// `f` closure which projects from `&mut T`, whatever data the store is using,
149*f6775a33SAlex Crichton /// to `MyLibraryState` which must be stored within the store itself.
150*f6775a33SAlex Crichton ///
151*f6775a33SAlex Crichton /// # Example: `Host for MyLibraryState<'_>` using `Store<T>`
152*f6775a33SAlex Crichton ///
153*f6775a33SAlex Crichton /// Let's say you're like the above scenario where you're writing a library but
154*f6775a33SAlex Crichton /// instead of being able to wrap up all your state for each trait
155*f6775a33SAlex Crichton /// implementation in a structure it's spread across a few structures. These
156*f6775a33SAlex Crichton /// structures may be stored in different locations inside of `Store<T>` which
157*f6775a33SAlex Crichton /// makes it difficult to wrap up in a single type and return that. Here you can
158*f6775a33SAlex Crichton /// make use of "view" types to collect a number of disjoint borrows into one
159*f6775a33SAlex Crichton /// structure:
160*f6775a33SAlex Crichton ///
161*f6775a33SAlex Crichton /// ```
162*f6775a33SAlex Crichton /// use wasmtime::component::{Linker, HasData};
163*f6775a33SAlex Crichton /// #
164*f6775a33SAlex Crichton /// # trait Host { }
165*f6775a33SAlex Crichton /// # impl<T: Host + ?Sized> Host for &mut T {}
166*f6775a33SAlex Crichton /// #
167*f6775a33SAlex Crichton /// # fn add_to_linker<T, D>(linker: &mut Linker<T>, getter: fn(&mut T) -> D::Data<'_>)
168*f6775a33SAlex Crichton /// #     where D: HasData,
169*f6775a33SAlex Crichton /// #           for<'a> D::Data<'a>: Host,
170*f6775a33SAlex Crichton /// # {
171*f6775a33SAlex Crichton /// # let _ = (linker, getter);
172*f6775a33SAlex Crichton /// # }
173*f6775a33SAlex Crichton /// # struct StateA;
174*f6775a33SAlex Crichton /// # struct StateB;
175*f6775a33SAlex Crichton ///
176*f6775a33SAlex Crichton /// // Like before, this is publicly exposed, and this is a "bag of pointers" to
177*f6775a33SAlex Crichton /// // all the pieces of state necessary to implement `Host` below.
178*f6775a33SAlex Crichton /// pub struct MyLibraryState<'a> {
179*f6775a33SAlex Crichton ///     pub state_a: &'a mut StateA,
180*f6775a33SAlex Crichton ///     pub state_b: &'a mut StateB,
181*f6775a33SAlex Crichton /// }
182*f6775a33SAlex Crichton ///
183*f6775a33SAlex Crichton /// impl Host for MyLibraryState<'_> {
184*f6775a33SAlex Crichton ///     // ..
185*f6775a33SAlex Crichton /// }
186*f6775a33SAlex Crichton ///
187*f6775a33SAlex Crichton /// pub fn add_my_library_to_linker<T>(
188*f6775a33SAlex Crichton ///     linker: &mut Linker<T>,
189*f6775a33SAlex Crichton ///     f: fn(&mut T) -> MyLibraryState<'_>,
190*f6775a33SAlex Crichton /// ) {
191*f6775a33SAlex Crichton ///     // invoke the bindgen!-generated `add_to_linker`
192*f6775a33SAlex Crichton ///     add_to_linker::<_, MyLibrary>(linker, f);
193*f6775a33SAlex Crichton /// }
194*f6775a33SAlex Crichton ///
195*f6775a33SAlex Crichton /// struct MyLibrary;
196*f6775a33SAlex Crichton ///
197*f6775a33SAlex Crichton /// impl HasData for MyLibrary {
198*f6775a33SAlex Crichton ///     type Data<'a> = MyLibraryState<'a>;
199*f6775a33SAlex Crichton /// }
200*f6775a33SAlex Crichton /// ```
201*f6775a33SAlex Crichton ///
202*f6775a33SAlex Crichton /// This is similar to the above example but shows using a lifetime parameter on
203*f6775a33SAlex Crichton /// a structure instead of using a pointer-with-a-lifetime only. Otherwise
204*f6775a33SAlex Crichton /// though this'll end up working out the same way.
205*f6775a33SAlex Crichton ///
206*f6775a33SAlex Crichton /// # Example: `Host for U: MyLibrary` using `Store<T>`
207*f6775a33SAlex Crichton ///
208*f6775a33SAlex Crichton /// Let's say you're in a situation where you're a library which wants to create
209*f6775a33SAlex Crichton /// a "simpler" trait than the `Host`-generated traits from [`bindgen!`] and
210*f6775a33SAlex Crichton /// then you want to implement `Host` in terms of this trait. This requires a
211*f6775a33SAlex Crichton /// bit more boilerplate as well as a new custom structure, but doing so looks
212*f6775a33SAlex Crichton /// like this:
213*f6775a33SAlex Crichton ///
214*f6775a33SAlex Crichton /// ```
215*f6775a33SAlex Crichton /// use wasmtime::component::{Linker, HasData};
216*f6775a33SAlex Crichton /// #
217*f6775a33SAlex Crichton /// # trait Host { }
218*f6775a33SAlex Crichton /// # impl<T: Host + ?Sized> Host for &mut T {}
219*f6775a33SAlex Crichton /// #
220*f6775a33SAlex Crichton /// # fn add_to_linker<T, D>(linker: &mut Linker<T>, getter: fn(&mut T) -> D::Data<'_>)
221*f6775a33SAlex Crichton /// #     where D: HasData,
222*f6775a33SAlex Crichton /// #           for<'a> D::Data<'a>: Host,
223*f6775a33SAlex Crichton /// # {
224*f6775a33SAlex Crichton /// # let _ = (linker, getter);
225*f6775a33SAlex Crichton /// # }
226*f6775a33SAlex Crichton ///
227*f6775a33SAlex Crichton /// // This is your public trait which external users need to implement. This
228*f6775a33SAlex Crichton /// // can encapsulate any "core" functionality needed to implement
229*f6775a33SAlex Crichton /// // bindgen!-generated traits such as `Host` below.
230*f6775a33SAlex Crichton /// pub trait MyLibraryTrait {
231*f6775a33SAlex Crichton ///     // ...
232*f6775a33SAlex Crichton /// }
233*f6775a33SAlex Crichton ///
234*f6775a33SAlex Crichton /// // You'll need to provide a "forwarding" implementation of this trait from
235*f6775a33SAlex Crichton /// // `&mut T` to `T` to get the below implementation to compile.
236*f6775a33SAlex Crichton /// impl<T: MyLibraryTrait + ?Sized> MyLibraryTrait for &mut T {
237*f6775a33SAlex Crichton ///     // ...
238*f6775a33SAlex Crichton /// }
239*f6775a33SAlex Crichton ///
240*f6775a33SAlex Crichton /// // This is a bit of a "hack" and an unfortunate workaround, but is currently
241*f6775a33SAlex Crichton /// // used to work within the confines of orphan rules and such. This is
242*f6775a33SAlex Crichton /// // publicly exposed as the function provided below must provide access to
243*f6775a33SAlex Crichton /// // this.
244*f6775a33SAlex Crichton /// pub struct MyLibraryImpl<T>(pub T);
245*f6775a33SAlex Crichton ///
246*f6775a33SAlex Crichton /// // Here you'd implement all of `Host` in terms of `MyLibraryTrait`.
247*f6775a33SAlex Crichton /// // Functions with `&mut self` would use `self.0` to access the functionality
248*f6775a33SAlex Crichton /// // in `MyLibraryTrait`.
249*f6775a33SAlex Crichton /// impl<T: MyLibraryTrait> Host for MyLibraryImpl<T> {
250*f6775a33SAlex Crichton ///     // ..
251*f6775a33SAlex Crichton /// }
252*f6775a33SAlex Crichton ///
253*f6775a33SAlex Crichton /// // optional: this avoids the need for `self.0` accessors in `Host` above,
254*f6775a33SAlex Crichton /// // but this otherwise isn't required.
255*f6775a33SAlex Crichton /// impl<T: MyLibraryTrait> MyLibraryTrait for MyLibraryImpl<T> {
256*f6775a33SAlex Crichton ///     // ..
257*f6775a33SAlex Crichton /// }
258*f6775a33SAlex Crichton ///
259*f6775a33SAlex Crichton /// // Note the second type parameter on this method, `U`, which is the user's
260*f6775a33SAlex Crichton /// // implementation of `MyLibraryTrait`. Note that this additionally must
261*f6775a33SAlex Crichton /// // be bounded with `'static` here.
262*f6775a33SAlex Crichton /// pub fn add_my_library_to_linker<T, U>(
263*f6775a33SAlex Crichton ///     linker: &mut Linker<T>,
264*f6775a33SAlex Crichton ///     f: fn(&mut T) -> MyLibraryImpl<&mut U>,
265*f6775a33SAlex Crichton /// )
266*f6775a33SAlex Crichton ///     where U: MyLibraryTrait + 'static,
267*f6775a33SAlex Crichton /// {
268*f6775a33SAlex Crichton ///     add_to_linker::<_, MyLibrary<U>>(linker, f);
269*f6775a33SAlex Crichton /// }
270*f6775a33SAlex Crichton ///
271*f6775a33SAlex Crichton /// // An adjusted definition of `MyLibrary` relative to the previous example,
272*f6775a33SAlex Crichton /// // still private, which hooks up all the types used here.
273*f6775a33SAlex Crichton /// struct MyLibrary<U>(U);
274*f6775a33SAlex Crichton ///
275*f6775a33SAlex Crichton /// impl<U: 'static> HasData for MyLibrary<U> {
276*f6775a33SAlex Crichton ///     type Data<'a> = MyLibraryImpl<&'a mut U>;
277*f6775a33SAlex Crichton /// }
278*f6775a33SAlex Crichton /// ```
279*f6775a33SAlex Crichton ///
280*f6775a33SAlex Crichton /// This iteration of implementing component-interfaces-as-a-library is
281*f6775a33SAlex Crichton /// unfortunately relatively verbose and unintuitive at this time. We're always
282*f6775a33SAlex Crichton /// keen on improving this though, so if you've got ideas of how to improve this
283*f6775a33SAlex Crichton /// please let us know!
284*f6775a33SAlex Crichton ///
285*f6775a33SAlex Crichton /// [`bindgen!`]: super::bindgen
286*f6775a33SAlex Crichton /// [`Linker`]: super::Linker
287*f6775a33SAlex Crichton /// [`Store<T>`]: crate::Store
288*f6775a33SAlex Crichton pub trait HasData: 'static {
289*f6775a33SAlex Crichton     /// The data associated with this trait implementation, chiefly used as a
290*f6775a33SAlex Crichton     /// generic associated type to allow plumbing the `'a` lifetime into the
291*f6775a33SAlex Crichton     /// definition here.
292*f6775a33SAlex Crichton     ///
293*f6775a33SAlex Crichton     /// See the trait documentation for more examples.
294*f6775a33SAlex Crichton     type Data<'a>;
295*f6775a33SAlex Crichton }
296*f6775a33SAlex Crichton 
297*f6775a33SAlex Crichton /// A convenience implementation of the [`HasData`] trait when the data
298*f6775a33SAlex Crichton /// associated with an implementation is `&mut T`.
299*f6775a33SAlex Crichton ///
300*f6775a33SAlex Crichton /// For more examples on using this see the [`HasData`] trait.
301*f6775a33SAlex Crichton pub struct HasSelf<T: ?Sized>(core::marker::PhantomData<T>);
302*f6775a33SAlex Crichton 
303*f6775a33SAlex Crichton impl<T: ?Sized + 'static> HasData for HasSelf<T> {
304*f6775a33SAlex Crichton     type Data<'a> = &'a mut T;
305*f6775a33SAlex Crichton }
306