Skip to main content

gir_parser/
interface.rs

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