1use crate::{ByteString, Bytes, storage::Storage};
2
3#[derive(Debug)]
5pub struct StorageVTable {
6 pub(crate) as_ptr: unsafe fn(*const u8, usize) -> *const u8,
7 pub(crate) len: unsafe fn(*const u8, usize) -> usize,
8 pub(crate) clone: unsafe fn(*const u8, usize) -> Option<(*const u8, usize)>,
9 pub(crate) drop: unsafe fn(*const u8, usize),
10}
11
12impl StorageVTable {
13 pub const fn new(
14 as_ptr: unsafe fn(*const u8, usize) -> *const u8,
15 len: unsafe fn(*const u8, usize) -> usize,
16 clone: unsafe fn(*const u8, usize) -> Option<(*const u8, usize)>,
17 drop: unsafe fn(*const u8, usize),
18 ) -> StorageVTable {
19 StorageVTable {
20 as_ptr,
21 len,
22 clone,
23 drop,
24 }
25 }
26}
27
28pub trait StorageExt: Send + Sync {
30 fn create(self) -> (*const u8, usize, &'static StorageVTable);
31}
32
33pub unsafe trait StorageExtStr: StorageExt + Sized {
38 fn create(self) -> (*const u8, usize, &'static StorageVTable) {
39 StorageExt::create(self)
40 }
41}
42
43impl Bytes {
44 pub fn from_ext<T: StorageExt>(val: T) -> Bytes {
45 let (addr, len, vtable) = val.create();
46
47 Bytes {
48 storage: Storage::from_stext(addr, len, vtable),
49 }
50 }
51}
52
53impl ByteString {
54 pub fn from_ext<T: StorageExtStr>(val: T) -> ByteString {
55 let (addr, len, vtable) = StorageExtStr::create(val);
56
57 unsafe {
58 ByteString::from_bytes_unchecked(Bytes {
59 storage: Storage::from_stext(addr, len, vtable),
60 })
61 }
62 }
63}