pub fn combine_bits(bits: &[(u8, u8)]) -> Result<u8, String> {
let total_bits: u8 = bits.iter().map(|&(_, width)| width).sum();
if total_bits > 8 {
return Err(format!("合計ビット数が8を超えています: {}", total_bits));
}
let mut result: u8 = 0;
let mut shift = total_bits;
for &(value, width) in bits {
shift -= width;
result |= (value & ((1 << width) - 1)) << shift;
}
Ok(result)
}
pub fn get_bits(bit_string: &str, from: usize, to: usize) -> Result<u32, String> {
let slice = &bit_string
.get(from..to)
.ok_or_else(|| format!("bit range out of bounds: {}..{}", from, to))?;
u32::from_str_radix(slice, 2).map_err(|e| format!("bit parse error: {}", e))
}
pub fn validate_120bit(bits: &[u8]) -> Result<(), String> {
if bits.len() != 15 {
Err("ビット列は120bit(15バイト)である必要があります".to_string())
} else {
Ok(())
}
}
pub fn validate_6bit_array(bits: &[u8]) -> Result<(), String> {
if bits.len() != 20 {
Err("6bit × 20個のビット列が必要です(長さ: 20)".to_string())
} else {
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_combine_bits_simple() {
let byte = combine_bits(&[(0b101, 3), (0b011, 3), (0b10, 2)]).unwrap();
assert_eq!(byte, 0b10101110);
}
#[test]
fn test_get_bits_valid_range() {
let bit_string = "1101010101110001"; let value = get_bits(&bit_string, 4, 8).unwrap(); assert_eq!(value, 5);
}
#[test]
fn test_get_bits_out_of_bounds() {
let bit_string = "1010"; let result = get_bits(&bit_string, 0, 8); assert!(result.is_err());
assert!(result.unwrap_err().contains("bit range out of bounds"));
}
#[test]
fn test_get_bits_parse_error() {
let bit_string = "1010XYZ101"; let result = get_bits(&bit_string, 4, 7); assert!(result.is_err());
assert!(result.unwrap_err().contains("bit parse error"));
}
}