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}