#![allow(dead_code, reason = "each including binary uses a different subset")]
use crate::seeded_sweep::{fold, fold_usize, next_seed};
const TEXT_ALPHABET: &[u8] =
b"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 -_.~/:?";
#[must_use]
pub fn next_byte(state: &mut u64) -> u8 {
u8::try_from(next_seed(state).rem_euclid(256)).unwrap_or(0)
}
#[must_use]
pub fn next_bytes(state: &mut u64, len: usize) -> Vec<u8> {
(0..len).map(|_| next_byte(state)).collect()
}
#[must_use]
pub fn next_text(state: &mut u64, len: usize) -> String {
let ceiling = u64::try_from(TEXT_ALPHABET.len()).unwrap_or(u64::MAX);
(0..len)
.map(|_| {
let offset = usize::try_from(next_seed(state).rem_euclid(ceiling)).unwrap_or(0);
char::from(TEXT_ALPHABET[offset])
})
.collect()
}
#[must_use]
pub fn repeated(byte: u8, len: usize) -> Vec<u8> {
vec![byte; len]
}
#[must_use]
pub fn below(state: &mut u64, bound: usize) -> usize {
let ceiling = u64::try_from(bound.max(1)).unwrap_or(u64::MAX);
usize::try_from(next_seed(state).rem_euclid(ceiling)).unwrap_or(0)
}
pub fn fold_bytes(trace: &mut u64, bytes: &[u8]) {
for byte in bytes {
fold(trace, u64::from(*byte));
}
}
pub fn fold_refusal(trace: &mut u64, arm: u64, first: usize, second: usize) {
fold(trace, arm);
fold_usize(trace, first);
fold_usize(trace, second);
}
#[must_use]
pub fn reference_nibble(character: u8) -> Option<u8> {
match character {
b'0'..=b'9' => character.checked_sub(b'0'),
b'a'..=b'f' => character
.checked_sub(b'a')
.and_then(|nibble| nibble.checked_add(10)),
b'A'..=b'F' => character
.checked_sub(b'A')
.and_then(|nibble| nibble.checked_add(10)),
_ => None,
}
}
#[must_use]
pub fn reference_escape(byte: u8) -> String {
let high = u32::from(byte >> 4);
let low = u32::from(byte & 0x0f);
let mut rendered = String::from("%");
rendered.push(
char::from_digit(high, 16)
.unwrap_or('0')
.to_ascii_uppercase(),
);
rendered.push(
char::from_digit(low, 16)
.unwrap_or('0')
.to_ascii_uppercase(),
);
rendered
}