use super::Bits;
use crate::{
error::Result,
optimize::{Parser, Segment},
types::Mode,
};
impl Bits {
pub fn push_segments<I>(&mut self, data: &[u8], segments_iter: I) -> Result<()>
where
I: Iterator<Item = Segment>,
{
for segment in segments_iter {
let slice = &data[segment.begin..segment.end];
match segment.mode {
Mode::Numeric => self.push_numeric_data(slice),
Mode::Alphanumeric => self.push_alphanumeric_data(slice),
Mode::Byte => self.push_byte_data(slice),
Mode::Kanji => self.push_kanji_data(slice),
}?;
}
Ok(())
}
pub fn push_optimal_data(&mut self, data: &[u8]) -> Result<()> {
let segments = Parser::new(data).optimize(self.version);
self.push_segments(data, segments)
}
}
#[cfg(test)]
mod tests {
use alloc::{vec, vec::Vec};
use super::*;
use crate::{
error::Error,
types::{EcLevel, Version},
};
fn encode(data: &[u8], version: Version, ec_level: EcLevel) -> Result<Vec<u8>> {
let mut bits = Bits::new(version);
bits.push_optimal_data(data)?;
bits.push_terminator(ec_level)?;
Ok(bits.into_bytes())
}
#[test]
fn test_alphanumeric() {
let res = encode(b"HELLO WORLD", Version::Normal(1), EcLevel::Q);
assert_eq!(
res,
Ok(vec![
0b0010_0000,
0b0101_1011,
0b0000_1011,
0b0111_1000,
0b1101_0001,
0b0111_0010,
0b1101_1100,
0b0100_1101,
0b0100_0011,
0b0100_0000,
0b1110_1100,
0b0001_0001,
0b1110_1100,
])
);
}
#[test]
fn test_auto_mode_switch() {
let res = encode(b"123A", Version::Micro(2), EcLevel::L);
assert_eq!(
res,
Ok(vec![
0b0001_1000,
0b1111_0111,
0b0010_0101,
0b0000_0000,
0b1110_1100
])
);
}
#[test]
fn test_too_long() {
let res = encode(b">>>>>>>>", Version::Normal(1), EcLevel::H);
assert_eq!(res, Err(Error::DataTooLong));
}
}