wasmtime/runtime/component/
has_data.rs

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