libgir/analysis/
safety_assertion_mode.rs

1use std::str::FromStr;
2
3use crate::{analysis::function_parameters::Parameters, env::Env, library};
4
5#[derive(Default, Clone, Copy, Debug, Eq, PartialEq)]
6pub enum SafetyAssertionMode {
7    #[default]
8    None,
9    Skip,
10    NotInitialized,
11    InMainThread,
12}
13
14impl std::fmt::Display for SafetyAssertionMode {
15    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
16        match self {
17            SafetyAssertionMode::None => f.write_str(""),
18            SafetyAssertionMode::NotInitialized => f.write_str("assert_not_initialized!();"),
19            SafetyAssertionMode::Skip => f.write_str("skip_assert_initialized!();"),
20            SafetyAssertionMode::InMainThread => f.write_str("assert_initialized_main_thread!();"),
21        }
22    }
23}
24
25impl FromStr for SafetyAssertionMode {
26    type Err = String;
27    fn from_str(name: &str) -> Result<SafetyAssertionMode, String> {
28        match name {
29            "none" => Ok(Self::None),
30            "skip" => Ok(Self::Skip),
31            "not-initialized" => Ok(Self::NotInitialized),
32            "in-main-thread" => Ok(Self::InMainThread),
33            _ => Err(format!("Unknown safety assertion mode '{name}'")),
34        }
35    }
36}
37
38impl SafetyAssertionMode {
39    pub fn of(env: &Env, is_method: bool, params: &Parameters) -> Self {
40        use crate::library::Type::*;
41        if !env.config.generate_safety_asserts {
42            return Self::None;
43        }
44        if is_method {
45            return Self::None;
46        }
47        for par in &params.rust_parameters {
48            let c_par = &params.c_parameters[par.ind_c];
49            match env.library.type_(c_par.typ) {
50                Class(..) | Interface(..)
51                    if !*c_par.nullable && c_par.typ.ns_id == library::MAIN_NAMESPACE =>
52                {
53                    return Self::Skip
54                }
55                _ => (),
56            }
57        }
58
59        Self::InMainThread
60    }
61
62    pub fn is_none(self) -> bool {
63        matches!(self, Self::None)
64    }
65}