off64 0.3.0

Read from and write to byte slices with u64 offsets
Documentation
use std::env::var;
use std::fmt::Write as FmtWrite;
use std::fs::File;
use std::io::Write as IoWrite;
use std::path::PathBuf;
use std::str::FromStr;

fn main() {
  let mut rs_trait = "pub trait Off64Int {\n".to_string();
  let mut rs_impl = "impl Off64Int for [u8] {\n".to_string();
  let mut rs_create = "".to_string();
  let widths = [16, 32, 64];
  for b in [16, 24, 32, 40, 48, 56, 64] {
    let bytes = b / 8;
    let w = widths[match widths.binary_search(&b) {
      Ok(v) | Err(v) => v,
    }];
    let width_bytes = w / 8;
    for s in ['i', 'u'] {
      for e in ['b', 'l'] {
        writeln!(
          &mut rs_trait,
          "fn read_{s}{b}_{e}e_at(&self, offset: u64) -> {s}{w};"
        )
        .unwrap();
        writeln!(
          &mut rs_trait,
          "fn write_{s}{b}_{e}e_at(&mut self, offset: u64, value: {s}{w});"
        )
        .unwrap();
        let (buf_start, buf_end) = match e {
          'b' => (width_bytes - bytes, width_bytes),
          'l' => (0, bytes),
          _ => unreachable!(),
        };
        write!(
          &mut rs_impl,
          "
          fn read_{s}{b}_{e}e_at(&self, offset: u64) -> {s}{w} {{
            let offset = usz!(offset);
            let mut buf = [0u8; {width_bytes}];
            buf[{buf_start}..{buf_end}].copy_from_slice(
              &self[offset..offset + {bytes}],
            );
            {s}{w}::from_{e}e_bytes(buf)
          }}
        "
        )
        .unwrap();
        write!(
          &mut rs_impl,
          "
          fn write_{s}{b}_{e}e_at(&mut self, offset: u64, value: {s}{w}) {{
            let offset = usz!(offset);
            let buf = value.to_{e}e_bytes();
            self[offset..offset + {bytes}].copy_from_slice(&buf[{buf_start}..{buf_end}]);
          }}
        "
        )
        .unwrap();
        write!(
          &mut rs_create,
          "
          pub fn create_{s}{b}_{e}e(value: {s}{w}) -> [u8; {bytes}] {{
            let buf = value.to_{e}e_bytes();
            buf[{buf_start}..{buf_end}].try_into().unwrap()
          }}
        "
        )
        .unwrap();
      }
    }
  }
  rs_trait.push_str("}\n\n");
  rs_impl.push_str("}\n\n");

  let mut f = File::create(
    PathBuf::from_str(&var("OUT_DIR").unwrap())
      .unwrap()
      .join("ints.rs"),
  )
  .unwrap();
  f.write_all(rs_trait.as_bytes()).unwrap();
  f.write_all(rs_impl.as_bytes()).unwrap();
  f.write_all(rs_create.as_bytes()).unwrap();
}