/// A trait used as part of [`bindgen!`] to indicate a `Data<'_>` payload that /// implements some host bindings traits. /// /// The purpose of the [`bindgen!`] macro is to define Rust traits that the host /// can implement to fulfill WIT functions imported from the host into a /// component. The [`bindgen!`] macro then additionally generates a function /// which takes a [`Linker`] and an implementation of the traits and fills out /// the [`Linker`]. This trait, [`HasData`], is used in this process of filling /// out the [`Linker`] for some WIT interfaces. /// /// Wasmtime's [`Store`] type is the home for all per-instance state. /// Notably the `T` here is generic (the Wasmtime library allows any type to be /// placed here) and it's also instance-specific as a [`Store`] is typically /// allocated one-per-instance. Implementations of host APIs, however, often /// want to live in a library and not be tied to any particular `T`. For example /// Wasmtime provides the `wasmtime-wasi` crates as an implementation of /// standard WASI APIs as a library, but they don't want to fix a particular `T` /// in [`Store`] as embedders should be able to fill out their own `T` for /// their needs. The purpose of this trait is to enable this situation. /// /// This trait is used in `add_to_linker` functions generated by [`bindgen!`] in /// conjunction with a function pointer. It looks something along the lines of: /// /// ``` /// use wasmtime::component::{Linker, HasData}; /// /// // generated by bindgen! /// trait Host { /// // .. /// } /// /// fn add_to_linker(linker: &mut Linker, getter: fn(&mut T) -> D::Data<'_>) /// where D: HasData, /// for<'a> D::Data<'a>: Host, /// { /// // ... /// # let _ = (linker, getter); /// } /// ``` /// /// Here the `D` type parameter, bounded by [`HasData`], is used to specify /// the return type of the `getter` function provided here. The `getter` /// "projects" from `&mut T` to `D::Data<'_>`, notably enabling it to capture /// the lifetime of the `&mut T` passed in as well. /// /// The `Data` associated type here is further bounded in `add_to_linker` above /// as it must implement the traits generated by [`bindgen!`]. This means that /// `linker` is filled out with functions that, when called, first `getter` is /// invoked and then the actual function delegates to the `Host` trait /// implementation in this case. /// /// The `D` type parameter here isn't actually a runtime value, nor is it stored /// anywhere. It's purely used as a means of projecting a "generic associated /// type", here where `<'a>` is the generic argument, a lifetime. This means /// that the choice of `D` is disconnected from both `T` and `D::Data<'_>` and /// can be whatever you like. Sometimes you might need to define an empty struct /// in your project to use this, but Wasmtime also provides a convenience /// [`HasSelf`] type to avoid the need for this in some common use cases. /// /// # Example: `Host for T` using `Store` /// /// Let's say you wanted to invoke the above `add_to_linker` function where the /// `T` in [`Store`] directly implements the `Host` trait itself: /// /// ``` /// use wasmtime::component::{Linker, HasSelf}; /// # use wasmtime::component::HasData; /// # /// # trait Host { } /// # impl Host for &mut T {} /// # /// # fn add_to_linker(linker: &mut Linker, getter: fn(&mut T) -> D::Data<'_>) /// # where D: HasData, /// # for<'a> D::Data<'a>: Host, /// # { /// # let _ = (linker, getter); /// # } /// /// struct MyStoreState { /* ... */ } /// /// impl Host for MyStoreState { /// // .. /// } /// /// fn fill_out_my_linker(linker: &mut Linker) { /// add_to_linker::<_, HasSelf<_>>(linker, |x| x) /// } /// ``` /// /// Here the `add_to_linker` invocation is annotated with `<_, HasSelf<_>>`. The /// first argument gets inferred to `MyStoreState`, and the second argument gets /// inferred to `HasSelf` This means that the projection function /// in this case, here the identity `|x| x`, is typed as /// `fn(&mut MyStoreState) -> &mut MyStoreState`. This is because the `HasData` /// implementation for `HasSelf` means that we have /// `type Data<'a> = &'a mut T`. /// /// # Example: `Host for MyLibraryState` using `Store` /// /// Let's say though that you instead are writing a library like WASI where you /// don't know the `T` of [`Store`] ahead of time. In such a case you might /// hand-write your own `add_to_linker` wrapper that looks like this: /// /// ``` /// use wasmtime::component::{Linker, HasData}; /// # /// # trait Host { } /// # impl Host for &mut T {} /// # /// # fn add_to_linker(linker: &mut Linker, getter: fn(&mut T) -> D::Data<'_>) /// # where D: HasData, /// # for<'a> D::Data<'a>: Host, /// # { /// # let _ = (linker, getter); /// # } /// /// // publicly exposed per-instance state for your library, users will /// // construct this and store it within the `T` in `Store` /// pub struct MyLibraryState { /* ... */ } /// /// impl Host for MyLibraryState { /// // .. /// } /// /// // hand-written publicly exposed convenience function to add this crate's /// // component functionality to the provided linker. /// pub fn add_my_library_to_linker( /// linker: &mut Linker, /// f: fn(&mut T) -> &mut MyLibraryState, /// ) { /// // invoke the bindgen!-generated `add_to_linker` /// add_to_linker::<_, MyLibrary>(linker, f); /// } /// /// // Note this need not be publicly exposed, it's just a private internal /// // detail. /// struct MyLibrary; /// /// impl HasData for MyLibrary { /// type Data<'a> = &'a mut MyLibraryState; /// } /// ``` /// /// Here the `MyLibrary` type, private to this crate, has a `HasData` /// implementation which indicates that implementations of the /// `bindgen!`-generated APIs are done in terms of `MyLibraryState` /// specifically. The `add_my_library_to_linker` takes an externally-provided /// `f` closure which projects from `&mut T`, whatever data the store is using, /// to `MyLibraryState` which must be stored within the store itself. /// /// # Example: `Host for MyLibraryState<'_>` using `Store` /// /// Let's say you're like the above scenario where you're writing a library but /// instead of being able to wrap up all your state for each trait /// implementation in a structure it's spread across a few structures. These /// structures may be stored in different locations inside of `Store` which /// makes it difficult to wrap up in a single type and return that. Here you can /// make use of "view" types to collect a number of disjoint borrows into one /// structure: /// /// ``` /// use wasmtime::component::{Linker, HasData}; /// # /// # trait Host { } /// # impl Host for &mut T {} /// # /// # fn add_to_linker(linker: &mut Linker, getter: fn(&mut T) -> D::Data<'_>) /// # where D: HasData, /// # for<'a> D::Data<'a>: Host, /// # { /// # let _ = (linker, getter); /// # } /// # struct StateA; /// # struct StateB; /// /// // Like before, this is publicly exposed, and this is a "bag of pointers" to /// // all the pieces of state necessary to implement `Host` below. /// pub struct MyLibraryState<'a> { /// pub state_a: &'a mut StateA, /// pub state_b: &'a mut StateB, /// } /// /// impl Host for MyLibraryState<'_> { /// // .. /// } /// /// pub fn add_my_library_to_linker( /// linker: &mut Linker, /// f: fn(&mut T) -> MyLibraryState<'_>, /// ) { /// // invoke the bindgen!-generated `add_to_linker` /// add_to_linker::<_, MyLibrary>(linker, f); /// } /// /// struct MyLibrary; /// /// impl HasData for MyLibrary { /// type Data<'a> = MyLibraryState<'a>; /// } /// ``` /// /// This is similar to the above example but shows using a lifetime parameter on /// a structure instead of using a pointer-with-a-lifetime only. Otherwise /// though this'll end up working out the same way. /// /// # Example: `Host for U: MyLibrary` using `Store` /// /// Let's say you're in a situation where you're a library which wants to create /// a "simpler" trait than the `Host`-generated traits from [`bindgen!`] and /// then you want to implement `Host` in terms of this trait. This requires a /// bit more boilerplate as well as a new custom structure, but doing so looks /// like this: /// /// ``` /// use wasmtime::component::{Linker, HasData}; /// # /// # trait Host { } /// # impl Host for &mut T {} /// # /// # fn add_to_linker(linker: &mut Linker, getter: fn(&mut T) -> D::Data<'_>) /// # where D: HasData, /// # for<'a> D::Data<'a>: Host, /// # { /// # let _ = (linker, getter); /// # } /// /// // This is your public trait which external users need to implement. This /// // can encapsulate any "core" functionality needed to implement /// // bindgen!-generated traits such as `Host` below. /// pub trait MyLibraryTrait { /// // ... /// } /// /// // You'll need to provide a "forwarding" implementation of this trait from /// // `&mut T` to `T` to get the below implementation to compile. /// impl MyLibraryTrait for &mut T { /// // ... /// } /// /// // This is a bit of a "hack" and an unfortunate workaround, but is currently /// // used to work within the confines of orphan rules and such. This is /// // publicly exposed as the function provided below must provide access to /// // this. /// pub struct MyLibraryImpl(pub T); /// /// // Here you'd implement all of `Host` in terms of `MyLibraryTrait`. /// // Functions with `&mut self` would use `self.0` to access the functionality /// // in `MyLibraryTrait`. /// impl Host for MyLibraryImpl { /// // .. /// } /// /// // optional: this avoids the need for `self.0` accessors in `Host` above, /// // but this otherwise isn't required. /// impl MyLibraryTrait for MyLibraryImpl { /// // .. /// } /// /// // Note the second type parameter on this method, `U`, which is the user's /// // implementation of `MyLibraryTrait`. Note that this additionally must /// // be bounded with `'static` here. /// pub fn add_my_library_to_linker( /// linker: &mut Linker, /// f: fn(&mut T) -> MyLibraryImpl<&mut U>, /// ) /// where U: MyLibraryTrait + 'static, /// { /// add_to_linker::<_, MyLibrary>(linker, f); /// } /// /// // An adjusted definition of `MyLibrary` relative to the previous example, /// // still private, which hooks up all the types used here. /// struct MyLibrary(U); /// /// impl HasData for MyLibrary { /// type Data<'a> = MyLibraryImpl<&'a mut U>; /// } /// ``` /// /// This iteration of implementing component-interfaces-as-a-library is /// unfortunately relatively verbose and unintuitive at this time. We're always /// keen on improving this though, so if you've got ideas of how to improve this /// please let us know! /// /// [`bindgen!`]: super::bindgen /// [`Linker`]: super::Linker /// [`Store`]: crate::Store pub trait HasData: 'static { /// The data associated with this trait implementation, chiefly used as a /// generic associated type to allow plumbing the `'a` lifetime into the /// definition here. /// /// See the trait documentation for more examples. type Data<'a>; } /// A convenience implementation of the [`HasData`] trait when the data /// associated with an implementation is `&mut T`. /// /// For more examples on using this see the [`HasData`] trait. pub struct HasSelf(core::marker::PhantomData); impl HasData for HasSelf { type Data<'a> = &'a mut T; }