Skip to main content

gir_parser/
record.rs

1use xmlserde_derives::XmlDeserialize;
2
3use crate::{
4    attribute::Attribute,
5    callable::Callable,
6    documentation::{DocDeprecated, DocStability, DocVersion, Documentation, SourcePosition},
7    field::Field,
8    function::{Function, FunctionInline},
9    method::{Method, MethodInline},
10    prelude::*,
11    union::Union,
12    version::Version,
13    Callback, Stability,
14};
15
16#[derive(Clone, Debug, PartialEq, Eq, XmlDeserialize)]
17// FIXME: The `Type` / `AnyType` fields are quite huge and some boxing would
18// probably be useful here but `xmlserde` does not seem to support that.
19#[allow(clippy::large_enum_variant)]
20pub enum RecordField {
21    #[xmlserde(name = b"field")]
22    Field(Field),
23    #[xmlserde(name = b"union")]
24    Union(Union),
25    #[xmlserde(name = b"record")]
26    Record(Record),
27    #[xmlserde(name = b"callback")]
28    Callback(Callback),
29}
30
31#[derive(Clone, Debug, PartialEq, Eq, XmlDeserialize)]
32#[xmlserde(root = b"record")]
33#[xmlserde(deny_unknown_fields)]
34pub struct Record {
35    #[xmlserde(name = b"name", ty = "attr")]
36    name: Option<String>,
37    #[xmlserde(name = b"c:type", ty = "attr")]
38    c_type: Option<String>,
39    /// Deprecated and replaced by `opaque` & `pointer`
40    #[xmlserde(name = b"disguised", ty = "attr")]
41    disguised: Option<bool>,
42    #[xmlserde(name = b"pointer", ty = "attr")]
43    pointer: Option<bool>,
44    #[xmlserde(name = b"opaque", ty = "attr")]
45    opaque: Option<bool>,
46    #[xmlserde(name = b"foreign", ty = "attr")]
47    foreign: Option<bool>,
48    #[xmlserde(name = b"glib:is-gtype-struct-for", ty = "attr")]
49    g_is_gtype_struct_for: Option<String>,
50    #[xmlserde(name = b"glib:type-name", ty = "attr")]
51    g_type_name: Option<String>,
52    #[xmlserde(name = b"glib:get-type", ty = "attr")]
53    g_get_type: Option<String>,
54    #[xmlserde(name = b"c:symbol-prefix", ty = "attr")]
55    symbol_prefix: Option<String>,
56    #[xmlserde(name = b"copy-function", ty = "attr")]
57    copy_function: Option<String>,
58    #[xmlserde(name = b"free-function", ty = "attr")]
59    free_function: Option<String>,
60
61    // Common attributes
62    #[xmlserde(name = b"introspectable", ty = "attr")]
63    introspectable: Option<bool>,
64    #[xmlserde(name = b"deprecated", ty = "attr")]
65    deprecated: Option<bool>,
66    #[xmlserde(name = b"version", ty = "attr")]
67    version: Option<Version>,
68    #[xmlserde(name = b"deprecated-version", ty = "attr")]
69    deprecated_version: Option<Version>,
70    #[xmlserde(name = b"stability", ty = "attr")]
71    stability: Option<Stability>,
72    // Documentation
73    #[xmlserde(name = b"doc", ty = "child")]
74    doc: Option<Documentation>,
75    #[xmlserde(name = b"doc-deprecated", ty = "child")]
76    doc_deprecated: Option<DocDeprecated>,
77    #[xmlserde(name = b"doc-stability", ty = "child")]
78    doc_stability: Option<DocStability>,
79    #[xmlserde(name = b"doc-version", ty = "child")]
80    doc_version: Option<DocVersion>,
81    #[xmlserde(name = b"source-position", ty = "child")]
82    source_position: Option<SourcePosition>,
83    // Attributes: 0 or more
84    #[xmlserde(name = b"attribute", ty = "child")]
85    attributes: Vec<Attribute>,
86
87    #[xmlserde(name = b"function-inline", ty = "child")]
88    inline_functions: Vec<FunctionInline>,
89
90    #[xmlserde(name = b"inline-methods", ty = "child")]
91    inline_methods: Vec<MethodInline>,
92
93    #[xmlserde(ty = "untag")]
94    fields: Vec<RecordField>,
95    #[xmlserde(ty = "untag")]
96    callables: Vec<Callable>,
97}
98
99impl Record {
100    pub fn name(&self) -> Option<&str> {
101        self.name.as_deref()
102    }
103
104    pub fn c_type(&self) -> Option<&str> {
105        self.c_type.as_deref()
106    }
107
108    pub fn is_disguised(&self) -> bool {
109        self.disguised.unwrap_or(false)
110    }
111
112    pub fn is_opaque(&self) -> bool {
113        self.opaque.unwrap_or(false)
114    }
115
116    pub fn is_pointer(&self) -> bool {
117        self.pointer.unwrap_or(false)
118    }
119
120    pub fn is_foreign(&self) -> bool {
121        self.foreign.unwrap_or(false)
122    }
123
124    pub fn g_is_gtype_struct_for(&self) -> Option<&str> {
125        self.g_is_gtype_struct_for.as_deref()
126    }
127
128    pub fn g_type_name(&self) -> Option<&str> {
129        self.g_type_name.as_deref()
130    }
131
132    pub fn g_get_type(&self) -> Option<&str> {
133        self.g_get_type.as_deref()
134    }
135
136    pub fn symbol_prefix(&self) -> Option<&str> {
137        self.symbol_prefix.as_deref()
138    }
139
140    pub fn copy_function(&self) -> Option<&str> {
141        self.copy_function.as_deref()
142    }
143
144    pub fn free_function(&self) -> Option<&str> {
145        self.free_function.as_deref()
146    }
147
148    pub fn fields(&self) -> &[RecordField] {
149        &self.fields
150    }
151
152    pub fn callables(&self) -> &[Callable] {
153        &self.callables
154    }
155
156    pub fn methods(&self) -> impl Iterator<Item = &Method> {
157        self.callables.iter().filter_map(|c| match c {
158            Callable::Method(m) => Some(m),
159            _ => None,
160        })
161    }
162
163    pub fn inlined_methods(&self) -> &[MethodInline] {
164        &self.inline_methods
165    }
166
167    pub fn functions(&self) -> impl Iterator<Item = &Function> {
168        self.callables.iter().filter_map(|c| match c {
169            Callable::Function(f) => Some(f),
170            _ => None,
171        })
172    }
173
174    pub fn inlined_functions(&self) -> &[FunctionInline] {
175        &self.inline_functions
176    }
177
178    pub fn constructors(&self) -> impl Iterator<Item = &Function> {
179        self.callables.iter().filter_map(|c| match c {
180            Callable::Constructor(f) => Some(f),
181            _ => None,
182        })
183    }
184}
185
186impl_info!(Record);
187impl_attributable!(Record);
188impl_documentable!(Record);