csbindgen/
field_map.rs

1use std::{
2    cell::RefCell,
3    collections::{HashMap, HashSet},
4};
5
6#[derive(Clone, Debug)]
7pub struct FieldMap {
8    fields: HashMap<String, RefCell<HashSet<String>>>, // field_type_name -> DeclaringType(s)
9}
10
11impl FieldMap {
12    pub fn new() -> Self {
13        Self {
14            fields: HashMap::new(),
15        }
16    }
17
18    // type_name must be normalized
19    pub fn insert(&mut self, type_name: &String, field_type: &String) {
20        match self.fields.get(field_type) {
21            Some(x) => {
22                x.borrow_mut().insert(type_name.to_owned());
23            }
24            None => {
25                let map = RefCell::new(HashSet::new());
26                map.borrow_mut().insert(type_name.to_owned());
27
28                self.fields.insert(field_type.to_owned(), map);
29            }
30        }
31    }
32
33    pub fn exists_in_using_types(
34        &self,
35        struct_name: &String,
36        using_types: &HashSet<String>,
37        recursive_count: i32, // detect recrusive reference
38    ) -> bool {
39        if recursive_count >= 10 {
40            return false;
41        }
42
43        if using_types.contains(struct_name) {
44            return true;
45        }
46
47        // try to find declaring types
48        if let Some(x) = self.fields.get(struct_name) {
49            for name in x.borrow().iter() {
50                if self.exists_in_using_types(name, using_types, recursive_count + 1) {
51                    return true;
52                }
53            }
54        }
55
56        false
57    }
58}