123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- use binrw::{binrw, BinRead, BinWrite};
- use diff::{Diff, VecDiff};
- use num::Num;
- use std::{
- fmt::{Debug, Display},
- marker::PhantomData,
- ops::{Deref, DerefMut},
- };
- /// Wrapper to prefix array of primitives (u8/u32/etc)
- #[binrw]
- #[derive(Clone, Default, PartialEq)]
- pub struct ArrayOfPrimitive<T, S = u32>
- where
- // Static bounds due to https://github.com/jam1garner/binrw/issues/199
- T: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
- T: Num + 'static,
- S: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
- S: TryFrom<usize> + Copy + Clone + Debug + 'static,
- <S as TryFrom<usize>>::Error: Display + Debug + Send + Sync,
- usize: TryFrom<S>,
- {
- // Temporary variable that holds number of elements
- #[br(temp)]
- #[bw(try_calc(S::try_from(value.len())))]
- count: S,
- #[br(count = count)]
- pub value: Vec<T>,
- _marker: PhantomData<S>,
- }
- impl<T, S> Debug for ArrayOfPrimitive<T, S>
- where
- T: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
- T: Debug + Num + 'static,
- S: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
- S: TryFrom<usize> + Copy + Clone + Debug + 'static,
- <S as TryFrom<usize>>::Error: Display + Debug + Send + Sync,
- usize: TryFrom<S>,
- {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- write!(f, "{:?}", self.value)
- }
- }
- // Custom Diff implementation to only diff internal value
- impl<T, S> Diff for ArrayOfPrimitive<T, S>
- where
- T: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
- T: Diff + PartialEq + Num + 'static,
- S: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
- S: TryFrom<usize> + Copy + Clone + Debug + Display + 'static,
- <S as TryFrom<usize>>::Error: Display + Debug + Send + Sync,
- usize: TryFrom<S>,
- {
- type Repr = VecDiff<T>;
- fn diff(&self, other: &Self) -> Self::Repr {
- self.value.diff(&other.value)
- }
- fn apply(&mut self, diff: &Self::Repr) {
- self.value.apply(diff)
- }
- fn identity() -> Self {
- Self {
- value: vec![],
- _marker: PhantomData,
- }
- }
- }
- impl<T, S> From<Vec<T>> for ArrayOfPrimitive<T, S>
- where
- T: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
- T: Num + 'static,
- S: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
- S: TryFrom<usize> + Copy + Clone + Debug + 'static,
- <S as TryFrom<usize>>::Error: Display + Debug + Send + Sync,
- usize: TryFrom<S>,
- {
- fn from(value: Vec<T>) -> Self {
- Self {
- value,
- _marker: PhantomData,
- }
- }
- }
- /// Wrapper to prefix array of single non-primitive type
- #[binrw]
- #[derive(Clone, PartialEq)]
- pub struct ArrayOf<T, S = u32>
- where
- // Static bounds due to https://github.com/jam1garner/binrw/issues/199
- T: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
- T: 'static,
- S: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
- S: TryFrom<usize> + Copy + Clone + Debug + 'static,
- <S as TryFrom<usize>>::Error: Display + Debug + Send + Sync,
- usize: TryFrom<S>,
- {
- // Temporary variable that holds number of elements
- #[br(temp)]
- #[bw(try_calc(S::try_from(value.len())))]
- count: S,
- #[br(count = count)]
- pub value: Vec<T>,
- _marker: PhantomData<S>,
- }
- // Custom Diff implementation to only diff internal value
- impl<T, S> Diff for ArrayOf<T, S>
- where
- T: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
- T: Diff + PartialEq + 'static,
- S: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
- S: TryFrom<usize> + Copy + Clone + Debug + Display + 'static,
- <S as TryFrom<usize>>::Error: Display + Debug + Send + Sync,
- usize: TryFrom<S>,
- {
- type Repr = VecDiff<T>;
- fn diff(&self, other: &Self) -> Self::Repr {
- self.value.diff(&other.value)
- }
- fn apply(&mut self, diff: &Self::Repr) {
- self.value.apply(diff)
- }
- fn identity() -> Self {
- Self {
- value: vec![],
- _marker: PhantomData,
- }
- }
- }
- impl<T, S> Debug for ArrayOf<T, S>
- where
- T: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
- T: Debug + 'static,
- S: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
- S: TryFrom<usize> + Copy + Clone + Debug + Display + 'static,
- <S as TryFrom<usize>>::Error: Display + Debug + Send + Sync,
- usize: TryFrom<S>,
- {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- write!(f, "{:#?}", self.value)
- }
- }
- impl<T, S> Deref for ArrayOf<T, S>
- where
- T: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
- T: 'static,
- S: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
- S: TryFrom<usize> + Copy + Clone + Debug + 'static,
- <S as TryFrom<usize>>::Error: Display + Debug + Send + Sync,
- usize: TryFrom<S>,
- {
- type Target = Vec<T>;
- fn deref(&self) -> &Self::Target {
- &self.value
- }
- }
- impl<T, S> DerefMut for ArrayOf<T, S>
- where
- T: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
- T: 'static,
- S: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
- S: TryFrom<usize> + Copy + Clone + Debug + 'static,
- <S as TryFrom<usize>>::Error: Display + Debug + Send + Sync,
- usize: TryFrom<S>,
- {
- fn deref_mut(&mut self) -> &mut Self::Target {
- &mut self.value
- }
- }
- impl<T, S> From<Vec<T>> for ArrayOf<T, S>
- where
- T: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
- T: 'static,
- S: for<'a> BinRead<Args<'a> = ()> + for<'a> BinWrite<Args<'a> = ()>,
- S: TryFrom<usize> + Copy + Clone + Debug + 'static,
- <S as TryFrom<usize>>::Error: Display + Debug + Send + Sync,
- usize: TryFrom<S>,
- {
- fn from(value: Vec<T>) -> Self {
- Self {
- value,
- _marker: PhantomData,
- }
- }
- }
|