libgir/analysis/
namespaces.rs

1use std::ops::Index;
2
3use crate::{library, nameutil, version::Version};
4
5pub type NsId = u16;
6pub const MAIN: NsId = library::MAIN_NAMESPACE;
7pub const INTERNAL: NsId = library::INTERNAL_NAMESPACE;
8
9#[derive(Debug)]
10pub struct Namespace {
11    pub name: String,
12    pub crate_name: String,
13    pub sys_crate_name: String,
14    pub higher_crate_name: String,
15    pub package_names: Vec<String>,
16    pub symbol_prefixes: Vec<String>,
17    pub shared_libs: Vec<String>,
18    pub versions: Vec<Version>,
19}
20
21#[derive(Debug)]
22pub struct Info {
23    namespaces: Vec<Namespace>,
24    pub is_glib_crate: bool,
25    pub glib_ns_id: NsId,
26}
27
28impl Info {
29    pub fn main(&self) -> &Namespace {
30        &self[MAIN]
31    }
32}
33
34impl Index<NsId> for Info {
35    type Output = Namespace;
36
37    fn index(&self, index: NsId) -> &Namespace {
38        &self.namespaces[index as usize]
39    }
40}
41
42pub fn run(gir: &library::Library) -> Info {
43    let mut namespaces = Vec::with_capacity(gir.namespaces.len());
44    let mut is_glib_crate = false;
45    let mut glib_ns_id = None;
46
47    for (ns_id, ns) in gir.namespaces.iter().enumerate() {
48        let ns_id = ns_id as NsId;
49        let crate_name = nameutil::crate_name(&ns.name);
50        let (sys_crate_name, higher_crate_name) = match crate_name.as_str() {
51            "gobject" => ("gobject_ffi".to_owned(), "glib".to_owned()),
52            _ => ("ffi".to_owned(), crate_name.clone()),
53        };
54        namespaces.push(Namespace {
55            name: ns.name.clone(),
56            crate_name,
57            sys_crate_name,
58            higher_crate_name,
59            package_names: ns.package_names.clone(),
60            symbol_prefixes: ns.symbol_prefixes.clone(),
61            shared_libs: ns.shared_library.clone(),
62            versions: ns.versions.iter().copied().collect(),
63        });
64        if ns.name == "GLib" {
65            glib_ns_id = Some(ns_id);
66            if ns_id == MAIN {
67                is_glib_crate = true;
68            }
69        } else if ns.name == "GObject" && ns_id == MAIN {
70            is_glib_crate = true;
71        }
72    }
73
74    Info {
75        namespaces,
76        is_glib_crate,
77        glib_ns_id: glib_ns_id.expect("Missing `GLib` namespace!"),
78    }
79}