1use crate::core::{
2 BufferMut, BufferRef, CreateFrom, Metadata, ReadFrom, Reader, ShaderSize, ShaderType,
3 WriteInto, Writer,
4};
5use core::num::{NonZeroI32, NonZeroU32, Wrapping};
6use core::sync::atomic::{AtomicI32, AtomicU32};
7
8macro_rules! impl_basic_traits {
9 ($type:ty) => {
10 impl_basic_traits!(__main, $type, );
11 };
12 ($type:ty, is_pod) => {
13 impl_basic_traits!(__main, $type, .pod());
14 };
15 (__main, $type:ty, $($tail:tt)*) => {
16 impl ShaderType for $type {
17 type ExtraMetadata = ();
18 const METADATA: Metadata<Self::ExtraMetadata> = Metadata::from_alignment_and_size(4, 4) $($tail)*;
19 }
20
21 impl ShaderSize for $type {}
22 };
23}
24
25macro_rules! impl_traits_for_pod {
26 ($type:ty) => {
27 impl_basic_traits!($type, is_pod);
28
29 impl WriteInto for $type {
30 #[inline]
31 fn write_into<B: BufferMut>(&self, writer: &mut Writer<B>) {
32 writer.write(&<$type>::to_le_bytes(*self));
33 }
34 }
35
36 impl ReadFrom for $type {
37 #[inline]
38 fn read_from<B: BufferRef>(&mut self, reader: &mut Reader<B>) {
39 *self = <$type>::from_le_bytes(*reader.read());
40 }
41 }
42
43 impl CreateFrom for $type {
44 #[inline]
45 fn create_from<B: BufferRef>(reader: &mut Reader<B>) -> Self {
46 <$type>::from_le_bytes(*reader.read())
47 }
48 }
49 };
50}
51
52impl_traits_for_pod!(f32);
53impl_traits_for_pod!(u32);
54impl_traits_for_pod!(i32);
55
56macro_rules! impl_traits_for_non_zero_option {
57 ($type:ty) => {
58 impl_basic_traits!(Option<$type>);
59
60 impl WriteInto for Option<$type> {
61 #[inline]
62 fn write_into<B: BufferMut>(&self, writer: &mut Writer<B>) {
63 let value = self.map(|num| num.get()).unwrap_or(0);
64 WriteInto::write_into(&value, writer);
65 }
66 }
67
68 impl ReadFrom for Option<$type> {
69 #[inline]
70 fn read_from<B: BufferRef>(&mut self, reader: &mut Reader<B>) {
71 *self = <$type>::new(CreateFrom::create_from(reader));
72 }
73 }
74
75 impl CreateFrom for Option<$type> {
76 #[inline]
77 fn create_from<B: BufferRef>(reader: &mut Reader<B>) -> Self {
78 <$type>::new(CreateFrom::create_from(reader))
79 }
80 }
81 };
82}
83
84impl_traits_for_non_zero_option!(NonZeroU32);
85impl_traits_for_non_zero_option!(NonZeroI32);
86
87macro_rules! impl_traits_for_wrapping {
88 ($type:ty) => {
89 impl_basic_traits!($type);
90
91 impl WriteInto for $type {
92 #[inline]
93 fn write_into<B: BufferMut>(&self, writer: &mut Writer<B>) {
94 WriteInto::write_into(&self.0, writer);
95 }
96 }
97
98 impl ReadFrom for $type {
99 #[inline]
100 fn read_from<B: BufferRef>(&mut self, reader: &mut Reader<B>) {
101 ReadFrom::read_from(&mut self.0, reader);
102 }
103 }
104
105 impl CreateFrom for $type {
106 #[inline]
107 fn create_from<B: BufferRef>(reader: &mut Reader<B>) -> Self {
108 Wrapping(CreateFrom::create_from(reader))
109 }
110 }
111 };
112}
113
114impl_traits_for_wrapping!(Wrapping<u32>);
115impl_traits_for_wrapping!(Wrapping<i32>);
116
117macro_rules! impl_traits_for_atomic {
118 ($type:ty) => {
119 impl_basic_traits!($type);
120
121 impl WriteInto for $type {
122 #[inline]
123 fn write_into<B: BufferMut>(&self, writer: &mut Writer<B>) {
124 let value = self.load(std::sync::atomic::Ordering::Relaxed);
125 WriteInto::write_into(&value, writer);
126 }
127 }
128
129 impl ReadFrom for $type {
130 #[inline]
131 fn read_from<B: BufferRef>(&mut self, reader: &mut Reader<B>) {
132 ReadFrom::read_from(self.get_mut(), reader);
133 }
134 }
135
136 impl CreateFrom for $type {
137 #[inline]
138 fn create_from<B: BufferRef>(reader: &mut Reader<B>) -> Self {
139 <$type>::new(CreateFrom::create_from(reader))
140 }
141 }
142 };
143}
144
145impl_traits_for_atomic!(AtomicU32);
146impl_traits_for_atomic!(AtomicI32);
147
148macro_rules! impl_marker_trait_for_f32 {
149 ($trait:path) => {
150 impl $trait for ::core::primitive::f32 {}
151 };
152}
153
154macro_rules! impl_marker_trait_for_u32 {
155 ($trait:path) => {
156 impl $trait for ::core::primitive::u32 {}
157 impl $trait for ::core::option::Option<::core::num::NonZeroU32> {}
158 impl $trait for ::core::num::Wrapping<::core::primitive::u32> {}
159 impl $trait for ::core::sync::atomic::AtomicU32 {}
160 };
161}
162
163macro_rules! impl_marker_trait_for_i32 {
164 ($trait:path) => {
165 impl $trait for ::core::primitive::i32 {}
166 impl $trait for ::core::option::Option<::core::num::NonZeroI32> {}
167 impl $trait for ::core::num::Wrapping<::core::primitive::i32> {}
168 impl $trait for ::core::sync::atomic::AtomicI32 {}
169 };
170}