1#![allow(non_camel_case_types)]
2
3use num_traits::{PrimInt, ToPrimitive, float::FloatCore};
4
5#[derive(Debug, Clone, Copy)]
9pub struct I16_LE([u8; 2]);
10
11#[derive(Debug, Clone, Copy)]
13pub struct I16_BE([u8; 2]);
14
15#[derive(Debug, Clone, Copy)]
17pub struct U16_LE([u8; 2]);
18
19#[derive(Debug, Clone, Copy)]
21pub struct U16_BE([u8; 2]);
22
23#[derive(Debug, Clone, Copy)]
27pub struct I24_LE([u8; 3]);
28
29#[derive(Debug, Clone, Copy)]
33pub struct I24_4LJ_LE([u8; 4]);
34
35#[derive(Debug, Clone, Copy)]
39pub struct I24_4RJ_LE([u8; 4]);
40
41#[derive(Debug, Clone, Copy)]
43pub struct I24_BE([u8; 3]);
44
45#[derive(Debug, Clone, Copy)]
49pub struct I24_4LJ_BE([u8; 4]);
50
51#[derive(Debug, Clone, Copy)]
55pub struct I24_4RJ_BE([u8; 4]);
56
57#[derive(Debug, Clone, Copy)]
59pub struct U24_LE([u8; 3]);
60
61#[derive(Debug, Clone, Copy)]
65pub struct U24_4LJ_LE([u8; 4]);
66
67#[derive(Debug, Clone, Copy)]
71pub struct U24_4RJ_LE([u8; 4]);
72
73#[derive(Debug, Clone, Copy)]
75pub struct U24_BE([u8; 3]);
76
77#[derive(Debug, Clone, Copy)]
81pub struct U24_4LJ_BE([u8; 4]);
82
83#[derive(Debug, Clone, Copy)]
87pub struct U24_4RJ_BE([u8; 4]);
88
89#[derive(Debug, Clone, Copy)]
93pub struct I32_LE([u8; 4]);
94
95#[derive(Debug, Clone, Copy)]
97pub struct I32_BE([u8; 4]);
98
99#[derive(Debug, Clone, Copy)]
101pub struct U32_LE([u8; 4]);
102
103#[derive(Debug, Clone, Copy)]
105pub struct U32_BE([u8; 4]);
106
107#[derive(Debug, Clone, Copy)]
111pub struct I64_LE([u8; 8]);
112
113#[derive(Debug, Clone, Copy)]
115pub struct I64_BE([u8; 8]);
116
117#[derive(Debug, Clone, Copy)]
119pub struct U64_LE([u8; 8]);
120
121#[derive(Debug, Clone, Copy)]
123pub struct U64_BE([u8; 8]);
124
125#[derive(Debug, Clone, Copy)]
129pub struct F32_LE([u8; 4]);
130
131#[derive(Debug, Clone, Copy)]
133pub struct F32_BE([u8; 4]);
134
135#[derive(Debug, Clone, Copy)]
137pub struct F64_LE([u8; 8]);
138
139#[derive(Debug, Clone, Copy)]
141pub struct F64_BE([u8; 8]);
142
143fn to_clamped_int<T: FloatCore + ToPrimitive, U: PrimInt>(
145 value: T,
146 converted: Option<U>,
147) -> ConversionResult<U> {
148 if let Some(val) = converted {
149 return ConversionResult {
150 clipped: false,
151 value: val,
152 };
153 }
154 if value.is_nan() {
155 return ConversionResult {
156 clipped: true,
157 value: U::zero(),
158 };
159 }
160 if value > T::zero() {
161 return ConversionResult {
162 clipped: true,
163 value: U::max_value(),
164 };
165 }
166 ConversionResult {
167 clipped: true,
168 value: U::min_value(),
169 }
170}
171
172pub struct ConversionResult<T> {
175 pub clipped: bool,
176 pub value: T,
177}
178
179pub trait RawSample
189where
190 Self: Sized,
191{
192 fn to_scaled_float<T: FloatCore + ToPrimitive>(&self) -> T;
194
195 fn from_scaled_float<T: FloatCore + ToPrimitive>(value: T) -> ConversionResult<Self>;
202}
203
204pub trait BytesSample {
216 type NumericType: Copy;
218
219 const BYTES_PER_SAMPLE: usize;
221
222 fn zero() -> Self;
228
229 fn from_slice(bytes: &[u8]) -> Self;
233
234 fn as_slice(&self) -> &[u8];
236
237 fn as_mut_slice(&mut self) -> &mut [u8];
239
240 fn to_number(&self) -> Self::NumericType;
242
243 fn from_number(value: Self::NumericType) -> Self;
245}
246
247macro_rules! rawsample_for_int {
248 ($type:ident, $to:ident) => {
249 impl RawSample for $type {
250 fn to_scaled_float<T: FloatCore + ToPrimitive>(&self) -> T {
251 T::from(*self).unwrap() / (T::from($type::MAX).unwrap() + T::one())
252 }
253
254 fn from_scaled_float<T: FloatCore + ToPrimitive>(value: T) -> ConversionResult<Self> {
255 let scaled = value * (T::from($type::MAX).unwrap() + T::one());
256 let converted = scaled.$to();
257 to_clamped_int(scaled, converted)
258 }
259 }
260 };
261}
262
263rawsample_for_int!(i8, to_i8);
264rawsample_for_int!(i16, to_i16);
265rawsample_for_int!(i32, to_i32);
266rawsample_for_int!(i64, to_i64);
267
268macro_rules! rawsample_for_uint {
269 ($type:ident, $to:ident) => {
270 impl RawSample for $type {
271 fn to_scaled_float<T: FloatCore + ToPrimitive>(&self) -> T {
272 let max_ampl = (T::from($type::MAX).unwrap() + T::one()) / T::from(2).unwrap();
273 (T::from(*self).unwrap() - max_ampl) / max_ampl
274 }
275
276 fn from_scaled_float<T: FloatCore + ToPrimitive>(value: T) -> ConversionResult<Self> {
277 let max_ampl = (T::from($type::MAX).unwrap() + T::one()) / T::from(2).unwrap();
278 let scaled = value * max_ampl + max_ampl;
279 let converted = scaled.$to();
280 to_clamped_int(scaled, converted)
281 }
282 }
283 };
284}
285
286rawsample_for_uint!(u8, to_u8);
287rawsample_for_uint!(u16, to_u16);
288rawsample_for_uint!(u32, to_u32);
289rawsample_for_uint!(u64, to_u64);
290
291macro_rules! rawsample_for_float {
292 ($type:ident, $to:ident) => {
293 impl RawSample for $type {
294 fn to_scaled_float<T: FloatCore + ToPrimitive>(&self) -> T {
295 T::from(*self).unwrap_or(T::zero())
296 }
297
298 fn from_scaled_float<T: FloatCore + ToPrimitive>(value: T) -> ConversionResult<Self> {
299 ConversionResult {
303 clipped: false,
304 value: value.$to().unwrap_or(0.0),
305 }
306 }
307 }
308 };
309}
310
311rawsample_for_float!(f32, to_f32);
312rawsample_for_float!(f64, to_f64);
313
314impl BytesSample for I24_4RJ_LE {
320 type NumericType = i32;
321 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
322
323 fn zero() -> Self {
324 Self(Default::default())
325 }
326
327 fn from_slice(bytes: &[u8]) -> Self {
328 Self(bytes[0..4].try_into().unwrap())
329 }
330
331 fn as_slice(&self) -> &[u8] {
332 &self.0
333 }
334
335 fn as_mut_slice(&mut self) -> &mut [u8] {
336 &mut self.0
337 }
338
339 fn to_number(&self) -> Self::NumericType {
340 let padded = [0, self.0[0], self.0[1], self.0[2]];
341 i32::from_le_bytes(padded)
342 }
343
344 fn from_number(value: Self::NumericType) -> Self {
345 let bytes = value.to_le_bytes();
346 Self([bytes[1], bytes[2], bytes[3], 0])
347 }
348}
349
350impl BytesSample for I24_4LJ_LE {
353 type NumericType = i32;
354 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
355
356 fn zero() -> Self {
357 Self(Default::default())
358 }
359
360 fn from_slice(bytes: &[u8]) -> Self {
361 Self(bytes[0..4].try_into().unwrap())
362 }
363
364 fn as_slice(&self) -> &[u8] {
365 &self.0
366 }
367
368 fn as_mut_slice(&mut self) -> &mut [u8] {
369 &mut self.0
370 }
371
372 fn to_number(&self) -> Self::NumericType {
373 let padded = [0, self.0[1], self.0[2], self.0[3]];
374 i32::from_le_bytes(padded)
375 }
376
377 fn from_number(value: Self::NumericType) -> Self {
378 let bytes = value.to_le_bytes();
379 Self([0, bytes[1], bytes[2], bytes[3]])
380 }
381}
382
383impl BytesSample for I24_LE {
385 type NumericType = i32;
386 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
387
388 fn zero() -> Self {
389 Self(Default::default())
390 }
391
392 fn from_slice(bytes: &[u8]) -> Self {
393 Self(bytes[0..3].try_into().unwrap())
394 }
395
396 fn as_slice(&self) -> &[u8] {
397 &self.0
398 }
399
400 fn as_mut_slice(&mut self) -> &mut [u8] {
401 &mut self.0
402 }
403
404 fn to_number(&self) -> Self::NumericType {
405 let padded = [0, self.0[0], self.0[1], self.0[2]];
406 i32::from_le_bytes(padded)
407 }
408
409 fn from_number(value: Self::NumericType) -> Self {
410 let bytes = value.to_le_bytes();
411 Self([bytes[1], bytes[2], bytes[3]])
412 }
413}
414
415impl BytesSample for I24_4RJ_BE {
418 type NumericType = i32;
419 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
420
421 fn zero() -> Self {
422 Self(Default::default())
423 }
424
425 fn from_slice(bytes: &[u8]) -> Self {
426 Self(bytes[0..4].try_into().unwrap())
427 }
428
429 fn as_slice(&self) -> &[u8] {
430 &self.0
431 }
432
433 fn as_mut_slice(&mut self) -> &mut [u8] {
434 &mut self.0
435 }
436
437 fn to_number(&self) -> Self::NumericType {
438 let padded = [self.0[1], self.0[2], self.0[3], 0];
439 i32::from_be_bytes(padded)
440 }
441
442 fn from_number(value: Self::NumericType) -> Self {
443 let bytes = value.to_be_bytes();
444 Self([0, bytes[0], bytes[1], bytes[2]])
445 }
446}
447
448impl BytesSample for I24_4LJ_BE {
451 type NumericType = i32;
452 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
453
454 fn zero() -> Self {
455 Self(Default::default())
456 }
457
458 fn from_slice(bytes: &[u8]) -> Self {
459 Self(bytes[0..4].try_into().unwrap())
460 }
461
462 fn as_slice(&self) -> &[u8] {
463 &self.0
464 }
465
466 fn as_mut_slice(&mut self) -> &mut [u8] {
467 &mut self.0
468 }
469
470 fn to_number(&self) -> Self::NumericType {
471 let padded = [self.0[0], self.0[1], self.0[2], 0];
472 i32::from_be_bytes(padded)
473 }
474
475 fn from_number(value: Self::NumericType) -> Self {
476 let bytes = value.to_be_bytes();
477 Self([bytes[0], bytes[1], bytes[2], 0])
478 }
479}
480
481impl BytesSample for I24_BE {
483 type NumericType = i32;
484 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
485
486 fn zero() -> Self {
487 Self(Default::default())
488 }
489
490 fn from_slice(bytes: &[u8]) -> Self {
491 Self(bytes[0..3].try_into().unwrap())
492 }
493
494 fn as_slice(&self) -> &[u8] {
495 &self.0
496 }
497
498 fn as_mut_slice(&mut self) -> &mut [u8] {
499 &mut self.0
500 }
501
502 fn to_number(&self) -> Self::NumericType {
503 let padded = [self.0[0], self.0[1], self.0[2], 0];
504 i32::from_be_bytes(padded)
505 }
506
507 fn from_number(value: Self::NumericType) -> Self {
508 let bytes = value.to_be_bytes();
509 Self([bytes[0], bytes[1], bytes[2]])
510 }
511}
512
513impl BytesSample for U24_4RJ_LE {
516 type NumericType = u32;
517 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
518
519 fn zero() -> Self {
520 Self(Default::default())
521 }
522
523 fn from_slice(bytes: &[u8]) -> Self {
524 Self(bytes[0..4].try_into().unwrap())
525 }
526
527 fn as_slice(&self) -> &[u8] {
528 &self.0
529 }
530
531 fn as_mut_slice(&mut self) -> &mut [u8] {
532 &mut self.0
533 }
534
535 fn to_number(&self) -> Self::NumericType {
536 let padded = [0, self.0[0], self.0[1], self.0[2]];
537 u32::from_le_bytes(padded)
538 }
539
540 fn from_number(value: Self::NumericType) -> Self {
541 let bytes = value.to_le_bytes();
542 Self([bytes[1], bytes[2], bytes[3], 0])
543 }
544}
545
546impl BytesSample for U24_4LJ_LE {
549 type NumericType = u32;
550 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
551
552 fn zero() -> Self {
553 Self(Default::default())
554 }
555
556 fn from_slice(bytes: &[u8]) -> Self {
557 Self(bytes[0..4].try_into().unwrap())
558 }
559
560 fn as_slice(&self) -> &[u8] {
561 &self.0
562 }
563
564 fn as_mut_slice(&mut self) -> &mut [u8] {
565 &mut self.0
566 }
567
568 fn to_number(&self) -> Self::NumericType {
569 let padded = [0, self.0[1], self.0[2], self.0[3]];
570 u32::from_le_bytes(padded)
571 }
572
573 fn from_number(value: Self::NumericType) -> Self {
574 let bytes = value.to_le_bytes();
575 Self([0, bytes[1], bytes[2], bytes[3]])
576 }
577}
578
579impl BytesSample for U24_LE {
581 type NumericType = u32;
582 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
583
584 fn zero() -> Self {
585 Self(Default::default())
586 }
587
588 fn from_slice(bytes: &[u8]) -> Self {
589 Self(bytes[0..3].try_into().unwrap())
590 }
591
592 fn as_slice(&self) -> &[u8] {
593 &self.0
594 }
595
596 fn as_mut_slice(&mut self) -> &mut [u8] {
597 &mut self.0
598 }
599
600 fn to_number(&self) -> Self::NumericType {
601 let padded = [0, self.0[0], self.0[1], self.0[2]];
602 u32::from_le_bytes(padded)
603 }
604
605 fn from_number(value: Self::NumericType) -> Self {
606 let bytes = value.to_le_bytes();
607 Self([bytes[1], bytes[2], bytes[3]])
608 }
609}
610
611impl BytesSample for U24_4RJ_BE {
614 type NumericType = u32;
615 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
616
617 fn zero() -> Self {
618 Self(Default::default())
619 }
620
621 fn from_slice(bytes: &[u8]) -> Self {
622 Self(bytes[0..4].try_into().unwrap())
623 }
624
625 fn as_slice(&self) -> &[u8] {
626 &self.0
627 }
628
629 fn as_mut_slice(&mut self) -> &mut [u8] {
630 &mut self.0
631 }
632
633 fn to_number(&self) -> Self::NumericType {
634 let padded = [self.0[1], self.0[2], self.0[3], 0];
635 u32::from_be_bytes(padded)
636 }
637
638 fn from_number(value: Self::NumericType) -> Self {
639 let bytes = value.to_be_bytes();
640 Self([0, bytes[0], bytes[1], bytes[2]])
641 }
642}
643
644impl BytesSample for U24_4LJ_BE {
647 type NumericType = u32;
648 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
649
650 fn zero() -> Self {
651 Self(Default::default())
652 }
653
654 fn from_slice(bytes: &[u8]) -> Self {
655 Self(bytes[0..4].try_into().unwrap())
656 }
657
658 fn as_slice(&self) -> &[u8] {
659 &self.0
660 }
661
662 fn as_mut_slice(&mut self) -> &mut [u8] {
663 &mut self.0
664 }
665
666 fn to_number(&self) -> Self::NumericType {
667 let padded = [self.0[0], self.0[1], self.0[2], 0];
668 u32::from_be_bytes(padded)
669 }
670
671 fn from_number(value: Self::NumericType) -> Self {
672 let bytes = value.to_be_bytes();
673 Self([bytes[0], bytes[1], bytes[2], 0])
674 }
675}
676
677impl BytesSample for U24_BE {
679 type NumericType = u32;
680 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<Self>();
681
682 fn zero() -> Self {
683 Self(Default::default())
684 }
685
686 fn from_slice(bytes: &[u8]) -> Self {
687 Self(bytes[0..3].try_into().unwrap())
688 }
689
690 fn as_slice(&self) -> &[u8] {
691 &self.0
692 }
693
694 fn as_mut_slice(&mut self) -> &mut [u8] {
695 &mut self.0
696 }
697
698 fn to_number(&self) -> Self::NumericType {
699 let padded = [self.0[0], self.0[1], self.0[2], 0];
700 u32::from_be_bytes(padded)
701 }
702
703 fn from_number(value: Self::NumericType) -> Self {
704 let bytes = value.to_be_bytes();
705 Self([bytes[0], bytes[1], bytes[2]])
706 }
707}
708
709macro_rules! bytessample_for_newtype {
710 ($type:ident, $newtype:ident, $from:ident, $to:ident) => {
711 impl BytesSample for $newtype {
712 type NumericType = $type;
713 const BYTES_PER_SAMPLE: usize = core::mem::size_of::<$type>();
714
715 fn zero() -> Self {
716 Self(Default::default())
717 }
718
719 fn from_slice(bytes: &[u8]) -> Self {
720 Self(bytes.try_into().unwrap())
721 }
722
723 fn as_slice(&self) -> &[u8] {
724 &self.0
725 }
726
727 fn as_mut_slice(&mut self) -> &mut [u8] {
728 &mut self.0
729 }
730
731 fn to_number(&self) -> Self::NumericType {
732 $type::$from(self.0)
733 }
734
735 fn from_number(value: Self::NumericType) -> Self {
736 Self(value.$to())
737 }
738 }
739 };
740}
741
742bytessample_for_newtype!(i64, I64_LE, from_le_bytes, to_le_bytes);
743bytessample_for_newtype!(u64, U64_LE, from_le_bytes, to_le_bytes);
744bytessample_for_newtype!(i64, I64_BE, from_be_bytes, to_be_bytes);
745bytessample_for_newtype!(u64, U64_BE, from_be_bytes, to_be_bytes);
746
747bytessample_for_newtype!(i16, I16_LE, from_le_bytes, to_le_bytes);
748bytessample_for_newtype!(u16, U16_LE, from_le_bytes, to_le_bytes);
749bytessample_for_newtype!(i16, I16_BE, from_be_bytes, to_be_bytes);
750bytessample_for_newtype!(u16, U16_BE, from_be_bytes, to_be_bytes);
751
752bytessample_for_newtype!(i32, I32_LE, from_le_bytes, to_le_bytes);
753bytessample_for_newtype!(u32, U32_LE, from_le_bytes, to_le_bytes);
754bytessample_for_newtype!(i32, I32_BE, from_be_bytes, to_be_bytes);
755bytessample_for_newtype!(u32, U32_BE, from_be_bytes, to_be_bytes);
756
757bytessample_for_newtype!(f32, F32_LE, from_le_bytes, to_le_bytes);
758bytessample_for_newtype!(f32, F32_BE, from_be_bytes, to_be_bytes);
759bytessample_for_newtype!(f64, F64_LE, from_le_bytes, to_le_bytes);
760bytessample_for_newtype!(f64, F64_BE, from_be_bytes, to_be_bytes);
761
762impl<V> RawSample for V
763where
764 V: BytesSample,
765 <V as BytesSample>::NumericType: RawSample,
766{
767 fn to_scaled_float<T: FloatCore + ToPrimitive>(&self) -> T {
768 let value = self.to_number();
769 value.to_scaled_float()
770 }
771
772 fn from_scaled_float<T: FloatCore + ToPrimitive>(value: T) -> ConversionResult<Self> {
773 let value = <V as BytesSample>::NumericType::from_scaled_float(value);
774 ConversionResult {
775 clipped: value.clipped,
776 value: V::from_number(value.value),
777 }
778 }
779}
780
781#[cfg(test)]
782mod tests {
783 use super::*;
784
785 macro_rules! assert_conversion_eq {
786 ($result:expr, $value:expr, $clipped:expr, $desc:expr) => {
787 assert_eq!($result.value, $value, $desc);
788 assert_eq!($result.clipped, $clipped, $desc);
789 };
790 }
791
792 macro_rules! test_to_signed_int {
793 ($fname:ident, $float:ty, $int:ident, $bits:expr) => {
794 #[test]
795 fn $fname() {
796 let val: $float = 0.25;
797 assert_conversion_eq!(
798 $int::from_scaled_float(val),
799 1 << ($bits - 3),
800 false,
801 "check +0.25"
802 );
803 let val: $float = -0.25;
804 assert_conversion_eq!(
805 $int::from_scaled_float(val),
806 -1 << ($bits - 3),
807 false,
808 "check -0.25"
809 );
810 let val: $float = 1.1;
811 assert_conversion_eq!(
812 $int::from_scaled_float(val),
813 $int::MAX,
814 true,
815 "clipped positive"
816 );
817 let val: $float = -1.1;
818 assert_conversion_eq!(
819 $int::from_scaled_float(val),
820 $int::MIN,
821 true,
822 "clipped negative"
823 );
824 }
825 };
826 }
827
828 macro_rules! test_to_unsigned_int {
829 ($fname:ident, $float:ty, $int:ident, $bits:expr) => {
830 #[test]
831 fn $fname() {
832 let val: $float = -0.5;
833 assert_conversion_eq!(
834 $int::from_scaled_float(val),
835 1 << ($bits - 2),
836 false,
837 "check -0.5"
838 );
839 let val: $float = 0.5;
840 assert_conversion_eq!(
841 $int::from_scaled_float(val),
842 $int::MAX - (1 << ($bits - 2)) + 1,
843 false,
844 "check 0.5"
845 );
846 let val: $float = 1.1;
847 assert_conversion_eq!(
848 $int::from_scaled_float(val),
849 $int::MAX,
850 true,
851 "clipped positive"
852 );
853 let val: $float = -1.1;
854 assert_conversion_eq!(
855 $int::from_scaled_float(val),
856 $int::MIN,
857 true,
858 "clipped negative"
859 );
860 }
861 };
862 }
863
864 test_to_signed_int!(convert_f32_to_i8, f32, i8, 8);
865 test_to_signed_int!(convert_642_to_i8, f64, i8, 8);
866 test_to_signed_int!(convert_f32_to_i16, f32, i16, 16);
867 test_to_signed_int!(convert_f64_to_i16, f64, i16, 16);
868 test_to_signed_int!(convert_f32_to_i32, f32, i32, 32);
869 test_to_signed_int!(convert_f64_to_i32, f64, i32, 32);
870 test_to_signed_int!(convert_f32_to_i64, f32, i64, 64);
871 test_to_signed_int!(convert_f64_to_i64, f64, i64, 64);
872
873 test_to_unsigned_int!(convert_f32_to_u8, f32, u8, 8);
874 test_to_unsigned_int!(convert_f64_to_u8, f64, u8, 8);
875 test_to_unsigned_int!(convert_f32_to_u16, f32, u16, 16);
876 test_to_unsigned_int!(convert_f64_to_u16, f64, u16, 16);
877 test_to_unsigned_int!(convert_f32_to_u32, f32, u32, 32);
878 test_to_unsigned_int!(convert_f64_to_u32, f64, u32, 32);
879 test_to_unsigned_int!(convert_f32_to_u64, f32, u64, 64);
880 test_to_unsigned_int!(convert_f64_to_u64, f64, u64, 64);
881
882 macro_rules! test_from_signed_int {
883 ($fname:ident, $float:ty, $int:ident, $bits:expr) => {
884 #[test]
885 fn $fname() {
886 let val: $int = -1 << ($bits - 2);
887 assert_eq!(val.to_scaled_float::<$float>(), -0.5, "check -0.5");
888 let val: $int = 1 << ($bits - 2);
889 assert_eq!(val.to_scaled_float::<$float>(), 0.5, "check 0.5");
890 let val: $int = $int::MIN;
891 assert_eq!(val.to_scaled_float::<$float>(), -1.0, "negative limit");
892 }
893 };
894 }
895
896 macro_rules! test_from_unsigned_int {
897 ($fname:ident, $float:ty, $int:ident, $bits:expr) => {
898 #[test]
899 fn $fname() {
900 let val: $int = 1 << ($bits - 2);
901 assert_eq!(val.to_scaled_float::<$float>(), -0.5, "check -0.5");
902 let val: $int = $int::MAX - (1 << ($bits - 2)) + 1;
903 assert_eq!(val.to_scaled_float::<$float>(), 0.5, "check 0.5");
904 let val: $int = 0;
905 assert_eq!(val.to_scaled_float::<$float>(), -1.0, "negative limit");
906 }
907 };
908 }
909
910 test_from_signed_int!(convert_f32_from_i8, f32, i8, 8);
911 test_from_signed_int!(convert_f64_from_i8, f64, i8, 8);
912 test_from_signed_int!(convert_f32_from_i16, f32, i16, 16);
913 test_from_signed_int!(convert_f64_from_i16, f64, i16, 16);
914 test_from_signed_int!(convert_f32_from_i32, f32, i32, 32);
915 test_from_signed_int!(convert_f64_from_i32, f64, i32, 32);
916 test_from_signed_int!(convert_f32_from_i64, f32, i64, 64);
917 test_from_signed_int!(convert_f64_from_i64, f64, i64, 64);
918
919 test_from_unsigned_int!(convert_f32_from_u8, f32, u8, 8);
920 test_from_unsigned_int!(convert_f64_from_u8, f64, u8, 8);
921 test_from_unsigned_int!(convert_f32_from_u16, f32, u16, 16);
922 test_from_unsigned_int!(convert_f64_from_u16, f64, u16, 16);
923 test_from_unsigned_int!(convert_f32_from_u32, f32, u32, 32);
924 test_from_unsigned_int!(convert_f64_from_u32, f64, u32, 32);
925 test_from_unsigned_int!(convert_f32_from_u64, f32, u64, 64);
926 test_from_unsigned_int!(convert_f64_from_u64, f64, u64, 64);
927
928 #[test]
929 fn test_to_clamped_int() {
930 let converted = to_clamped_int::<f32, i32>(12345.0, Some(12345));
931 assert_conversion_eq!(converted, 12345, false, "in range f32 i32");
932
933 let converted = to_clamped_int::<f32, i32>(1.0e10, None);
934 assert_conversion_eq!(converted, i32::MAX, true, "above range f32 i32");
935
936 let converted = to_clamped_int::<f32, i32>(-1.0e10, None);
937 assert_conversion_eq!(converted, i32::MIN, true, "below range f32 i32");
938
939 let converted = to_clamped_int::<f64, i32>(12345.0, Some(12345));
940 assert_conversion_eq!(converted, 12345, false, "in range f64 i32");
941
942 let converted = to_clamped_int::<f64, i32>(1.0e10, None);
943 assert_conversion_eq!(converted, i32::MAX, true, "above range f64 i32");
944
945 let converted = to_clamped_int::<f64, i32>(-1.0e10, None);
946 assert_conversion_eq!(converted, i32::MIN, true, "below range f64 i32");
947 }
948
949 #[test]
950 fn test_to_clamped_uint() {
951 let converted = to_clamped_int::<f32, u32>(12345.0, Some(12345));
952 assert_conversion_eq!(converted, 12345, false, "in range f32 u32");
953
954 let converted = to_clamped_int::<f32, u32>(1.0e10, None);
955 assert_conversion_eq!(converted, u32::MAX, true, "above range f32 u32");
956
957 let converted = to_clamped_int::<f32, u32>(-1.0, None);
958 assert_conversion_eq!(converted, u32::MIN, true, "below range f32 u32");
959
960 let converted = to_clamped_int::<f64, u32>(12345.0, Some(12345));
961 assert_conversion_eq!(converted, 12345, false, "in range f64 u32");
962
963 let converted = to_clamped_int::<f64, u32>(1.0e10, None);
964 assert_conversion_eq!(converted, u32::MAX, true, "above range f64 u32");
965
966 let converted = to_clamped_int::<f64, u32>(-1.0, None);
967 assert_conversion_eq!(converted, u32::MIN, true, "below range f64 u32");
968 }
969
970 macro_rules! test_simple_int_bytes {
971 ($fname:ident, $number:ty, $wrapper:ident, $to_bytes_fn:ident) => {
972 #[test]
973 #[allow(non_snake_case)]
974 fn $fname() {
975 let number: $number = <$number>::MAX / 5 * 4;
976 let wrapped = $wrapper(number.$to_bytes_fn());
977 assert_eq!(number, wrapped.to_number());
978 }
979 };
980 }
981
982 macro_rules! test_float_bytes {
983 ($fname:ident, $number:ty, $wrapper:ident, $to_bytes_fn:ident) => {
984 #[test]
985 #[allow(non_snake_case)]
986 fn $fname() {
987 let number: $number = 12345.0;
988 let wrapped = $wrapper(number.$to_bytes_fn());
989 assert_eq!(number, wrapped.to_number());
990 }
991 };
992 }
993
994 test_simple_int_bytes!(convert_i16_from_I16_LE, i16, I16_LE, to_le_bytes);
995 test_simple_int_bytes!(convert_i16_from_I16_BE, i16, I16_BE, to_be_bytes);
996 test_simple_int_bytes!(convert_i32_from_I32_LE, i32, I32_LE, to_le_bytes);
997 test_simple_int_bytes!(convert_i32_from_I32_BE, i32, I32_BE, to_be_bytes);
998 test_simple_int_bytes!(convert_i64_from_I64_LE, i64, I64_LE, to_le_bytes);
999 test_simple_int_bytes!(convert_i64_from_I64_BE, i64, I64_BE, to_be_bytes);
1000
1001 test_simple_int_bytes!(convert_u16_from_U16_LE, u16, U16_LE, to_le_bytes);
1002 test_simple_int_bytes!(convert_u16_from_U16_BE, u16, U16_BE, to_be_bytes);
1003 test_simple_int_bytes!(convert_u32_from_U32_LE, u32, U32_LE, to_le_bytes);
1004 test_simple_int_bytes!(convert_u32_from_U32_BE, u32, U32_BE, to_be_bytes);
1005 test_simple_int_bytes!(convert_u64_from_U64_LE, u64, U64_LE, to_le_bytes);
1006 test_simple_int_bytes!(convert_u64_from_U64_BE, u64, U64_BE, to_be_bytes);
1007
1008 test_float_bytes!(convert_f32_fom_F32_LE, f32, F32_LE, to_le_bytes);
1009 test_float_bytes!(convert_f32_fom_F32_BE, f32, F32_BE, to_be_bytes);
1010 test_float_bytes!(convert_f64_fom_F64_LE, f64, F64_LE, to_le_bytes);
1011 test_float_bytes!(convert_f64_fom_F64_BE, f64, F64_BE, to_be_bytes);
1012
1013 #[test]
1014 #[allow(non_snake_case)]
1015 fn test_I24_LE() {
1016 let number = i32::MAX / 5 * 4;
1017
1018 let number = number >> 8;
1020 let number = number << 8;
1021
1022 let allbytes = number.to_le_bytes();
1023 let bytes = [allbytes[1], allbytes[2], allbytes[3]];
1026
1027 let wrapped = I24_LE(bytes);
1028 assert_eq!(number, wrapped.to_number());
1029 }
1030
1031 #[test]
1032 #[allow(non_snake_case)]
1033 fn test_I24_BE() {
1034 let number = i32::MAX / 5 * 4;
1035
1036 let number = number >> 8;
1038 let number = number << 8;
1039
1040 let allbytes = number.to_be_bytes();
1041 let bytes = [allbytes[0], allbytes[1], allbytes[2]];
1044
1045 let wrapped = I24_BE(bytes);
1046 assert_eq!(number, wrapped.to_number());
1047 }
1048
1049 #[test]
1050 #[allow(non_snake_case)]
1051 fn test_I24_4RJ_LE() {
1052 let number = i32::MAX / 5 * 4;
1053
1054 let number = number >> 8;
1056 let number = number << 8;
1057
1058 let allbytes = number.to_le_bytes();
1059 let bytes = [allbytes[1], allbytes[2], allbytes[3], 0];
1062
1063 let wrapped = I24_4RJ_LE(bytes);
1064 assert_eq!(number, wrapped.to_number());
1065 }
1066
1067 #[test]
1068 #[allow(non_snake_case)]
1069 fn test_I24_4RJ_BE() {
1070 let number = i32::MAX / 5 * 4;
1071
1072 let number = number >> 8;
1074 let number = number << 8;
1075
1076 let allbytes = number.to_be_bytes();
1077 let bytes = [0, allbytes[0], allbytes[1], allbytes[2]];
1080
1081 let wrapped = I24_4RJ_BE(bytes);
1082 assert_eq!(number, wrapped.to_number());
1083 }
1084
1085 #[test]
1086 #[allow(non_snake_case)]
1087 fn test_I24_4LJ_LE() {
1088 let number = i32::MAX / 5 * 4;
1089
1090 let number = number >> 8;
1092 let number = number << 8;
1093
1094 let allbytes = number.to_le_bytes();
1095 let bytes = [0, allbytes[1], allbytes[2], allbytes[3]];
1098
1099 let wrapped = I24_4LJ_LE(bytes);
1100 assert_eq!(number, wrapped.to_number());
1101 }
1102
1103 #[test]
1104 #[allow(non_snake_case)]
1105 fn test_I24_4LJ_BE() {
1106 let number = i32::MAX / 5 * 4;
1107
1108 let number = number >> 8;
1110 let number = number << 8;
1111
1112 let allbytes = number.to_be_bytes();
1113 let bytes = [allbytes[0], allbytes[1], allbytes[2], 0];
1116
1117 let wrapped = I24_4LJ_BE(bytes);
1118 assert_eq!(number, wrapped.to_number());
1119 }
1120
1121 #[test]
1122 #[allow(non_snake_case)]
1123 fn test_U24_LE() {
1124 let number = u32::MAX / 5 * 4;
1125
1126 let number = number >> 8;
1128 let number = number << 8;
1129
1130 let allbytes = number.to_le_bytes();
1131 let bytes = [allbytes[1], allbytes[2], allbytes[3]];
1134
1135 let wrapped = U24_LE(bytes);
1136 assert_eq!(number, wrapped.to_number());
1137 }
1138
1139 #[test]
1140 #[allow(non_snake_case)]
1141 fn test_U24_BE() {
1142 let number = u32::MAX / 5 * 4;
1143
1144 let number = number >> 8;
1146 let number = number << 8;
1147
1148 let allbytes = number.to_be_bytes();
1149 let bytes = [allbytes[0], allbytes[1], allbytes[2]];
1152
1153 let wrapped = U24_BE(bytes);
1154 assert_eq!(number, wrapped.to_number());
1155 }
1156
1157 #[test]
1158 #[allow(non_snake_case)]
1159 fn test_U24_4RJ_LE() {
1160 let number = u32::MAX / 5 * 4;
1161
1162 let number = number >> 8;
1164 let number = number << 8;
1165
1166 let allbytes = number.to_le_bytes();
1167 let bytes = [allbytes[1], allbytes[2], allbytes[3], 0];
1170
1171 let wrapped = U24_4RJ_LE(bytes);
1172 assert_eq!(number, wrapped.to_number());
1173 }
1174
1175 #[test]
1176 #[allow(non_snake_case)]
1177 fn test_U24_4RJ_BE() {
1178 let number = u32::MAX / 5 * 4;
1179
1180 let number = number >> 8;
1182 let number = number << 8;
1183
1184 let allbytes = number.to_be_bytes();
1185 let bytes = [0, allbytes[0], allbytes[1], allbytes[2]];
1188
1189 let wrapped = U24_4RJ_BE(bytes);
1190 assert_eq!(number, wrapped.to_number());
1191 }
1192
1193 #[test]
1194 #[allow(non_snake_case)]
1195 fn test_U24_4LJ_LE() {
1196 let number = u32::MAX / 5 * 4;
1197
1198 let number = number >> 8;
1200 let number = number << 8;
1201
1202 let allbytes = number.to_le_bytes();
1203 let bytes = [0, allbytes[1], allbytes[2], allbytes[3]];
1206
1207 let wrapped = U24_4LJ_LE(bytes);
1208 assert_eq!(number, wrapped.to_number());
1209 }
1210
1211 #[test]
1212 #[allow(non_snake_case)]
1213 fn test_U24_4LJ_BE() {
1214 let number = u32::MAX / 5 * 4;
1215
1216 let number = number >> 8;
1218 let number = number << 8;
1219
1220 let allbytes = number.to_be_bytes();
1221 let bytes = [allbytes[0], allbytes[1], allbytes[2], 0];
1224
1225 let wrapped = U24_4LJ_BE(bytes);
1226 assert_eq!(number, wrapped.to_number());
1227 }
1228}