1#[macro_export]
30 macro_rules! impl_mul {
31 ( $input:ident, $by:ident, $output:ident ) => {
32 impl core::ops::Mul<$by> for $input {
33 type Output = $output;
34
35 #[inline]
36 fn mul(self, rhs : $by) -> $output {
37 $output(self.0 * rhs.0)
38 }
39 }
40 };
41 ( $input:ident, $by:ident, $output:ident, $conv:literal ) => {
42 impl core::ops::Mul<$by> for $input {
43 type Output = $output;
44
45 #[inline]
46 fn mul(self, rhs : $by) -> $output {
47 $output(self.0 * rhs.0 * $conv)
48 }
49 }
50 };
51 }
52
53 #[macro_export]
65 macro_rules! impl_mul_bidir {
66 ( $input:ident, $by:ident, $output:ident ) => {
67 syunit::impl_mul!( $input, $by, $output );
68 syunit::impl_mul!( $by, $input, $output );
69 };
70 ( $input:ident, $by:ident, $output:ident, $conv:literal ) => {
71 syunit::impl_mul!( $input, $by, $output, $conv );
72 syunit::impl_mul!( $by, $input, $output, $conv );
73 };
74 }
75
76 #[macro_export]
102 macro_rules! impl_div {
103 ( $input:ident, $by:ident, $output:ident ) => {
104 impl core::ops::Div<$by> for $input {
105 type Output = $output;
106
107 #[inline]
108 fn div(self, rhs : $by) -> $output {
109 $output(self.0 / rhs.0)
110 }
111 }
112 };
113 ( $input:ident, $by:ident, $output:ident, $conv:literal ) => {
114 impl core::ops::Div<$by> for $input {
115 type Output = $output;
116
117 #[inline]
118 fn div(self, rhs : $by) -> $output {
119 $output(self.0 / rhs.0 / $conv)
120 }
121 }
122 };
123 }
124
125 #[macro_export]
137 macro_rules! impl_div_bidir {
138 ( $input:ident, $by:ident, $output:ident ) => {
139 syunit::impl_div!( $input, $by, $output );
140 syunit::impl_div!( $input, $output, $by );
141 };
142 ( $input:ident, $by:ident, $output:ident, $conv:literal ) => {
143 syunit::impl_div!( $input, $by, $output, $conv );
144 syunit::impl_div!( $input, $output, $by, $conv );
145 };
146 }
147#[macro_export]
163 macro_rules! impl_conversion {
164 ( $input:ident, $output:ident ) => {
165 impl From<$input> for $output {
166 #[inline(always)]
167 fn from(value : $input) -> Self {
168 Self(value.0)
169 }
170 }
171
172 impl From<$output> for $input {
173 #[inline(always)]
174 fn from(value : $output) -> Self {
175 Self(value.0)
176 }
177 }
178 };
179 ( $input:ident, $output:ident, $conv:literal ) => {
180 impl From<$input> for $output {
181 #[inline(always)]
182 fn from(value : $input) -> Self {
183 Self(value.0 * ($conv))
184 }
185 }
186
187 impl From<$output> for $input {
188 #[inline(always)]
189 fn from(value : $output) -> Self {
190 Self(value.0 / ($conv))
191 }
192 }
193 };
194 }
195
196 #[macro_export]
198 macro_rules! impl_full_conversion {
199 ( $input:ident, $by:ident, $output:ident ) => {
200 syunit::impl_mul_bidir!( $input, $by, $output );
201 syunit::impl_div_bidir!( $output, $by, $input );
202 };
203 ( $input:ident, $by:ident, $output:ident, $conv:literal ) => {
204 syunit::impl_mul_bidir!( $input, $by, $output, $conv );
205 syunit::impl_div_bidir!( $output, $by, $input, $conv );
206 };
207 }
208#[macro_export]
215 macro_rules! basic_unit_helper {
216 ( $a:ident ) => {
217 impl core::str::FromStr for $a {
219 type Err = <f32 as core::str::FromStr>::Err;
220
221 fn from_str(s: &str) -> Result<Self, Self::Err> {
222 Ok(Self(s.parse::<f32>()?))
223 }
224 }
225
226 impl core::fmt::Debug for $a {
227 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
228 f.write_fmt(format_args!("{}({})", stringify!($a), self.0))
229 }
230 }
231
232 impl core::convert::From<f32> for $a {
233 #[inline(always)]
234 fn from(value : f32) -> Self {
235 Self(value)
236 }
237 }
238
239 impl core::convert::Into<f32> for $a {
240 #[inline(always)]
241 fn into(self) -> f32 {
242 self.0
243 }
244 }
245 impl core::ops::Neg for $a {
249 type Output = Self;
250
251 #[inline(always)]
252 fn neg(self) -> Self::Output {
253 Self(-self.0)
254 }
255 }
256 impl core::ops::Mul<f32> for $a {
260 type Output = $a;
261
262 #[inline(always)]
263 fn mul(self, rhs: f32) -> Self::Output {
264 $a(self.0 * rhs)
265 }
266 }
267
268 impl core::ops::Mul<$a> for f32 {
269 type Output = $a;
270
271 #[inline(always)]
272 fn mul(self, rhs : $a) -> Self::Output {
273 $a(self * rhs.0)
274 }
275 }
276 impl core::ops::Div<f32> for $a {
280 type Output = $a;
281
282 #[inline(always)]
283 fn div(self, rhs: f32) -> Self::Output {
284 $a(self.0 / rhs)
285 }
286 }
287
288 impl core::ops::Div<$a> for $a {
289 type Output = f32;
290
291 #[inline(always)]
292 fn div(self, rhs : $a) -> Self::Output {
293 self.0 / rhs.0
294 }
295 }
296 impl core::ops::Mul<syunit::Factor> for $a {
300 type Output = $a;
301
302 #[inline]
303 fn mul(self, rhs : syunit::Factor) -> Self::Output {
304 Self(self.0 * rhs.as_f32())
305 }
306 }
307 impl syunit::Unit for $a {
310 const ZERO : Self = Self(0.0);
312 const INFINITY : Self = Self(f32::INFINITY);
314 const NEG_INFINITY : Self = Self(f32::NEG_INFINITY);
316 const NAN : Self = Self(f32::NAN);
318 }
319 };
320 }
321
322 #[macro_export]
324 macro_rules! basic_unit {
325 ( $name:ident ) => {
326 syunit::basic_unit_helper!( $name );
327
328 impl core::fmt::Display for $name {
329 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
330 <f32 as core::fmt::Display>::fmt(&self.0, f)
331 }
332 }
333 };
334 ( $name:ident, $sym:literal ) => {
335 syunit::basic_unit_helper!( $name );
336
337 impl core::fmt::Display for $name {
338 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
339 f.write_fmt(format_args!("{}{}", self.0, $sym))
340 }
341 }
342 }
343 }
344#[macro_export]
348macro_rules! additive_unit {
349 ( $unit:ident ) => {
350 impl core::ops::Add<$unit> for $unit {
351 type Output = $unit;
352
353 #[inline(always)]
354 fn add(self, rhs: $unit) -> Self::Output {
355 $unit(self.0 + rhs.0)
356 }
357 }
358
359 impl core::ops::AddAssign<$unit> for $unit {
360 #[inline(always)]
361 fn add_assign(&mut self, rhs: $unit) {
362 self.0 += rhs.0;
363 }
364 }
365
366 impl core::ops::Sub<$unit> for $unit {
367 type Output = $unit;
368
369 #[inline(always)]
370 fn sub(self, rhs: $unit) -> Self::Output {
371 $unit(self.0 - rhs.0)
372 }
373 }
374
375 impl core::ops::SubAssign<$unit> for $unit {
376 #[inline]
377 fn sub_assign(&mut self, rhs : $unit) {
378 self.0 -= rhs.0
379 }
380 }
381
382 impl syunit::AdditiveUnit for $unit { }
383 };
384}
385
386#[macro_export]
388macro_rules! position_unit {
389 ( $pos:ident, $unit:ident ) => {
390 impl core::ops::Add<$unit> for $pos {
391 type Output = $pos;
392
393 fn add(self, rhs: $unit) -> Self::Output {
394 Self(self.0 + rhs.0)
395 }
396 }
397
398 impl core::ops::AddAssign<$unit> for $pos {
399 fn add_assign(&mut self, other : $unit) {
400 self.0.add_assign(other.0);
401 }
402 }
403
404 impl core::ops::Sub<$unit> for $pos {
405 type Output = $pos;
406
407 fn sub(self, rhs: $unit) -> Self::Output {
408 Self(self.0 - rhs.0)
409 }
410 }
411
412 impl core::ops::SubAssign<$unit> for $pos {
413 fn sub_assign(&mut self, other : $unit) {
414 self.0.sub_assign(other.0);
415 }
416 }
417
418 impl core::ops::Sub<$pos> for $pos {
419 type Output = $unit;
420
421 fn sub(self, rhs: $pos) -> Self::Output {
422 $unit(self.0 - rhs.0)
423 }
424 }
425
426 syunit::impl_conversion!($pos, $unit);
427 };
428}
429
430#[macro_export]
433macro_rules! derive_units {
434 ( $dist:ident, $vel:ident, $time:ident ) => {
435
436 syunit::impl_full_conversion!( $vel, $time, $dist );
437
438 impl syunit::DerivableUnit<$time> for $dist {
439 type Result = $vel;
440 }
441
442 impl syunit::IntegrableUnit<$time> for $vel {
443 type Result = $dist;
444 }
445 };
446}
447
448#[macro_export]
451macro_rules! inertia_unit {
452 ( $name:ident, $length:ident, $reduced:ident ) => {
453 impl syunit::InertiaUnit<$length> for $name {
454 type Reduced = $reduced;
455 }
456 };
457 ( $name:ident, $length:ident, $reduced:ident, $conv:literal ) => {
458 impl syunit::InertiaUnit<$length> for $name {
459 type Reduced = $reduced;
460
461 fn reduce(self, ratio : $length) -> Self::Reduced {
462 Self::Reduced::from(<Self as Into<f32>>::into(self) * <$length as Into<f32>>::into(ratio) * <$length as Into<f32>>::into(ratio) * $conv)
463 }
464
465 fn extend(reduced : Self::Reduced, ratio : $length) -> Self {
466 Self::from(<$reduced as Into<f32>>::into(reduced) / <$length as Into<f32>>::into(ratio) / <$length as Into<f32>>::into(ratio) / $conv)
467 }
468 }
469 };
470}