oo_bindgen/backend/dotnet/conversion/
type_info.rs

1use crate::model::*;
2
3const INT_PTR_STRING: &str = "IntPtr";
4
5/// provides information about a type
6pub(crate) trait TypeInfo {
7    /// Returns the .NET natural type
8    fn get_dotnet_type(&self) -> String;
9    /// Return the .NET representation of the native C type
10    fn get_native_type(&self) -> String;
11}
12
13impl TypeInfo for DurationType {
14    fn get_dotnet_type(&self) -> String {
15        "TimeSpan".to_string()
16    }
17
18    fn get_native_type(&self) -> String {
19        "ulong".to_string()
20    }
21}
22
23impl TypeInfo for Primitive {
24    fn get_dotnet_type(&self) -> String {
25        match self {
26            Self::Bool => "bool".to_string(),
27            Self::U8 => "byte".to_string(),
28            Self::S8 => "sbyte".to_string(),
29            Self::U16 => "ushort".to_string(),
30            Self::S16 => "short".to_string(),
31            Self::U32 => "uint".to_string(),
32            Self::S32 => "int".to_string(),
33            Self::U64 => "ulong".to_string(),
34            Self::S64 => "long".to_string(),
35            Self::Float => "float".to_string(),
36            Self::Double => "double".to_string(),
37        }
38    }
39
40    fn get_native_type(&self) -> String {
41        match self {
42            Self::Bool => "byte".to_string(),
43            Self::U8 => "byte".to_string(),
44            Self::S8 => "sbyte".to_string(),
45            Self::U16 => "ushort".to_string(),
46            Self::S16 => "short".to_string(),
47            Self::U32 => "uint".to_string(),
48            Self::S32 => "int".to_string(),
49            Self::U64 => "ulong".to_string(),
50            Self::S64 => "long".to_string(),
51            Self::Float => "float".to_string(),
52            Self::Double => "double".to_string(),
53        }
54    }
55}
56
57impl<D> TypeInfo for Handle<Enum<D>>
58where
59    D: DocReference,
60{
61    fn get_dotnet_type(&self) -> String {
62        self.name.camel_case()
63    }
64
65    fn get_native_type(&self) -> String {
66        self.name.camel_case()
67    }
68}
69
70impl TypeInfo for BasicType {
71    fn get_dotnet_type(&self) -> String {
72        match self {
73            Self::Primitive(x) => x.get_dotnet_type(),
74            Self::Duration(x) => x.get_dotnet_type(),
75            Self::Enum(x) => x.get_dotnet_type(),
76        }
77    }
78
79    fn get_native_type(&self) -> String {
80        match self {
81            Self::Primitive(x) => x.get_native_type(),
82            Self::Duration(x) => x.get_native_type(),
83            Self::Enum(x) => x.get_native_type(),
84        }
85    }
86}
87
88impl TypeInfo for StringType {
89    fn get_dotnet_type(&self) -> String {
90        "string".to_string()
91    }
92
93    fn get_native_type(&self) -> String {
94        INT_PTR_STRING.to_string()
95    }
96}
97
98pub(crate) fn base_functor_type<D>(cb: &CallbackFunction<D>) -> &'static str
99where
100    D: DocReference,
101{
102    if cb.return_type.is_none() {
103        "Action"
104    } else {
105        "Func"
106    }
107}
108
109pub(crate) fn full_functor_type<D>(cb: &CallbackFunction<D>) -> String
110where
111    D: DocReference,
112{
113    fn arg_types<D>(args: &[Arg<CallbackArgument, D>]) -> String
114    where
115        D: DocReference,
116    {
117        args.iter()
118            .map(|x| x.arg_type.get_dotnet_type())
119            .collect::<Vec<String>>()
120            .join(", ")
121    }
122
123    match (&cb.return_type.get_value(), cb.arguments.as_slice()) {
124        (None, []) => "Action".to_string(),
125        (None, args) => {
126            format!("Action<{}>", arg_types(args))
127        }
128        (Some(t), []) => {
129            format!("Func<{}>", t.get_dotnet_type())
130        }
131        (Some(t), args) => {
132            format!("Func<{}, {}>", arg_types(args), t.get_dotnet_type())
133        }
134    }
135}
136
137impl<D> TypeInfo for Handle<Interface<D>>
138where
139    D: DocReference,
140{
141    fn get_dotnet_type(&self) -> String {
142        if let Some(cb) = self.get_functional_callback() {
143            if cb.functional_transform.enabled() {
144                return full_functor_type(cb);
145            }
146        }
147
148        format!("I{}", self.name.camel_case())
149    }
150
151    fn get_native_type(&self) -> String {
152        format!("I{}NativeAdapter", self.name.camel_case())
153    }
154}
155
156impl TypeInfo for ClassDeclarationHandle {
157    fn get_dotnet_type(&self) -> String {
158        self.name.camel_case()
159    }
160
161    fn get_native_type(&self) -> String {
162        INT_PTR_STRING.to_string()
163    }
164}
165
166impl<D> TypeInfo for Handle<Collection<D>>
167where
168    D: DocReference,
169{
170    fn get_dotnet_type(&self) -> String {
171        format!(
172            "System.Collections.Generic.ICollection<{}>",
173            self.item_type.get_dotnet_type()
174        )
175    }
176
177    fn get_native_type(&self) -> String {
178        INT_PTR_STRING.to_string()
179    }
180}
181
182impl<D> TypeInfo for Handle<AbstractIterator<D>>
183where
184    D: DocReference,
185{
186    fn get_dotnet_type(&self) -> String {
187        match &self.item_type {
188            IteratorItemType::Primitive(x) => {
189                format!(
190                    "System.Collections.Generic.ICollection<{}>",
191                    x.get_dotnet_type()
192                )
193            }
194            IteratorItemType::Struct(x) => {
195                format!(
196                    "System.Collections.Generic.ICollection<{}>",
197                    x.name().camel_case()
198                )
199            }
200        }
201    }
202
203    fn get_native_type(&self) -> String {
204        INT_PTR_STRING.to_string()
205    }
206}
207
208impl<T> TypeInfo for UniversalOr<T>
209where
210    T: StructFieldType,
211{
212    fn get_dotnet_type(&self) -> String {
213        match self {
214            UniversalOr::Specific(x) => x.get_dotnet_type(),
215            UniversalOr::Universal(x) => x.get_dotnet_type(),
216        }
217    }
218
219    fn get_native_type(&self) -> String {
220        match self {
221            UniversalOr::Specific(x) => x.get_native_type(),
222            UniversalOr::Universal(x) => x.get_native_type(),
223        }
224    }
225}
226
227impl TypeInfo for FunctionArgStructField {
228    fn get_dotnet_type(&self) -> String {
229        match self {
230            FunctionArgStructField::Basic(x) => x.get_dotnet_type(),
231            FunctionArgStructField::String(x) => x.get_dotnet_type(),
232            FunctionArgStructField::Interface(x) => x.inner.get_dotnet_type(),
233            FunctionArgStructField::Struct(x) => x.get_dotnet_type(),
234        }
235    }
236
237    fn get_native_type(&self) -> String {
238        match self {
239            FunctionArgStructField::Basic(x) => x.get_native_type(),
240            FunctionArgStructField::String(x) => x.get_native_type(),
241            FunctionArgStructField::Interface(x) => x.inner.get_native_type(),
242            FunctionArgStructField::Struct(x) => x.get_native_type(),
243        }
244    }
245}
246
247impl TypeInfo for FunctionReturnStructField {
248    fn get_dotnet_type(&self) -> String {
249        match self {
250            Self::Basic(x) => x.get_dotnet_type(),
251            Self::ClassRef(x) => x.get_dotnet_type(),
252            Self::Struct(x) => x.get_dotnet_type(),
253            Self::Iterator(x) => x.get_dotnet_type(),
254        }
255    }
256
257    fn get_native_type(&self) -> String {
258        match self {
259            Self::Basic(x) => x.get_native_type(),
260            Self::ClassRef(x) => x.get_native_type(),
261            Self::Struct(x) => x.get_native_type(),
262            Self::Iterator(x) => x.get_native_type(),
263        }
264    }
265}
266
267impl TypeInfo for CallbackArgStructField {
268    fn get_dotnet_type(&self) -> String {
269        match self {
270            Self::Basic(x) => x.get_dotnet_type(),
271            Self::Iterator(x) => x.get_dotnet_type(),
272            Self::Struct(x) => x.get_dotnet_type(),
273            Self::String(x) => x.get_dotnet_type(),
274        }
275    }
276
277    fn get_native_type(&self) -> String {
278        match self {
279            Self::Basic(x) => x.get_native_type(),
280            Self::Iterator(x) => x.get_native_type(),
281            Self::Struct(x) => x.get_native_type(),
282            Self::String(x) => x.get_native_type(),
283        }
284    }
285}
286
287impl TypeInfo for UniversalStructField {
288    fn get_dotnet_type(&self) -> String {
289        match self {
290            UniversalStructField::Basic(x) => x.get_dotnet_type(),
291            UniversalStructField::Struct(x) => x.get_dotnet_type(),
292            UniversalStructField::String(x) => x.get_dotnet_type(),
293        }
294    }
295
296    fn get_native_type(&self) -> String {
297        match self {
298            UniversalStructField::Basic(x) => x.get_native_type(),
299            UniversalStructField::Struct(x) => x.get_native_type(),
300            UniversalStructField::String(x) => x.get_native_type(),
301        }
302    }
303}
304
305impl TypeInfo for FunctionArgument {
306    fn get_dotnet_type(&self) -> String {
307        match self {
308            FunctionArgument::Basic(x) => x.get_dotnet_type(),
309            FunctionArgument::String(x) => x.get_dotnet_type(),
310            FunctionArgument::Collection(x) => x.get_dotnet_type(),
311            FunctionArgument::Struct(x) => x.get_dotnet_type(),
312            FunctionArgument::StructRef(x) => x.inner.get_dotnet_type(),
313            FunctionArgument::ClassRef(x) => x.get_dotnet_type(),
314            FunctionArgument::Interface(x) => x.get_dotnet_type(),
315        }
316    }
317
318    fn get_native_type(&self) -> String {
319        match self {
320            FunctionArgument::Basic(x) => x.get_native_type(),
321            FunctionArgument::String(x) => x.get_native_type(),
322            FunctionArgument::Collection(x) => x.get_native_type(),
323            FunctionArgument::Struct(x) => x.get_native_type(),
324            FunctionArgument::StructRef(x) => x.inner.get_native_type(),
325            FunctionArgument::ClassRef(x) => x.get_native_type(),
326            FunctionArgument::Interface(x) => x.get_native_type(),
327        }
328    }
329}
330
331impl TypeInfo for CallbackArgument {
332    fn get_dotnet_type(&self) -> String {
333        match self {
334            Self::Basic(x) => x.get_dotnet_type(),
335            Self::String(x) => x.get_dotnet_type(),
336            Self::Iterator(x) => x.get_dotnet_type(),
337            Self::Struct(x) => x.get_dotnet_type(),
338            Self::Class(x) => x.get_dotnet_type(),
339        }
340    }
341
342    fn get_native_type(&self) -> String {
343        match self {
344            Self::Basic(x) => x.get_native_type(),
345            Self::String(x) => x.get_native_type(),
346            Self::Iterator(x) => x.get_native_type(),
347            Self::Struct(x) => x.get_native_type(),
348            Self::Class(x) => x.get_native_type(),
349        }
350    }
351}
352
353impl TypeInfo for CallbackReturnValue {
354    fn get_dotnet_type(&self) -> String {
355        match self {
356            Self::Basic(x) => x.get_dotnet_type(),
357            Self::Struct(x) => x.get_dotnet_type(),
358        }
359    }
360
361    fn get_native_type(&self) -> String {
362        match self {
363            Self::Basic(x) => x.get_native_type(),
364            Self::Struct(x) => x.get_native_type(),
365        }
366    }
367}
368
369impl TypeInfo for PrimitiveRef {
370    fn get_dotnet_type(&self) -> String {
371        self.inner.get_dotnet_type()
372    }
373
374    fn get_native_type(&self) -> String {
375        INT_PTR_STRING.to_string()
376    }
377}
378
379impl TypeInfo for FunctionReturnValue {
380    fn get_dotnet_type(&self) -> String {
381        match self {
382            Self::Basic(x) => x.get_dotnet_type(),
383            Self::String(x) => x.get_dotnet_type(),
384            Self::ClassRef(x) => x.get_dotnet_type(),
385            Self::Struct(x) => x.get_dotnet_type(),
386            Self::StructRef(x) => x.untyped().get_dotnet_type(),
387            Self::PrimitiveRef(x) => x.get_dotnet_type(),
388        }
389    }
390
391    fn get_native_type(&self) -> String {
392        match self {
393            Self::Basic(x) => x.get_native_type(),
394            Self::String(x) => x.get_native_type(),
395            Self::ClassRef(x) => x.get_native_type(),
396            Self::Struct(x) => x.get_native_type(),
397            Self::StructRef(x) => x.untyped().get_native_type(),
398            Self::PrimitiveRef(x) => x.get_native_type(),
399        }
400    }
401}
402
403impl TypeInfo for StructDeclarationHandle {
404    fn get_dotnet_type(&self) -> String {
405        self.name.camel_case()
406    }
407
408    fn get_native_type(&self) -> String {
409        INT_PTR_STRING.to_string()
410    }
411}
412
413impl<T, D> TypeInfo for Handle<Struct<T, D>>
414where
415    D: DocReference,
416    T: StructFieldType,
417{
418    fn get_dotnet_type(&self) -> String {
419        self.name().camel_case()
420    }
421
422    fn get_native_type(&self) -> String {
423        format!("{}Native", self.name().camel_case())
424    }
425}
426
427const VOID: &str = "void";
428
429impl<T, D> TypeInfo for OptionalReturnType<T, D>
430where
431    D: DocReference,
432    T: Clone + TypeInfo,
433{
434    fn get_dotnet_type(&self) -> String {
435        match self.get_value() {
436            None => VOID.to_string(),
437            Some(x) => x.get_dotnet_type(),
438        }
439    }
440
441    fn get_native_type(&self) -> String {
442        match self.get_value() {
443            None => VOID.to_string(),
444            Some(x) => x.get_native_type(),
445        }
446    }
447}