1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
macro_rules! define_object_subtype {
(
$(#[$meta:meta])*
$ty_sub:ident: $ty_super:ident
) => {
$(#[$meta])*
#[derive(Debug, Clone, Copy)]
pub struct $ty_sub<'a> {
object: $ty_super<'a>,
}
impl<'a> $ty_sub<'a> {
pub(crate) fn new(object: $ty_super<'a>) -> Self {
Self { object }
}
}
impl<'a> std::ops::Deref for $ty_sub<'a> {
type Target = $ty_super<'a>;
fn deref(&self) -> &Self::Target {
&self.object
}
}
}
}
macro_rules! define_typed_handle {
(
$(#[$outer_meta:meta])*
$outer:ident($inner_def:ident) {
$(
$(#[$variant_meta:meta])*
($class:pat, $subclass:pat) => $variant:ident($inner:ident),
)*
}
) => {
$(#[$outer_meta])*
#[derive(Debug, Clone, Copy)]
pub enum $outer<'a> {
$(
$(#[$variant_meta])*
$variant($inner<'a>),
)*
Unknown($inner_def<'a>),
#[doc(hidden)]
__Nonexhaustive,
}
impl<'a> $outer<'a> {
pub(crate) fn new(obj: $inner_def<'a>) -> Self {
match (obj.class(), obj.subclass()) {
$(
($class, $subclass) => $outer::$variant(<$inner<'_>>::new(obj)),
)*
_ => $outer::Unknown(obj),
}
}
}
impl<'a> std::ops::Deref for $outer<'a> {
type Target = $inner_def<'a>;
fn deref(&self) -> &Self::Target {
match self {
$(
$outer::$variant(o) => &**o,
)*
$outer::Unknown(o) => o,
$outer::__Nonexhaustive => panic!("`__Nonexhaustive` should not be used"),
}
}
}
};
}
macro_rules! impl_prop_proxy_getters {
($(
$(#[$meta:meta])*
$prop:ident -> $ty:ty {
name = $name:expr,
loader = $loader:expr,
description = $description:expr,
default: {
$(#[$meta_default:meta])*
$prop_default:ident = $default_value: expr
}
}
)*) => {
$(
$(#[$meta])*
pub fn $prop(&self) -> Result<Option<$ty>, anyhow::Error> {
self.properties
.get_property($name)
.map(|p| p.load_value($loader))
.transpose()
.map_err(|e| anyhow::format_err!("Failed to load {}: {}", $description, e))
}
$(#[$meta_default])*
pub fn $prop_default(&self) -> Result<$ty, anyhow::Error> {
self.$prop().map(|v| v.unwrap_or($default_value))
}
)*
};
}