mirror_mirror/foreign_impls/
via_scalar.rs1use core::num::NonZeroI128;
2use core::num::NonZeroI16;
3use core::num::NonZeroI32;
4use core::num::NonZeroI64;
5use core::num::NonZeroI8;
6use core::num::NonZeroU128;
7use core::num::NonZeroU16;
8use core::num::NonZeroU32;
9use core::num::NonZeroU64;
10use core::num::NonZeroU8;
11use core::num::NonZeroUsize;
12use core::time::Duration;
13
14macro_rules! impl_reflect_via_scalar {
15 ($ty:ty, $via_ty:ty, $get_fn:expr, $new_fn:expr $(,)?) => {
16 const _: () = {
17 use $crate::__private::*;
18
19 impl DescribeType for $ty {
20 fn build(graph: &mut TypeGraph) -> NodeId {
21 graph.get_or_build_node_with::<Self, _>(|graph| {
22 OpaqueNode::new::<Self>(Default::default(), graph)
23 })
24 }
25 }
26
27 impl Reflect for $ty {
28 trivial_reflect_methods!();
29
30 #[allow(clippy::redundant_closure_call)]
31 fn reflect_owned(self: Box<Self>) -> ReflectOwned {
32 ReflectOwned::Scalar(ScalarOwned::from($get_fn(&*self)))
33 }
34
35 #[allow(clippy::redundant_closure_call)]
36 fn reflect_ref(&self) -> ReflectRef<'_> {
37 ReflectRef::Scalar(ScalarRef::from($get_fn(self)))
38 }
39
40 fn reflect_mut(&mut self) -> ReflectMut<'_> {
41 ReflectMut::Opaque(self)
42 }
43
44 fn patch(&mut self, value: &dyn Reflect) {
45 if let Some(n) = Self::from_reflect(value) {
46 *self = n;
47 }
48 }
49
50 #[allow(clippy::redundant_closure_call)]
51 fn to_value(&self) -> Value {
52 $get_fn(self).to_value()
53 }
54
55 fn clone_reflect(&self) -> Box<dyn Reflect> {
56 Box::new(*self)
57 }
58
59 fn debug(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60 if f.alternate() {
61 write!(f, "{:#?}", self)
62 } else {
63 write!(f, "{:?}", self)
64 }
65 }
66 }
67
68 impl FromReflect for $ty {
69 fn from_reflect(reflect: &dyn Reflect) -> Option<Self> {
70 if let Some(n) = reflect.downcast_ref::<Self>() {
71 Some(*n)
72 } else {
73 <$via_ty>::from_reflect(reflect)
74 .and_then(|value| $new_fn(value).into_option())
75 }
76 }
77 }
78
79 impl From<$ty> for Value {
80 fn from(n: $ty) -> Self {
81 n.to_value()
82 }
83 }
84 };
85 };
86}
87
88impl_reflect_via_scalar! { NonZeroUsize, usize, |n: &NonZeroUsize| n.get(), Self::new }
89impl_reflect_via_scalar! { NonZeroU8, u8, |n: &NonZeroU8| n.get(), Self::new }
90impl_reflect_via_scalar! { NonZeroU16, u16, |n: &NonZeroU16| n.get(), Self::new }
91impl_reflect_via_scalar! { NonZeroU32, u32, |n: &NonZeroU32| n.get(), Self::new }
92impl_reflect_via_scalar! { NonZeroU64, u64, |n: &NonZeroU64| n.get(), Self::new }
93impl_reflect_via_scalar! { NonZeroU128, u128, |n: &NonZeroU128| n.get(), Self::new }
94impl_reflect_via_scalar! { NonZeroI8, i8, |n: &NonZeroI8| n.get(), Self::new }
95impl_reflect_via_scalar! { NonZeroI16, i16, |n: &NonZeroI16| n.get(), Self::new }
96impl_reflect_via_scalar! { NonZeroI32, i32, |n: &NonZeroI32| n.get(), Self::new }
97impl_reflect_via_scalar! { NonZeroI64, i64, |n: &NonZeroI64| n.get(), Self::new }
98impl_reflect_via_scalar! { NonZeroI128, i128, |n: &NonZeroI128| n.get(), Self::new }
99
100impl_reflect_via_scalar! { Duration, f32, |d: &Duration| d.as_secs_f32(), Self::from_secs_f32 }
101
102trait IntoOption<T> {
103 fn into_option(self) -> Option<T>;
104}
105
106impl<T> IntoOption<T> for Option<T> {
107 fn into_option(self) -> Option<T> {
108 self
109 }
110}
111
112impl<T> IntoOption<T> for T {
113 fn into_option(self) -> Option<T> {
114 Some(self)
115 }
116}
117
118#[cfg(test)]
119mod tests {
120 use super::*;
121 use crate::DescribeType;
122
123 #[test]
124 fn keeps_type_name() {
125 assert_eq!(
126 <NonZeroI8 as DescribeType>::type_descriptor()
127 .get_type()
128 .type_name(),
129 "core::num::nonzero::NonZero<i8>"
130 );
131
132 assert_eq!(
133 <Duration as DescribeType>::type_descriptor()
134 .get_type()
135 .type_name(),
136 "core::time::Duration"
137 );
138 }
139}