asciidork-parser 0.37.0

Asciidork parser
Documentation
use crate::internal::*;

pub fn encode_in<'a>(bytes: &[u8], bump: &'a Bump) -> BumpString<'a> {
  let mut out = BumpString::with_capacity_in(bytes.len().div_ceil(3) * 4, bump);
  let alphabet = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  let digit = |index: u8| alphabet[index as usize] as char;
  for chunk in bytes.chunks(3) {
    out.push(digit(chunk[0] >> 2));
    match chunk.len() {
      3 => {
        let second = (chunk[0] << 4 | chunk[1] >> 4) & 0b111111;
        let third = (chunk[1] << 2 | chunk[2] >> 6) & 0b111111;
        let fourth = chunk[2] & 0b111111;
        out.extend([digit(second), digit(third), digit(fourth)]);
      }
      2 => {
        let second = (chunk[0] << 4 | chunk[1] >> 4) & 0b111111;
        let third = chunk[1] << 2 & 0b111111;
        out.extend([digit(second), digit(third), '=']);
      }
      _ => {
        let second = chunk[0] << 4 & 0b111111;
        out.extend([digit(second), '=', '=']);
      }
    }
  }
  out
}

#[test]
fn base64_encode() {
  let bump = Bump::new();
  assert_eq!(encode_in(b"", &bump).as_str(), "");
  assert_eq!(encode_in(b"f", &bump).as_str(), "Zg==");
  assert_eq!(encode_in(b"fo", &bump).as_str(), "Zm8=");
  assert_eq!(encode_in(b"foo", &bump).as_str(), "Zm9v");
  assert_eq!(encode_in(b"foob", &bump).as_str(), "Zm9vYg==");
  assert_eq!(encode_in(b"fooba", &bump).as_str(), "Zm9vYmE=");
  assert_eq!(encode_in(b"foobar", &bump).as_str(), "Zm9vYmFy");
  assert_eq!(
    encode_in(b"Hello, World!", &bump).as_str(),
    "SGVsbG8sIFdvcmxkIQ=="
  );
  let invalid_utf8: [u8; 4] = [0xFF, 0x00, 0xAB, 0xCD];
  assert_eq!(encode_in(&invalid_utf8, &bump).as_str(), "/wCrzQ==");
}