libgir/config/
virtual_methods.rs

1use std::collections::HashSet;
2
3use log::error;
4use toml::Value;
5
6use super::{
7    error::TomlHelper,
8    functions::{check_rename, Parameters, Return},
9    gobjects::GStatus,
10    ident::Ident,
11    parsable::{Parsable, Parse},
12};
13use crate::version::Version;
14
15#[derive(Clone, Debug)]
16pub struct VirtualMethod {
17    pub ident: Ident,
18    pub status: GStatus,
19    pub version: Option<Version>,
20    pub cfg_condition: Option<String>,
21    pub parameters: Parameters,
22    pub ret: Return,
23    pub doc_hidden: bool,
24    pub doc_ignore_parameters: HashSet<String>,
25    pub doc_trait_name: Option<String>,
26    pub unsafe_: bool,
27    pub rename: Option<String>,
28    pub bypass_auto_rename: bool,
29    pub generate_doc: bool,
30}
31
32impl Parse for VirtualMethod {
33    fn parse(toml: &Value, object_name: &str) -> Option<Self> {
34        let Some(ident) = Ident::parse(toml, object_name, "virtual_method") else {
35            error!(
36                "No 'name' or 'pattern' given for virtual_method for object {}",
37                object_name
38            );
39            return None;
40        };
41        toml.check_unwanted(
42            &[
43                "ignore",
44                "manual",
45                "version",
46                "cfg_condition",
47                "parameter",
48                "return",
49                "name",
50                "doc_hidden",
51                "doc_ignore_parameters",
52                "pattern",
53                "doc_trait_name",
54                "unsafe",
55                "rename",
56                "bypass_auto_rename",
57                "generate_doc",
58            ],
59            &format!("virtual_method {object_name}"),
60        );
61
62        let status = {
63            if toml
64                .lookup("ignore")
65                .and_then(Value::as_bool)
66                .unwrap_or(false)
67            {
68                GStatus::Ignore
69            } else if toml
70                .lookup("manual")
71                .and_then(Value::as_bool)
72                .unwrap_or(false)
73            {
74                GStatus::Manual
75            } else {
76                GStatus::Generate
77            }
78        };
79        let version = toml
80            .lookup("version")
81            .and_then(Value::as_str)
82            .and_then(|s| s.parse().ok());
83        let cfg_condition = toml
84            .lookup("cfg_condition")
85            .and_then(Value::as_str)
86            .map(ToOwned::to_owned);
87        let parameters = Parameters::parse(toml.lookup("parameter"), object_name);
88        let ret = Return::parse(toml.lookup("return"), object_name);
89        let doc_hidden = toml
90            .lookup("doc_hidden")
91            .and_then(Value::as_bool)
92            .unwrap_or(false);
93        let doc_ignore_parameters = toml
94            .lookup_vec("doc_ignore_parameters", "Invalid doc_ignore_parameters")
95            .map(|v| {
96                v.iter()
97                    .filter_map(|v| v.as_str().map(String::from))
98                    .collect()
99            })
100            .unwrap_or_default();
101        let doc_trait_name = toml
102            .lookup("doc_trait_name")
103            .and_then(Value::as_str)
104            .map(ToOwned::to_owned);
105        let unsafe_ = toml
106            .lookup("unsafe")
107            .and_then(Value::as_bool)
108            .unwrap_or(false);
109        let rename = toml
110            .lookup("rename")
111            .and_then(Value::as_str)
112            .map(ToOwned::to_owned);
113        if !check_rename(&rename, object_name, &ident) {
114            return None;
115        }
116        let bypass_auto_rename = toml
117            .lookup("bypass_auto_rename")
118            .and_then(Value::as_bool)
119            .unwrap_or(false);
120
121        let generate_doc = toml
122            .lookup("generate_doc")
123            .and_then(Value::as_bool)
124            .unwrap_or(true);
125        Some(Self {
126            ident,
127            status,
128            version,
129            cfg_condition,
130            parameters,
131            ret,
132            doc_hidden,
133            doc_ignore_parameters,
134            doc_trait_name,
135            unsafe_,
136            rename,
137            bypass_auto_rename,
138            generate_doc,
139        })
140    }
141}
142
143impl AsRef<Ident> for VirtualMethod {
144    fn as_ref(&self) -> &Ident {
145        &self.ident
146    }
147}
148
149pub type VirtualMethods = Vec<VirtualMethod>;
150
151#[cfg(test)]
152mod tests {
153    use super::{super::ident::Ident, *};
154
155    fn toml(input: &str) -> ::toml::Value {
156        let value = ::toml::from_str(input);
157        assert!(value.is_ok());
158        value.unwrap()
159    }
160
161    #[test]
162    fn function_parse_ignore() {
163        let toml = toml(
164            r#"
165name = "func1"
166ignore = true
167"#,
168        );
169        let f = VirtualMethod::parse(&toml, "a").unwrap();
170        assert_eq!(f.ident, Ident::Name("func1".into()));
171        assert!(f.status.ignored());
172    }
173
174    #[test]
175    fn function_parse_manual() {
176        let toml = toml(
177            r#"
178name = "func1"
179manual = true
180"#,
181        );
182        let f = VirtualMethod::parse(&toml, "a").unwrap();
183        assert_eq!(f.ident, Ident::Name("func1".into()));
184        assert!(f.status.manual());
185    }
186}