array_of.rs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. use binrw::{binrw, BinRead, BinWrite};
  2. use diff::Diff;
  3. use num::Num;
  4. use std::{
  5. fmt::{Debug, Display},
  6. marker::PhantomData,
  7. ops::{Deref, DerefMut},
  8. };
  9. /// Wrapper to prefix array of primitives (u8/u32/etc)
  10. #[binrw]
  11. #[derive(Clone, Diff, PartialEq)]
  12. #[diff(attr(
  13. #[derive(Debug, PartialEq)]
  14. ))]
  15. pub struct ArrayOfPrimitive<T, S = u32>
  16. where
  17. // Static bounds due to https://github.com/jam1garner/binrw/issues/199
  18. T: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
  19. T: Debug + Diff + PartialEq + Num + 'static,
  20. <T as Diff>::Repr: Debug + PartialEq,
  21. S: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
  22. S: TryFrom<usize> + Copy + Clone + Debug + Display + Diff + PartialEq + 'static,
  23. <S as TryFrom<usize>>::Error: Display + Debug + Send + Sync,
  24. usize: TryFrom<S>,
  25. {
  26. // Temporary variable that holds number of elements
  27. #[br(temp)]
  28. #[bw(try_calc(S::try_from(value.len())))]
  29. count: S,
  30. #[br(count = count)]
  31. pub value: Vec<T>,
  32. _marker: PhantomData<S>,
  33. }
  34. impl<T, S> Debug for ArrayOfPrimitive<T, S>
  35. where
  36. T: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
  37. T: Debug + Diff + PartialEq + Num + 'static,
  38. <T as Diff>::Repr: Debug + PartialEq,
  39. S: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
  40. S: TryFrom<usize> + Copy + Clone + Debug + Display + Diff + PartialEq + 'static,
  41. <S as TryFrom<usize>>::Error: Display + Debug + Send + Sync,
  42. usize: TryFrom<S>,
  43. {
  44. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  45. write!(f, "{:?}", self.value)
  46. }
  47. }
  48. /// Wrapper to prefix array of single non-primitive type
  49. #[binrw]
  50. #[derive(Clone, Diff, PartialEq)]
  51. #[diff(attr(
  52. #[derive(Debug, PartialEq)]
  53. ))]
  54. pub struct ArrayOf<T, S = u32>
  55. where
  56. // Static bounds due to https://github.com/jam1garner/binrw/issues/199
  57. T: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
  58. T: Debug + Diff + PartialEq + 'static,
  59. <T as Diff>::Repr: Debug + PartialEq,
  60. S: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
  61. S: TryFrom<usize> + Copy + Clone + Debug + Display + Diff + PartialEq + 'static,
  62. <S as TryFrom<usize>>::Error: Display + Debug + Send + Sync,
  63. usize: TryFrom<S>,
  64. {
  65. // Temporary variable that holds number of elements
  66. #[br(temp)]
  67. #[bw(try_calc(S::try_from(value.len())))]
  68. count: S,
  69. #[br(count = count)]
  70. pub value: Vec<T>,
  71. _marker: PhantomData<S>,
  72. }
  73. impl<T, S> Debug for ArrayOf<T, S>
  74. where
  75. T: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
  76. T: Debug + Diff + PartialEq + 'static,
  77. <T as Diff>::Repr: Debug + PartialEq,
  78. S: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
  79. S: TryFrom<usize> + Copy + Clone + Debug + Display + Diff + PartialEq + 'static,
  80. <S as TryFrom<usize>>::Error: Display + Debug + Send + Sync,
  81. usize: TryFrom<S>,
  82. {
  83. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  84. write!(f, "{:#?}", self.value)
  85. }
  86. }
  87. impl<T, S> Deref for ArrayOf<T, S>
  88. where
  89. T: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
  90. T: Debug + Diff + PartialEq + 'static,
  91. <T as Diff>::Repr: Debug + PartialEq,
  92. S: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
  93. S: TryFrom<usize> + Copy + Clone + Debug + Display + Diff + PartialEq + 'static,
  94. <S as TryFrom<usize>>::Error: Display + Debug + Send + Sync,
  95. usize: TryFrom<S>,
  96. {
  97. type Target = Vec<T>;
  98. fn deref(&self) -> &Self::Target {
  99. &self.value
  100. }
  101. }
  102. impl<T, S> DerefMut for ArrayOf<T, S>
  103. where
  104. T: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
  105. T: Debug + Diff + PartialEq + 'static,
  106. <T as Diff>::Repr: Debug + PartialEq,
  107. S: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
  108. S: TryFrom<usize> + Copy + Clone + Debug + Display + Diff + PartialEq + 'static,
  109. <S as TryFrom<usize>>::Error: Display + Debug + Send + Sync,
  110. usize: TryFrom<S>,
  111. {
  112. fn deref_mut(&mut self) -> &mut Self::Target {
  113. &mut self.value
  114. }
  115. }
  116. impl<T, S> From<Vec<T>> for ArrayOf<T, S>
  117. where
  118. T: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
  119. T: Debug + Diff + PartialEq + 'static,
  120. <T as Diff>::Repr: Debug + PartialEq,
  121. S: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
  122. S: TryFrom<usize> + Copy + Clone + Debug + Display + Diff + PartialEq + 'static,
  123. <S as TryFrom<usize>>::Error: Display + Debug + Send + Sync,
  124. usize: TryFrom<S>,
  125. {
  126. fn from(value: Vec<T>) -> Self {
  127. Self {
  128. value,
  129. _marker: PhantomData,
  130. }
  131. }
  132. }