libgir/analysis/
c_type.rs
1use log::trace;
2
3use crate::{env::Env, library::TypeId};
4
5pub fn rustify_pointers(c_type: &str) -> (String, String) {
6 let mut input = c_type.trim();
7 let leading_const = input.starts_with("const ");
8 if leading_const {
9 input = &input[6..];
10 }
11 let end = [
12 input.find(" const"),
13 input.find("*const"),
14 input.find('*'),
15 Some(input.len()),
16 ]
17 .iter()
18 .filter_map(|&x| x)
19 .min()
20 .unwrap();
21 let inner = input[..end].trim().into();
22
23 let mut ptrs: Vec<_> = input[end..]
24 .rsplit('*')
25 .skip(1)
26 .map(|s| {
27 if s.contains("const") {
28 "*const"
29 } else {
30 "*mut"
31 }
32 })
33 .collect();
34 if let (true, Some(p)) = (leading_const, ptrs.last_mut()) {
35 *p = "*const";
36 }
37
38 let res = (ptrs.join(" "), inner);
39 trace!("rustify `{}` -> `{}` `{}`", c_type, res.0, res.1);
40 res
41}
42
43pub fn is_mut_ptr(c_type: &str) -> bool {
44 let (ptr, _inner) = rustify_pointers(c_type);
45 ptr.find("*mut") == Some(0)
46}
47
48pub fn implements_c_type(env: &Env, tid: TypeId, c_type: &str) -> bool {
49 env.class_hierarchy
50 .supertypes(tid)
51 .iter()
52 .any(|&super_tid| env.library.type_(super_tid).get_glib_name() == Some(c_type))
53}
54
55#[cfg(test)]
56mod tests {
57 use super::rustify_pointers as rustify_ptr;
58
59 fn s(x: &str, y: &str) -> (String, String) {
60 (x.into(), y.into())
61 }
62
63 #[test]
64 fn rustify_pointers() {
65 assert_eq!(rustify_ptr("char"), s("", "char"));
66 assert_eq!(rustify_ptr("char*"), s("*mut", "char"));
67 assert_eq!(rustify_ptr("const char*"), s("*const", "char"));
68 assert_eq!(rustify_ptr("char const*"), s("*const", "char"));
69 assert_eq!(rustify_ptr("char const *"), s("*const", "char"));
70 assert_eq!(rustify_ptr(" char * * "), s("*mut *mut", "char"));
71 assert_eq!(rustify_ptr("const char**"), s("*mut *const", "char"));
72 assert_eq!(rustify_ptr("char const**"), s("*mut *const", "char"));
73 assert_eq!(
74 rustify_ptr("const char* const*"),
75 s("*const *const", "char")
76 );
77 assert_eq!(
78 rustify_ptr("char const * const *"),
79 s("*const *const", "char")
80 );
81 assert_eq!(rustify_ptr("char* const*"), s("*const *mut", "char"));
82
83 assert_eq!(rustify_ptr("GtkWidget*"), s("*mut", "GtkWidget"));
84 }
85}