1
1
#![ allow( clippy:: cargo_common_metadata) ]
2
2
3
+ use std:: marker:: PhantomData ;
4
+
3
5
use libffi:: middle:: Type ;
4
6
use mlua:: prelude:: * ;
5
7
@@ -8,106 +10,104 @@ use super::c_helper::get_ensured_size;
8
10
use super :: c_ptr:: CPtr ;
9
11
use crate :: ffi:: ffi_helper:: get_ptr_from_userdata;
10
12
11
- pub struct CType {
13
+ pub struct CType < T : ? Sized > {
12
14
// for ffi_ptrarray_to_raw?
13
15
// libffi_cif: Cif,
14
16
libffi_type : Type ,
15
17
size : usize ,
16
- name : Option < String > ,
17
-
18
- // Write converted data from luavalue into some ptr
19
- pub luavalue_into_ptr : fn ( value : LuaValue , ptr : * mut ( ) ) -> LuaResult < ( ) > ,
20
-
21
- // Read luavalue from some ptr
22
- pub ptr_into_luavalue : fn ( lua : & Lua , ptr : * mut ( ) ) -> LuaResult < LuaValue > ,
18
+ name : Option < & ' static str > ,
19
+ _phantom : PhantomData < T > ,
23
20
}
24
21
25
- impl CType {
26
- pub fn new (
27
- libffi_type : Type ,
28
- name : Option < String > ,
29
- luavalue_into_ptr : fn ( value : LuaValue , ptr : * mut ( ) ) -> LuaResult < ( ) > ,
30
- ptr_into_luavalue : fn ( lua : & Lua , ptr : * mut ( ) ) -> LuaResult < LuaValue > ,
31
- ) -> LuaResult < Self > {
22
+ impl < T > CType < T >
23
+ where
24
+ T : ?Sized ,
25
+ {
26
+ pub fn new_with_libffi_type ( libffi_type : Type , name : Option < & ' static str > ) -> LuaResult < Self > {
32
27
// let libffi_cfi = Cif::new(vec![libffi_type.clone()], Type::void());
33
28
let size = get_ensured_size ( libffi_type. as_raw_ptr ( ) ) ?;
34
29
Ok ( Self {
35
30
// libffi_cif: libffi_cfi,
36
31
libffi_type,
37
32
size,
38
33
name,
39
- luavalue_into_ptr,
40
- ptr_into_luavalue,
34
+ _phantom : PhantomData { } ,
41
35
} )
42
36
}
43
37
44
- pub fn get_type ( & self ) -> Type {
45
- self . libffi_type . clone ( )
38
+ pub fn get_type ( & self ) -> & Type {
39
+ & self . libffi_type
46
40
}
47
41
48
- pub fn stringify ( & self ) -> String {
49
- match & self . name {
50
- Some ( t) => t. to_owned ( ) ,
51
- None => String :: from ( "unnamed" ) ,
42
+ pub fn stringify ( & self ) -> & str {
43
+ match self . name {
44
+ Some ( t) => t,
45
+ None => "unnamed" ,
52
46
}
53
47
}
48
+ }
49
+
50
+ pub trait PtrHandle {
51
+ // Convert luavalue into data, then write into ptr
52
+ fn luavalue_into_ptr ( value : LuaValue , ptr : * mut ( ) ) -> LuaResult < ( ) > ;
53
+
54
+ // Read data from ptr, then convert into luavalue
55
+ fn ptr_into_luavalue ( lua : & Lua , ptr : * mut ( ) ) -> LuaResult < LuaValue > ;
54
56
55
- // Read data from ptr and convert it into luavalue
56
- pub unsafe fn read_ptr < ' lua > (
57
+ // Read data from userdata (such as box or ref) and convert it into luavalue
58
+ unsafe fn read_userdata < ' lua > (
57
59
& self ,
58
60
lua : & ' lua Lua ,
59
61
userdata : LuaAnyUserData < ' lua > ,
60
62
offset : Option < isize > ,
61
63
) -> LuaResult < LuaValue < ' lua > > {
62
64
let ptr = unsafe { get_ptr_from_userdata ( & userdata, offset) ? } ;
63
- let value = ( self . ptr_into_luavalue ) ( lua, ptr) ?;
65
+ let value = Self :: ptr_into_luavalue ( lua, ptr) ?;
64
66
Ok ( value)
65
67
}
66
68
67
- // Write converted data from luavalue into ptr
68
- pub unsafe fn write_ptr < ' lua > (
69
+ // Write data into userdata (such as box or ref) from luavalue
70
+ unsafe fn write_userdata < ' lua > (
69
71
& self ,
70
72
luavalue : LuaValue < ' lua > ,
71
73
userdata : LuaAnyUserData < ' lua > ,
72
74
offset : Option < isize > ,
73
75
) -> LuaResult < ( ) > {
74
76
let ptr = unsafe { get_ptr_from_userdata ( & userdata, offset) ? } ;
75
- ( self . luavalue_into_ptr ) ( luavalue, ptr) ?;
77
+ Self :: luavalue_into_ptr ( luavalue, ptr) ?;
76
78
Ok ( ( ) )
77
79
}
78
80
}
79
81
80
- impl LuaUserData for CType {
82
+ impl < T > LuaUserData for CType < T >
83
+ where
84
+ Self : Sized + PtrHandle ,
85
+ {
81
86
fn add_fields < ' lua , F : LuaUserDataFields < ' lua , Self > > ( fields : & mut F ) {
82
87
fields. add_field_method_get ( "size" , |_, this| Ok ( this. size ) ) ;
83
88
}
84
89
85
90
fn add_methods < ' lua , M : LuaUserDataMethods < ' lua , Self > > ( methods : & mut M ) {
86
91
methods. add_function ( "ptr" , |lua, this : LuaAnyUserData | {
87
- let pointer = CPtr :: from_lua_userdata ( lua, & this) ?;
88
- Ok ( pointer)
92
+ CPtr :: from_lua_userdata ( lua, & this)
89
93
} ) ;
90
94
methods. add_method (
91
95
"from" ,
92
- |lua, ctype, ( userdata, offset) : ( LuaAnyUserData , Option < isize > ) | {
93
- let value = unsafe { ctype. read_ptr ( lua, userdata, offset) ? } ;
94
- Ok ( value)
96
+ |lua, ctype, ( userdata, offset) : ( LuaAnyUserData , Option < isize > ) | unsafe {
97
+ ctype. read_userdata ( lua, userdata, offset)
95
98
} ,
96
99
) ;
97
100
methods. add_method (
98
101
"into" ,
99
- |_, ctype, ( value, userdata, offset) : ( LuaValue , LuaAnyUserData , Option < isize > ) | {
100
- unsafe { ctype. write_ptr ( value, userdata, offset) ? } ;
101
- Ok ( ( ) )
102
+ |_, ctype, ( value, userdata, offset) : ( LuaValue , LuaAnyUserData , Option < isize > ) | unsafe {
103
+ ctype. write_userdata ( value, userdata, offset)
102
104
} ,
103
105
) ;
104
106
methods. add_function ( "arr" , |lua, ( this, length) : ( LuaAnyUserData , usize ) | {
105
- let carr = CArr :: from_lua_userdata ( lua, & this, length) ?;
106
- Ok ( carr)
107
+ CArr :: from_lua_userdata ( lua, & this, length)
107
108
} ) ;
108
- methods. add_meta_method ( LuaMetaMethod :: ToString , |_, this, ( ) | {
109
- let name = this. stringify ( ) ;
110
- Ok ( name)
109
+ methods. add_meta_method ( LuaMetaMethod :: ToString , |lua, this, ( ) | {
110
+ lua. create_string ( this. stringify ( ) )
111
111
} ) ;
112
112
}
113
113
}
0 commit comments