array_of.rs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. use binrw::{binrw, BinRead, BinWrite};
  2. use diff::{Diff, VecDiff};
  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, Default, PartialEq)]
  12. pub struct ArrayOfPrimitive<T, S = u32>
  13. where
  14. // Static bounds due to https://github.com/jam1garner/binrw/issues/199
  15. T: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
  16. T: Num + 'static,
  17. S: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
  18. S: TryFrom<usize> + Copy + Clone + Debug + 'static,
  19. <S as TryFrom<usize>>::Error: Display + Debug + Send + Sync,
  20. usize: TryFrom<S>,
  21. {
  22. // Temporary variable that holds number of elements
  23. #[br(temp)]
  24. #[bw(try_calc(S::try_from(value.len())))]
  25. count: S,
  26. #[br(count = count)]
  27. pub value: Vec<T>,
  28. _marker: PhantomData<S>,
  29. }
  30. impl<T, S> Debug for ArrayOfPrimitive<T, S>
  31. where
  32. T: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
  33. T: Debug + Num + 'static,
  34. S: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
  35. S: TryFrom<usize> + Copy + Clone + Debug + 'static,
  36. <S as TryFrom<usize>>::Error: Display + Debug + Send + Sync,
  37. usize: TryFrom<S>,
  38. {
  39. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  40. write!(f, "{:?}", self.value)
  41. }
  42. }
  43. // Custom Diff implementation to only diff internal value
  44. impl<T, S> Diff for ArrayOfPrimitive<T, S>
  45. where
  46. T: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
  47. T: Diff + PartialEq + Num + 'static,
  48. S: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
  49. S: TryFrom<usize> + Copy + Clone + Debug + Display + 'static,
  50. <S as TryFrom<usize>>::Error: Display + Debug + Send + Sync,
  51. usize: TryFrom<S>,
  52. {
  53. type Repr = VecDiff<T>;
  54. fn diff(&self, other: &Self) -> Self::Repr {
  55. self.value.diff(&other.value)
  56. }
  57. fn apply(&mut self, diff: &Self::Repr) {
  58. self.value.apply(diff)
  59. }
  60. fn identity() -> Self {
  61. Self {
  62. value: vec![],
  63. _marker: PhantomData,
  64. }
  65. }
  66. }
  67. impl<T, S> From<Vec<T>> for ArrayOfPrimitive<T, S>
  68. where
  69. T: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
  70. T: Num + 'static,
  71. S: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
  72. S: TryFrom<usize> + Copy + Clone + Debug + 'static,
  73. <S as TryFrom<usize>>::Error: Display + Debug + Send + Sync,
  74. usize: TryFrom<S>,
  75. {
  76. fn from(value: Vec<T>) -> Self {
  77. Self {
  78. value,
  79. _marker: PhantomData,
  80. }
  81. }
  82. }
  83. /// Wrapper to prefix array of single non-primitive type
  84. #[binrw]
  85. #[derive(Clone, PartialEq)]
  86. pub struct ArrayOf<T, S = u32>
  87. where
  88. // Static bounds due to https://github.com/jam1garner/binrw/issues/199
  89. T: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
  90. T: 'static,
  91. S: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
  92. S: TryFrom<usize> + Copy + Clone + Debug + 'static,
  93. <S as TryFrom<usize>>::Error: Display + Debug + Send + Sync,
  94. usize: TryFrom<S>,
  95. {
  96. // Temporary variable that holds number of elements
  97. #[br(temp)]
  98. #[bw(try_calc(S::try_from(value.len())))]
  99. count: S,
  100. #[br(count = count)]
  101. pub value: Vec<T>,
  102. _marker: PhantomData<S>,
  103. }
  104. // Custom Diff implementation to only diff internal value
  105. impl<T, S> Diff for ArrayOf<T, S>
  106. where
  107. T: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
  108. T: Diff + PartialEq + 'static,
  109. S: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
  110. S: TryFrom<usize> + Copy + Clone + Debug + Display + 'static,
  111. <S as TryFrom<usize>>::Error: Display + Debug + Send + Sync,
  112. usize: TryFrom<S>,
  113. {
  114. type Repr = VecDiff<T>;
  115. fn diff(&self, other: &Self) -> Self::Repr {
  116. self.value.diff(&other.value)
  117. }
  118. fn apply(&mut self, diff: &Self::Repr) {
  119. self.value.apply(diff)
  120. }
  121. fn identity() -> Self {
  122. Self {
  123. value: vec![],
  124. _marker: PhantomData,
  125. }
  126. }
  127. }
  128. impl<T, S> Debug for ArrayOf<T, S>
  129. where
  130. T: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
  131. T: Debug + 'static,
  132. S: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
  133. S: TryFrom<usize> + Copy + Clone + Debug + Display + 'static,
  134. <S as TryFrom<usize>>::Error: Display + Debug + Send + Sync,
  135. usize: TryFrom<S>,
  136. {
  137. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  138. write!(f, "{:#?}", self.value)
  139. }
  140. }
  141. impl<T, S> Deref for ArrayOf<T, S>
  142. where
  143. T: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
  144. T: 'static,
  145. S: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
  146. S: TryFrom<usize> + Copy + Clone + Debug + 'static,
  147. <S as TryFrom<usize>>::Error: Display + Debug + Send + Sync,
  148. usize: TryFrom<S>,
  149. {
  150. type Target = Vec<T>;
  151. fn deref(&self) -> &Self::Target {
  152. &self.value
  153. }
  154. }
  155. impl<T, S> DerefMut for ArrayOf<T, S>
  156. where
  157. T: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
  158. T: 'static,
  159. S: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
  160. S: TryFrom<usize> + Copy + Clone + Debug + 'static,
  161. <S as TryFrom<usize>>::Error: Display + Debug + Send + Sync,
  162. usize: TryFrom<S>,
  163. {
  164. fn deref_mut(&mut self) -> &mut Self::Target {
  165. &mut self.value
  166. }
  167. }
  168. impl<T, S> From<Vec<T>> for ArrayOf<T, S>
  169. where
  170. T: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
  171. T: 'static,
  172. S: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
  173. S: TryFrom<usize> + Copy + Clone + Debug + 'static,
  174. <S as TryFrom<usize>>::Error: Display + Debug + Send + Sync,
  175. usize: TryFrom<S>,
  176. {
  177. fn from(value: Vec<T>) -> Self {
  178. Self {
  179. value,
  180. _marker: PhantomData,
  181. }
  182. }
  183. }