Skip to main content

gir_parser/
union.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    record::Record,
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 UnionField {
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"union")]
33#[xmlserde(deny_unknown_fields)]
34pub struct Union {
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    #[xmlserde(name = b"c:symbol-prefix", ty = "attr")]
40    c_symbol_prefix: Option<String>,
41    #[xmlserde(name = b"glib:type-name", ty = "attr")]
42    g_type_name: Option<String>,
43    #[xmlserde(name = b"glib:get-type", ty = "attr")]
44    g_get_type: Option<String>,
45    #[xmlserde(name = b"copy-function", ty = "attr")]
46    copy_function: Option<String>,
47    #[xmlserde(name = b"free-function", ty = "attr")]
48    free_function: Option<String>,
49    // Common attributes
50    #[xmlserde(name = b"introspectable", ty = "attr")]
51    introspectable: Option<bool>,
52    #[xmlserde(name = b"deprecated", ty = "attr")]
53    deprecated: Option<bool>,
54    #[xmlserde(name = b"version", ty = "attr")]
55    version: Option<Version>,
56    #[xmlserde(name = b"deprecated-version", ty = "attr")]
57    deprecated_version: Option<Version>,
58    #[xmlserde(name = b"stability", ty = "attr")]
59    stability: Option<Stability>,
60    // Documentation
61    #[xmlserde(name = b"doc", ty = "child")]
62    doc: Option<Documentation>,
63    #[xmlserde(name = b"doc-deprecated", ty = "child")]
64    doc_deprecated: Option<DocDeprecated>,
65    #[xmlserde(name = b"doc-stability", ty = "child")]
66    doc_stability: Option<DocStability>,
67    #[xmlserde(name = b"doc-version", ty = "child")]
68    doc_version: Option<DocVersion>,
69    #[xmlserde(name = b"source-position", ty = "child")]
70    source_position: Option<SourcePosition>,
71    // Attributes: 0 or more
72    #[xmlserde(name = b"attribute", ty = "child")]
73    attributes: Vec<Attribute>,
74
75    #[xmlserde(name = b"function-inline", ty = "child")]
76    inline_functions: Vec<FunctionInline>,
77
78    #[xmlserde(name = b"method-inline", ty = "child")]
79    inline_methods: Vec<MethodInline>,
80
81    #[xmlserde(ty = "untag")]
82    fields: Vec<UnionField>,
83    #[xmlserde(ty = "untag")]
84    callables: Vec<Callable>,
85}
86
87impl Union {
88    pub fn name(&self) -> Option<&str> {
89        self.name.as_deref()
90    }
91
92    pub fn c_type(&self) -> Option<&str> {
93        self.c_type.as_deref()
94    }
95
96    pub fn c_symbol_prefix(&self) -> Option<&str> {
97        self.c_symbol_prefix.as_deref()
98    }
99
100    pub fn g_type_name(&self) -> Option<&str> {
101        self.g_type_name.as_deref()
102    }
103
104    pub fn g_get_type(&self) -> Option<&str> {
105        self.g_get_type.as_deref()
106    }
107
108    pub fn copy_function(&self) -> Option<&str> {
109        self.copy_function.as_deref()
110    }
111
112    pub fn free_function(&self) -> Option<&str> {
113        self.free_function.as_deref()
114    }
115
116    pub fn fields(&self) -> &[UnionField] {
117        &self.fields
118    }
119
120    pub fn callables(&self) -> &[Callable] {
121        &self.callables
122    }
123
124    pub fn constructors(&self) -> impl Iterator<Item = &Function> {
125        self.callables.iter().filter_map(|c| match c {
126            Callable::Constructor(f) => Some(f),
127            _ => None,
128        })
129    }
130
131    pub fn inlined_methods(&self) -> &[MethodInline] {
132        &self.inline_methods
133    }
134
135    pub fn methods(&self) -> impl Iterator<Item = &Method> {
136        self.callables.iter().filter_map(|c| match c {
137            Callable::Method(m) => Some(m),
138            _ => None,
139        })
140    }
141
142    pub fn inlined_functions(&self) -> &[FunctionInline] {
143        &self.inline_functions
144    }
145
146    pub fn functions(&self) -> impl Iterator<Item = &Function> {
147        self.callables.iter().filter_map(|c| match c {
148            Callable::Function(f) => Some(f),
149            _ => None,
150        })
151    }
152}
153
154impl_info!(Union);
155impl_attributable!(Union);
156impl_documentable!(Union);