Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_reflect/src/std_traits.rs
9367 views
1
//! Module containing the [`ReflectDefault`] type.
2
3
use alloc::boxed::Box;
4
use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, RemAssign, Sub, SubAssign};
5
6
use crate::{FromType, Reflect};
7
8
/// A struct used to provide the default value of a type.
9
///
10
/// A [`ReflectDefault`] for type `T` can be obtained via [`FromType::from_type`].
11
#[derive(Clone)]
12
pub struct ReflectDefault {
13
default: fn() -> Box<dyn Reflect>,
14
}
15
16
impl ReflectDefault {
17
/// Returns the default value for a type.
18
pub fn default(&self) -> Box<dyn Reflect> {
19
(self.default)()
20
}
21
}
22
23
impl<T: Reflect + Default> FromType<T> for ReflectDefault {
24
fn from_type() -> Self {
25
ReflectDefault {
26
default: || Box::<T>::default(),
27
}
28
}
29
}
30
31
/// A struct used to perform addition on reflected values.
32
///
33
/// A [`ReflectAdd`] for type `T` can be obtained via [`FromType::from_type`].
34
#[derive(Clone)]
35
pub struct ReflectAdd {
36
/// Function pointer implementing [`ReflectAdd::add()`].
37
pub add: fn(
38
Box<dyn Reflect>,
39
Box<dyn Reflect>,
40
) -> Result<Box<dyn Reflect>, (Box<dyn Reflect>, Box<dyn Reflect>)>,
41
}
42
43
impl ReflectAdd {
44
/// Adds two reflected values together, returning the result as a new reflected value.
45
///
46
/// # Errors
47
///
48
/// Returns `Err((a, b))` if the types are incompatible.
49
pub fn add(
50
&self,
51
a: Box<dyn Reflect>,
52
b: Box<dyn Reflect>,
53
) -> Result<Box<dyn Reflect>, (Box<dyn Reflect>, Box<dyn Reflect>)> {
54
(self.add)(a, b)
55
}
56
}
57
58
impl<T: Reflect + Add<Output: Reflect>> FromType<T> for ReflectAdd {
59
fn from_type() -> Self {
60
ReflectAdd {
61
add: |a: Box<dyn Reflect>, b: Box<dyn Reflect>| {
62
let (a, b) = match (a.downcast::<T>(), b.downcast::<T>()) {
63
(Ok(a), Ok(b)) => (a, b),
64
(a, b) => {
65
let a = a.map(|a| a as Box<dyn Reflect>).unwrap_or_else(|e| e);
66
let b = b.map(|b| b as Box<dyn Reflect>).unwrap_or_else(|e| e);
67
return Err((a, b));
68
}
69
};
70
Ok(Box::new(*a + *b))
71
},
72
}
73
}
74
}
75
76
/// A struct used to perform subtraction on reflected values.
77
///
78
/// A [`ReflectSub`] for type `T` can be obtained via [`FromType::from_type`].
79
#[derive(Clone)]
80
pub struct ReflectSub {
81
/// Function pointer implementing [`ReflectSub::sub()`].
82
pub sub: fn(
83
Box<dyn Reflect>,
84
Box<dyn Reflect>,
85
) -> Result<Box<dyn Reflect>, (Box<dyn Reflect>, Box<dyn Reflect>)>,
86
}
87
88
impl ReflectSub {
89
/// Subtracts two reflected values, returning the result as a new reflected value.
90
///
91
/// # Errors
92
///
93
/// Returns `Err((a, b))` if the types are incompatible.
94
pub fn sub(
95
&self,
96
a: Box<dyn Reflect>,
97
b: Box<dyn Reflect>,
98
) -> Result<Box<dyn Reflect>, (Box<dyn Reflect>, Box<dyn Reflect>)> {
99
(self.sub)(a, b)
100
}
101
}
102
103
impl<T: Reflect + Sub<Output: Reflect>> FromType<T> for ReflectSub {
104
fn from_type() -> Self {
105
ReflectSub {
106
sub: |a: Box<dyn Reflect>, b: Box<dyn Reflect>| {
107
let (a, b) = match (a.downcast::<T>(), b.downcast::<T>()) {
108
(Ok(a), Ok(b)) => (a, b),
109
(a, b) => {
110
let a = a.map(|a| a as Box<dyn Reflect>).unwrap_or_else(|e| e);
111
let b = b.map(|b| b as Box<dyn Reflect>).unwrap_or_else(|e| e);
112
return Err((a, b));
113
}
114
};
115
Ok(Box::new(*a - *b))
116
},
117
}
118
}
119
}
120
121
/// A struct used to perform multiplication on reflected values.
122
///
123
/// A [`ReflectMul`] for type `T` can be obtained via [`FromType::from_type`].
124
#[derive(Clone)]
125
pub struct ReflectMul {
126
/// Function pointer implementing [`ReflectMul::mul()`].
127
pub mul: fn(
128
Box<dyn Reflect>,
129
Box<dyn Reflect>,
130
) -> Result<Box<dyn Reflect>, (Box<dyn Reflect>, Box<dyn Reflect>)>,
131
}
132
133
impl ReflectMul {
134
/// Multiplies two reflected values, returning the result as a new reflected value.
135
///
136
/// # Errors
137
///
138
/// Returns `Err((a, b))` if the types are incompatible.
139
pub fn mul(
140
&self,
141
a: Box<dyn Reflect>,
142
b: Box<dyn Reflect>,
143
) -> Result<Box<dyn Reflect>, (Box<dyn Reflect>, Box<dyn Reflect>)> {
144
(self.mul)(a, b)
145
}
146
}
147
148
impl<T: Reflect + Mul<Output: Reflect>> FromType<T> for ReflectMul {
149
fn from_type() -> Self {
150
ReflectMul {
151
mul: |a: Box<dyn Reflect>, b: Box<dyn Reflect>| {
152
let (a, b) = match (a.downcast::<T>(), b.downcast::<T>()) {
153
(Ok(a), Ok(b)) => (a, b),
154
(a, b) => {
155
let a = a.map(|a| a as Box<dyn Reflect>).unwrap_or_else(|e| e);
156
let b = b.map(|b| b as Box<dyn Reflect>).unwrap_or_else(|e| e);
157
return Err((a, b));
158
}
159
};
160
Ok(Box::new(*a * *b))
161
},
162
}
163
}
164
}
165
166
/// A struct used to perform division on reflected values.
167
///
168
/// A [`ReflectDiv`] for type `T` can be obtained via [`FromType::from_type`].
169
#[derive(Clone)]
170
pub struct ReflectDiv {
171
/// Function pointer implementing [`ReflectDiv::div()`].
172
pub div: fn(
173
Box<dyn Reflect>,
174
Box<dyn Reflect>,
175
) -> Result<Box<dyn Reflect>, (Box<dyn Reflect>, Box<dyn Reflect>)>,
176
}
177
178
impl ReflectDiv {
179
/// Divides two reflected values, returning the result as a new reflected value.
180
///
181
/// # Errors
182
///
183
/// Returns `Err((a, b))` if the types are incompatible.
184
pub fn div(
185
&self,
186
a: Box<dyn Reflect>,
187
b: Box<dyn Reflect>,
188
) -> Result<Box<dyn Reflect>, (Box<dyn Reflect>, Box<dyn Reflect>)> {
189
(self.div)(a, b)
190
}
191
}
192
193
impl<T: Reflect + Div<Output: Reflect>> FromType<T> for ReflectDiv {
194
fn from_type() -> Self {
195
ReflectDiv {
196
div: |a: Box<dyn Reflect>, b: Box<dyn Reflect>| {
197
let (a, b) = match (a.downcast::<T>(), b.downcast::<T>()) {
198
(Ok(a), Ok(b)) => (a, b),
199
(a, b) => {
200
let a = a.map(|a| a as Box<dyn Reflect>).unwrap_or_else(|e| e);
201
let b = b.map(|b| b as Box<dyn Reflect>).unwrap_or_else(|e| e);
202
return Err((a, b));
203
}
204
};
205
Ok(Box::new(*a / *b))
206
},
207
}
208
}
209
}
210
211
/// A struct used to perform division on reflected values.
212
///
213
/// A [`ReflectDiv`] for type `T` can be obtained via [`FromType::from_type`].
214
#[derive(Clone)]
215
pub struct ReflectRem {
216
/// Function pointer implementing [`ReflectRem::rem()`].
217
pub rem: fn(
218
Box<dyn Reflect>,
219
Box<dyn Reflect>,
220
) -> Result<Box<dyn Reflect>, (Box<dyn Reflect>, Box<dyn Reflect>)>,
221
}
222
223
impl ReflectRem {
224
/// Computes the remainder of two reflected values, returning the result as
225
/// a new reflected value.
226
///
227
/// # Errors
228
///
229
/// Returns `Err((a, b))` if the types are incompatible.
230
pub fn rem(
231
&self,
232
a: Box<dyn Reflect>,
233
b: Box<dyn Reflect>,
234
) -> Result<Box<dyn Reflect>, (Box<dyn Reflect>, Box<dyn Reflect>)> {
235
(self.rem)(a, b)
236
}
237
}
238
239
impl<T: Reflect + Rem<Output: Reflect>> FromType<T> for ReflectRem {
240
fn from_type() -> Self {
241
ReflectRem {
242
rem: |a: Box<dyn Reflect>, b: Box<dyn Reflect>| {
243
let (a, b) = match (a.downcast::<T>(), b.downcast::<T>()) {
244
(Ok(a), Ok(b)) => (a, b),
245
(a, b) => {
246
let a = a.map(|a| a as Box<dyn Reflect>).unwrap_or_else(|e| e);
247
let b = b.map(|b| b as Box<dyn Reflect>).unwrap_or_else(|e| e);
248
return Err((a, b));
249
}
250
};
251
Ok(Box::new(*a % *b))
252
},
253
}
254
}
255
}
256
257
/// A struct used to perform addition assignment on reflected values.
258
///
259
/// A [`ReflectAddAssign`] for type `T` can be obtained via [`FromType::from_type`].
260
#[derive(Clone)]
261
pub struct ReflectAddAssign {
262
/// Function pointer implementing [`ReflectAddAssign::add_assign()`].
263
pub add_assign: fn(&mut dyn Reflect, Box<dyn Reflect>) -> Result<(), Option<Box<dyn Reflect>>>,
264
}
265
266
impl ReflectAddAssign {
267
/// Adds a reflected value to another reflected value in place.
268
///
269
/// # Errors
270
///
271
/// - Returns `Err(None)` if the first argument is of an incompatible type.
272
/// - Returns `Err(Some(b))` if the second argument is of an incompatible type.
273
pub fn add_assign(
274
&self,
275
a: &mut dyn Reflect,
276
b: Box<dyn Reflect>,
277
) -> Result<(), Option<Box<dyn Reflect>>> {
278
(self.add_assign)(a, b)
279
}
280
}
281
282
impl<T: Reflect + AddAssign> FromType<T> for ReflectAddAssign {
283
fn from_type() -> Self {
284
ReflectAddAssign {
285
add_assign: |a: &mut dyn Reflect, b: Box<dyn Reflect>| {
286
let Some(a) = a.downcast_mut::<T>() else {
287
return Err(None);
288
};
289
let b = match b.downcast::<T>() {
290
Ok(b) => b,
291
Err(b) => return Err(Some(b)),
292
};
293
*a += *b;
294
Ok(())
295
},
296
}
297
}
298
}
299
300
/// A struct used to perform subtraction assignment on reflected values.
301
///
302
/// A [`ReflectSubAssign`] for type `T` can be obtained via [`FromType::from_type`].
303
#[derive(Clone)]
304
pub struct ReflectSubAssign {
305
/// Function pointer implementing [`ReflectSubAssign::sub_assign()`].
306
pub sub_assign: fn(&mut dyn Reflect, Box<dyn Reflect>) -> Result<(), Option<Box<dyn Reflect>>>,
307
}
308
309
impl ReflectSubAssign {
310
/// Subtracts a reflected value from another reflected value in place.
311
///
312
/// # Errors
313
///
314
/// - Returns `Err(None)` if the first argument is of an incompatible type.
315
/// - Returns `Err(Some(b))` if the second argument is of an incompatible type.
316
pub fn sub_assign(
317
&self,
318
a: &mut dyn Reflect,
319
b: Box<dyn Reflect>,
320
) -> Result<(), Option<Box<dyn Reflect>>> {
321
(self.sub_assign)(a, b)
322
}
323
}
324
325
impl<T: Reflect + SubAssign> FromType<T> for ReflectSubAssign {
326
fn from_type() -> Self {
327
ReflectSubAssign {
328
sub_assign: |a: &mut dyn Reflect, b: Box<dyn Reflect>| {
329
let Some(a) = a.downcast_mut::<T>() else {
330
return Err(None);
331
};
332
let b = match b.downcast::<T>() {
333
Ok(b) => b,
334
Err(b) => return Err(Some(b)),
335
};
336
*a -= *b;
337
Ok(())
338
},
339
}
340
}
341
}
342
343
/// A struct used to perform multiplication assignment on reflected values.
344
///
345
/// A [`ReflectMulAssign`] for type `T` can be obtained via [`FromType::from_type`].
346
#[derive(Clone)]
347
pub struct ReflectMulAssign {
348
/// Function pointer implementing [`ReflectMulAssign::mul_assign()`].
349
pub mul_assign: fn(&mut dyn Reflect, Box<dyn Reflect>) -> Result<(), Option<Box<dyn Reflect>>>,
350
}
351
352
impl ReflectMulAssign {
353
/// Multiplies a reflected value by another reflected value in place.
354
///
355
/// # Errors
356
///
357
/// - Returns `Err(None)` if the first argument is of an incompatible type.
358
/// - Returns `Err(Some(b))` if the second argument is of an incompatible type.
359
pub fn mul_assign(
360
&self,
361
a: &mut dyn Reflect,
362
b: Box<dyn Reflect>,
363
) -> Result<(), Option<Box<dyn Reflect>>> {
364
(self.mul_assign)(a, b)
365
}
366
}
367
368
impl<T: Reflect + MulAssign> FromType<T> for ReflectMulAssign {
369
fn from_type() -> Self {
370
ReflectMulAssign {
371
mul_assign: |a: &mut dyn Reflect, b: Box<dyn Reflect>| {
372
let Some(a) = a.downcast_mut::<T>() else {
373
return Err(None);
374
};
375
let b = match b.downcast::<T>() {
376
Ok(b) => b,
377
Err(b) => return Err(Some(b)),
378
};
379
*a *= *b;
380
Ok(())
381
},
382
}
383
}
384
}
385
386
/// A struct used to perform division assignment on reflected values.
387
///
388
/// A [`ReflectDivAssign`] for type `T` can be obtained via [`FromType::from_type`].
389
#[derive(Clone)]
390
pub struct ReflectDivAssign {
391
/// Function pointer implementing [`ReflectDivAssign::div_assign()`].
392
pub div_assign: fn(&mut dyn Reflect, Box<dyn Reflect>) -> Result<(), Option<Box<dyn Reflect>>>,
393
}
394
395
impl ReflectDivAssign {
396
/// Divides a reflected value by another reflected value in place.
397
///
398
/// # Errors
399
///
400
/// - Returns `Err(None)` if the first argument is of an incompatible type.
401
/// - Returns `Err(Some(b))` if the second argument is of an incompatible type.
402
pub fn div_assign(
403
&self,
404
a: &mut dyn Reflect,
405
b: Box<dyn Reflect>,
406
) -> Result<(), Option<Box<dyn Reflect>>> {
407
(self.div_assign)(a, b)
408
}
409
}
410
411
impl<T: Reflect + DivAssign> FromType<T> for ReflectDivAssign {
412
fn from_type() -> Self {
413
ReflectDivAssign {
414
div_assign: |a: &mut dyn Reflect, b: Box<dyn Reflect>| {
415
let Some(a) = a.downcast_mut::<T>() else {
416
return Err(None);
417
};
418
let b = match b.downcast::<T>() {
419
Ok(b) => b,
420
Err(b) => return Err(Some(b)),
421
};
422
*a /= *b;
423
Ok(())
424
},
425
}
426
}
427
}
428
429
/// A struct used to perform remainder assignment on reflected values.
430
///
431
/// A [`ReflectRemAssign`] for type `T` can be obtained via [`FromType::from_type`].
432
#[derive(Clone)]
433
pub struct ReflectRemAssign {
434
/// Function pointer implementing [`ReflectRemAssign::rem_assign()`].
435
pub rem_assign: fn(&mut dyn Reflect, Box<dyn Reflect>) -> Result<(), Option<Box<dyn Reflect>>>,
436
}
437
438
impl ReflectRemAssign {
439
/// Computes the remainder of a reflected value by another reflected value in place.
440
///
441
/// # Errors
442
///
443
/// - Returns `Err(None)` if the first argument is of an incompatible type.
444
/// - Returns `Err(Some(b))` if the second argument is of an incompatible type.
445
pub fn rem_assign(
446
&self,
447
a: &mut dyn Reflect,
448
b: Box<dyn Reflect>,
449
) -> Result<(), Option<Box<dyn Reflect>>> {
450
(self.rem_assign)(a, b)
451
}
452
}
453
454
impl<T: Reflect + RemAssign> FromType<T> for ReflectRemAssign {
455
fn from_type() -> Self {
456
ReflectRemAssign {
457
rem_assign: |a: &mut dyn Reflect, b: Box<dyn Reflect>| {
458
let Some(a) = a.downcast_mut::<T>() else {
459
return Err(None);
460
};
461
let b = match b.downcast::<T>() {
462
Ok(b) => b,
463
Err(b) => return Err(Some(b)),
464
};
465
*a %= *b;
466
Ok(())
467
},
468
}
469
}
470
}
471
472