archivelib 0.2.0

An implementaton of the Greenleaf ArchiveLib compression/decompression algorithm
Documentation
pub trait ArrayAlias<P> {
  type Item;

  fn get(&self, parent: &P, index: usize) -> Self::Item;
  fn set(&mut self, parent: &mut P, index: usize, item: Self::Item);
  fn shift(&mut self, parent: &P, delta: isize) -> usize;
  fn set_offset(&mut self, parent: &P, offset: usize) -> usize;
  fn offset(&mut self, parent: &P) -> usize;
  fn slice_copy(&self, parent: &P) -> Box<[Self::Item]>;

  fn apply<F>(&mut self, parent: &mut P, index: usize, apply: F)
  where
    F: FnOnce(&mut P, Self::Item) -> Self::Item,
  {
    let val = self.get(parent, index);
    let new_val = apply(parent, val);
    self.set(parent, index, new_val);
  }
}

#[macro_export]
macro_rules! array_alias_enum {
  (
    $(
      pub enum<$($generic_k:tt: $generic_v:tt),*> $name:ident {
        type Parent = $parent:ty;
        type Item = $item:ty;
        $(
          $key:ident => $target_arr:ident;
        )*
      }
    )+
  ) => (
    $(
      #[allow(dead_code)]
      #[derive(Debug, PartialEq)]
      pub enum $name<'a> {
        $(
          $key(usize),
        )*
        Custom(usize, &'a mut [$item]),
      }
      impl<'a, $($generic_k: $generic_v),*> ArrayAlias<$parent> for $name<'a> {
        type Item = $item;
        fn shift(&mut self, parent: &$parent, delta:isize) -> usize {
            let new_offset = match self {
            $(
              $name::$key(ref mut idx) => cast!((cast!((*idx) as isize) + delta) as usize),
            )*
            $name::Custom(ref mut idx, _) => cast!((cast!((*idx) as isize) + delta) as usize),
          }
          ; self.set_offset(parent, new_offset)
        }
        fn offset(&mut self, _parent: &$parent) -> usize {
          match self {
            $(
              $name::$key(ref mut idx) => {*idx},
            )*
            $name::Custom(ref mut idx, _) => {*idx},
          }
        }
        fn set_offset(&mut self, _parent: &$parent, offset: usize) -> usize {
          match self {
            $(
              $name::$key(ref mut idx) => {*idx = offset; *idx},
            )*
            $name::Custom(ref mut idx, _) => {*idx = offset; *idx},
          }
        }
        fn slice_copy(&self, parent: &$parent) -> Box<[Self::Item]> {
          match self {
            $(
              $name::$key(ref idx) => parent.$target_arr[*idx..].to_vec().into_boxed_slice(),
            )*
            $name::Custom(idx, arr) => arr[*idx..].to_vec().into_boxed_slice(),
          }
        }
        fn get(&self, parent: &$parent, index: usize) -> Self::Item {
          match self {
            $(
              $name::$key(ref idx) => parent.$target_arr[idx + index],
            )*
            $name::Custom(idx, arr) => arr[idx + index],
          }
        }
        fn set(&mut self, parent: &mut $parent, index: usize, item: Self::Item) {
          match self {
            $(
              $name::$key(ref idx) => parent.$target_arr[idx + index] = item,
            )*
            $name::Custom(ref idx, arr) => arr[idx + index] = item,
          }
        }
      }
    )+
  );
}