archivelib/compress/
array_alias.rs1pub 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}