Skip to content

Commit 6cffda6

Browse files
committed
Refactor: extract repeated code in find_api_ptr.
1 parent fcd711b commit 6cffda6

File tree

1 file changed

+49
-30
lines changed

1 file changed

+49
-30
lines changed

gdnative-sys/src/lib.rs

Lines changed: 49 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -27,59 +27,78 @@ fn map_option_to_init_error<T>(t: Option<T>, message: &'static str) -> Result<T,
2727
}
2828
}
2929

30-
unsafe fn find_api_ptr(
31-
core_api: *const godot_gdnative_core_api_struct,
30+
unsafe fn find_version(
31+
mut api: *const godot_gdnative_api_struct,
3232
api_type: GDNATIVE_API_TYPES,
3333
version_major: u32,
3434
version_minor: u32,
35-
) -> Result<*const godot_gdnative_api_struct, InitError> {
35+
) -> Option<Result<*const godot_gdnative_api_struct, InitError>> {
3636
let mut got = None;
37-
let mut api = core_api as *const godot_gdnative_api_struct;
3837
if (*api).type_ as u32 == api_type as u32 {
3938
while !api.is_null() {
4039
// The boolean expression below SHOULD always be true;
4140
// we will double check to be safe.
4241
if (*api).type_ as u32 == api_type as u32 {
4342
let (major, minor) = ((*api).version.major, (*api).version.minor);
4443
if major == version_major && minor == version_minor {
45-
return Ok(api);
44+
return Some(Ok(api));
4645
} else {
4746
got = Some(godot_gdnative_api_version { major, minor });
4847
}
4948
}
5049
api = (*api).next;
5150
}
5251
}
53-
for i in 0..(*core_api).num_extensions {
54-
let mut extension =
55-
*(*core_api).extensions.offset(i as _) as *const godot_gdnative_api_struct;
56-
if (*extension).type_ as u32 == api_type as u32 {
57-
while !extension.is_null() {
58-
// The boolean expression below SHOULD always be true;
59-
// we will double check to be safe.
60-
if (*extension).type_ as u32 == api_type as u32 {
61-
let (major, minor) = ((*extension).version.major, (*extension).version.minor);
62-
if major == version_major && minor == version_minor {
63-
return Ok(extension);
64-
} else {
65-
got = Some(godot_gdnative_api_version { major, minor });
66-
}
67-
}
68-
extension = (*extension).next;
69-
}
70-
}
71-
}
72-
match got {
73-
Some(got) => Err(InitError::VersionMismatch {
52+
got.map(|got| {
53+
Err(InitError::VersionMismatch {
7454
want: godot_gdnative_api_version {
7555
major: version_major,
7656
minor: version_minor,
7757
},
7858
got,
7959
api_type,
80-
}),
81-
None => Err(InitError::Generic {
82-
message: format!("Couldn't find API struct with type {}", api_type),
83-
}),
60+
})
61+
})
62+
}
63+
64+
unsafe fn find_api_ptr(
65+
core_api: *const godot_gdnative_core_api_struct,
66+
api_type: GDNATIVE_API_TYPES,
67+
version_major: u32,
68+
version_minor: u32,
69+
) -> Result<*const godot_gdnative_api_struct, InitError> {
70+
let mut last_error = None;
71+
match find_version(
72+
core_api as *const godot_gdnative_api_struct,
73+
api_type,
74+
version_major,
75+
version_minor,
76+
) {
77+
Some(Ok(api)) => {
78+
return Ok(api);
79+
}
80+
Some(Err(error)) => {
81+
last_error = Some(error);
82+
}
83+
None => {}
84+
}
85+
for i in 0..(*core_api).num_extensions {
86+
match find_version(
87+
*(*core_api).extensions.offset(i as _),
88+
api_type,
89+
version_major,
90+
version_minor,
91+
) {
92+
Some(Ok(api)) => {
93+
return Ok(api);
94+
}
95+
Some(Err(error)) => {
96+
last_error = Some(error);
97+
}
98+
None => {}
99+
}
84100
}
101+
Err(last_error.unwrap_or(InitError::Generic {
102+
message: format!("Couldn't find API struct with type {}", api_type),
103+
}))
85104
}

0 commit comments

Comments
 (0)