Skip to main content

wit_bindgen/
resource.rs

1//! Helper traits, types, and utilities for managing resources in the component
2//! model.
3
4/// A trait implemented by all resources that a component might export.
5///
6/// This is an implementation detail primarily for the code generated by
7/// exported resources. The primary purpose of this trait is to serve as an
8/// abstraction for the in-memory storage of a resource.
9pub trait Resource: Sized + 'static {
10    /// The type which is actually stored in-memory for this resource.
11    ///
12    /// By default this is `Option<T>`.
13    type Rep: ResourceRep<Self>;
14}
15
16impl<T: 'static> Resource for T {
17    type Rep = Option<T>;
18}
19
20/// A trait used to define how to access the underlying data `T` from an
21/// in-memory representation.
22///
23/// This is used as a bound on the [`Resource::Rep`] associated type which is in
24/// turn used to access data within a resources.
25pub unsafe trait ResourceRep<T> {
26    /// Creates a new instance of `Self` which wraps the provided data.
27    fn rep_new(inner: T) -> Self;
28
29    /// Acquires `&T` from a raw pointer to `Self`.
30    unsafe fn rep_as_ref<'a>(ptr: *const Self) -> &'a T;
31
32    /// Acquires `&mut T` from a raw pointer to `Self`.
33    unsafe fn rep_as_mut<'a>(ptr: *mut Self) -> &'a mut T;
34
35    /// Takes the value out of `Self` at the provided pointer.
36    ///
37    /// Note that `ptr` will later be deallocated meaning that it must not run
38    /// the destructor of `T` after this method is called. This is guaranteed to
39    /// be called at most once, however. Additionally after calling this method
40    /// it's guaranteed that the `rep_as_*` method above will not be called.
41    unsafe fn rep_take<'a>(ptr: *mut Self) -> T;
42}
43
44unsafe impl<T> ResourceRep<T> for Option<T> {
45    fn rep_new(inner: T) -> Option<T> {
46        Some(inner)
47    }
48    unsafe fn rep_as_ref<'a>(ptr: *const Option<T>) -> &'a T {
49        unsafe { (*ptr).as_ref().unwrap() }
50    }
51    unsafe fn rep_as_mut<'a>(ptr: *mut Option<T>) -> &'a mut T {
52        unsafe { (*ptr).as_mut().unwrap() }
53    }
54    unsafe fn rep_take(ptr: *mut Option<T>) -> T {
55        unsafe { (*ptr).take().unwrap() }
56    }
57}