pub(super) fn try_bit_is_set(bitmask: &[u32], i: u32) -> Result<bool, String> {
let word = crate::dispatch_decode::u32_to_usize(i / 32, "reachability witness bit word")
.map_err(|error| format!("{error}. Fix: shard witness bitmasks before extraction."))?;
let bit = 1u32 << (i % 32);
Ok(bitmask.get(word).is_some_and(|value| (*value & bit) != 0))
}
pub(super) fn try_set_bit(bitmask: &mut [u32], i: u32) -> Result<(), String> {
let word = crate::dispatch_decode::u32_to_usize(i / 32, "reachability witness bit word")
.map_err(|error| format!("{error}. Fix: shard witness bitmasks before extraction."))?;
let bit = 1u32 << (i % 32);
if word >= bitmask.len() {
return Err(format!(
"reachability witness bitmask has {} word(s), cannot set bit {i} at word {word}. Fix: allocate the statement mask with the checked semantic width.",
bitmask.len()
));
}
bitmask[word] |= bit;
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn bitmask_set_rejects_short_masks_without_panic() {
let mut mask = [];
let error = try_set_bit(&mut mask, 7).expect_err("short witness mask must fail");
assert!(error.contains("cannot set bit 7"), "{error}");
}
#[test]
fn bitmask_helpers_expose_fallible_release_path() {
let source = include_str!("bitmask.rs");
let production = source
.split("#[cfg(test)]")
.next()
.expect("witness bitmask production source must precede tests");
assert!(
production.contains("pub(super) fn try_bit_is_set")
&& production.contains("pub(super) fn try_set_bit"),
"Fix: reachability witness bitmasks must expose fallible helpers for production proof assembly."
);
}
}