1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
use super::utils;
use syn::*;
use quote::Tokens;
pub trait ParamHandler {
fn arg_ty(
&self, ty : &Ty
) -> Tokens
{
quote!( #ty )
}
fn for_call(
&self, ident : &Ident, _ty : &Ty
) -> Tokens
{
quote!( #ident.into() )
}
fn write_out(
&self, ident : &Ident, _ty : &Ty
) -> Tokens
{
quote!( *#ident = r.into(); )
}
fn write_null(
&self, ident : &Ident, ty : &Ty
) -> Tokens
{
match ty {
&Ty::Path( _, ref p ) => {
let name : &str = &p.segments.last().unwrap().ident.as_ref();
match name {
"c_void" => quote!( *#ident = std::ptr::null_mut() ),
"RawComPtr" => quote!( *#ident = std::ptr::null_mut() ),
"ComRc" => quote!( *#ident = std::ptr::null_mut() ),
_ => quote!( *#ident = Default::default(); )
}
},
_ => quote!( *#ident = Default::default(); )
}
}
}
struct IdentityParam;
impl ParamHandler for IdentityParam { }
struct ComRcParam;
impl ParamHandler for ComRcParam {
fn arg_ty(
&self, _ : &Ty
) -> Tokens
{
quote!( intercom::RawComPtr )
}
fn write_out(
&self, ident : &Ident, ty : &Ty
) -> Tokens
{
let none_tokens = quote!( );
let comrc_params = match ty {
&Ty::Path( _, ref p ) => {
let last_segment = &p.segments.last().unwrap();
match last_segment.parameters {
PathParameters::AngleBracketed( ref data ) => data,
_ => return none_tokens
}
}
_ => return none_tokens
};
let itf_ty = match comrc_params.types.first() {
Some( ty ) => ty,
_ => return none_tokens
};
let itf_ident = match utils::get_ty_ident( itf_ty ) {
Some( ty_ident ) => ty_ident,
None => panic!()
};
let iid_ident = super::idents::iid( &itf_ident );
quote!(
intercom::ComRc::query_interface(
&r, &#iid_ident, #ident ) )
}
}
struct StringParam;
impl ParamHandler for StringParam
{
fn arg_ty(
&self, _ : &Ty
) -> Tokens
{
quote!( intercom::BStr )
}
fn for_call(
&self, ident : &Ident, _ty : &Ty
) -> Tokens
{
quote!( #ident.bstr_to_string() )
}
fn write_out(
&self, ident : &Ident, _ty : &Ty
) -> Tokens
{
quote!( *#ident = intercom::BStr::string_to_bstr( &r ) )
}
}
pub fn get_param_handler(
arg_ty : &Ty,
) -> Box<ParamHandler>
{
match arg_ty {
&Ty::Path( _, ref p ) => {
let name : &str = &p.segments.last().unwrap().ident.as_ref();
match name {
"ComRc" => Box::new( ComRcParam ),
"String" => Box::new( StringParam ),
_ => Box::new( IdentityParam )
}
},
_ => Box::new( IdentityParam )
}
}