archivelib/compress/
array_alias.rs

1pub trait ArrayAlias<P> {
2  type Item;
3
4  fn get(&self, parent: &P, index: usize) -> Self::Item;
5  fn set(&mut self, parent: &mut P, index: usize, item: Self::Item);
6  fn shift(&mut self, parent: &P, delta: isize) -> usize;
7  fn set_offset(&mut self, parent: &P, offset: usize) -> usize;
8  fn offset(&mut self, parent: &P) -> usize;
9  fn slice_copy(&self, parent: &P) -> Box<[Self::Item]>;
10
11  fn apply<F>(&mut self, parent: &mut P, index: usize, apply: F)
12  where
13    F: FnOnce(&mut P, Self::Item) -> Self::Item,
14  {
15    let val = self.get(parent, index);
16    let new_val = apply(parent, val);
17    self.set(parent, index, new_val);
18  }
19}
20
21#[macro_export]
22macro_rules! array_alias_enum {
23  (
24    $(
25      pub enum<$($generic_k:tt: $generic_v:tt),*> $name:ident {
26        type Parent = $parent:ty;
27        type Item = $item:ty;
28        $(
29          $key:ident => $target_arr:ident;
30        )*
31      }
32    )+
33  ) => (
34    $(
35      #[allow(dead_code)]
36      #[derive(Debug, PartialEq)]
37      pub enum $name<'a> {
38        $(
39          $key(usize),
40        )*
41        Custom(usize, &'a mut [$item]),
42      }
43      impl<'a, $($generic_k: $generic_v),*> ArrayAlias<$parent> for $name<'a> {
44        type Item = $item;
45        fn shift(&mut self, parent: &$parent, delta:isize) -> usize {
46            let new_offset = match self {
47            $(
48              $name::$key(ref mut idx) => cast!((cast!((*idx) as isize) + delta) as usize),
49            )*
50            $name::Custom(ref mut idx, _) => cast!((cast!((*idx) as isize) + delta) as usize),
51          }
52          ; self.set_offset(parent, new_offset)
53        }
54        fn offset(&mut self, _parent: &$parent) -> usize {
55          match self {
56            $(
57              $name::$key(ref mut idx) => {*idx},
58            )*
59            $name::Custom(ref mut idx, _) => {*idx},
60          }
61        }
62        fn set_offset(&mut self, _parent: &$parent, offset: usize) -> usize {
63          match self {
64            $(
65              $name::$key(ref mut idx) => {*idx = offset; *idx},
66            )*
67            $name::Custom(ref mut idx, _) => {*idx = offset; *idx},
68          }
69        }
70        fn slice_copy(&self, parent: &$parent) -> Box<[Self::Item]> {
71          match self {
72            $(
73              $name::$key(ref idx) => parent.$target_arr[*idx..].to_vec().into_boxed_slice(),
74            )*
75            $name::Custom(idx, arr) => arr[*idx..].to_vec().into_boxed_slice(),
76          }
77        }
78        fn get(&self, parent: &$parent, index: usize) -> Self::Item {
79          match self {
80            $(
81              $name::$key(ref idx) => parent.$target_arr[idx + index],
82            )*
83            $name::Custom(idx, arr) => arr[idx + index],
84          }
85        }
86        fn set(&mut self, parent: &mut $parent, index: usize, item: Self::Item) {
87          match self {
88            $(
89              $name::$key(ref idx) => parent.$target_arr[idx + index] = item,
90            )*
91            $name::Custom(ref idx, arr) => arr[idx + index] = item,
92          }
93        }
94      }
95    )+
96  );
97}