1#![allow(
7 non_upper_case_globals,
8 non_camel_case_types,
9 non_snake_case,
10 improper_ctypes,
11 deref_nullptr,
12 clippy::style
13)]
14include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
15include!(concat!(env!("OUT_DIR"), "/api_wrapper.rs"));
16
17#[derive(Debug)]
18pub enum InitError {
19 VersionMismatch {
20 api_type: GDNATIVE_API_TYPES,
21 want: godot_gdnative_api_version,
22 got: godot_gdnative_api_version,
23 },
24 Generic {
25 message: String,
26 },
27}
28
29fn map_option_to_init_error<T>(t: Option<T>, message: &'static str) -> Result<T, InitError> {
30 match t {
31 Some(t) => Ok(t),
32 None => Err(InitError::Generic {
33 message: message.to_string(),
34 }),
35 }
36}
37
38#[allow(clippy::unnecessary_cast)] unsafe fn find_version(
40 mut api: *const godot_gdnative_api_struct,
41 api_type: GDNATIVE_API_TYPES,
42 version_major: u32,
43 version_minor: u32,
44) -> Option<Result<*const godot_gdnative_api_struct, InitError>> {
45 let mut got = None;
46 if (*api).type_ as u32 == api_type as u32 {
47 while !api.is_null() {
48 if (*api).type_ as u32 == api_type as u32 {
51 let (major, minor) = ((*api).version.major, (*api).version.minor);
52 if major == version_major && minor == version_minor {
53 return Some(Ok(api));
54 } else {
55 got = Some(godot_gdnative_api_version { major, minor });
56 }
57 }
58 api = (*api).next;
59 }
60 }
61 got.map(|got| {
62 Err(InitError::VersionMismatch {
63 want: godot_gdnative_api_version {
64 major: version_major,
65 minor: version_minor,
66 },
67 got,
68 api_type,
69 })
70 })
71}
72
73unsafe fn find_api_ptr(
74 core_api: *const godot_gdnative_core_api_struct,
75 api_type: GDNATIVE_API_TYPES,
76 version_major: u32,
77 version_minor: u32,
78) -> Result<*const godot_gdnative_api_struct, InitError> {
79 let mut last_error = None;
80 match find_version(
81 core_api as *const godot_gdnative_api_struct,
82 api_type,
83 version_major,
84 version_minor,
85 ) {
86 Some(Ok(api)) => {
87 return Ok(api);
88 }
89 Some(Err(error)) => {
90 last_error = Some(error);
91 }
92 None => {}
93 }
94 for i in 0..(*core_api).num_extensions {
95 match find_version(
96 *(*core_api).extensions.offset(i as _),
97 api_type,
98 version_major,
99 version_minor,
100 ) {
101 Some(Ok(api)) => {
102 return Ok(api);
103 }
104 Some(Err(error)) => {
105 last_error = Some(error);
106 }
107 None => {}
108 }
109 }
110 Err(last_error.unwrap_or(InitError::Generic {
111 message: format!("Couldn't find API struct with type {}", api_type),
112 }))
113}