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
288 pub 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.
301 pub struct HasSelf<T: ?Sized>(core::marker::PhantomData<T>);
302 
303 impl<T: ?Sized + 'static> HasData for HasSelf<T> {
304     type Data<'a> = &'a mut T;
305 }
306