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