Skip to main content

qrcode_core/
bits.rs

1#![allow(clippy::unreadable_literal, clippy::unusual_byte_groupings)]
2//! Bit-level data encoding for QR codes.
3//!
4//! This module handles the conversion of raw input data into the bit stream
5//! that gets placed onto the QR code canvas. It supports all four data modes:
6//!
7//! - **Numeric** — digits 0-9 (most efficient)
8//! - **Alphanumeric** — uppercase letters, digits, and a few symbols
9//! - **Byte** — arbitrary 8-bit data (including UTF-8)
10//! - **Kanji** — Shift JIS encoded double-byte characters
11//!
12//! The [`Bits`] struct is the main entry point. Use [`encode_auto`] or
13//! [`encode_auto_micro`] for automatic version and mode selection, or
14//! construct a [`Bits`] manually for advanced use cases like ECI designators
15//! or FNC1 patterns.
16
17#[cfg(not(feature = "std"))]
18#[allow(unused_imports)]
19use alloc::{
20    borrow::ToOwned,
21    format,
22    string::{String, ToString},
23    vec,
24    vec::Vec,
25};
26
27use core::cmp::min;
28
29use crate::cast::{As, Truncate};
30use crate::mode::{AlphanumericMode, EncodingMode, KanjiMode, NumericMode};
31use crate::optimize::{Parser, Segment, optimize_segments, total_encoded_len};
32use crate::types::{EcLevel, Mode, QrError, QrResult, Version};
33
34//------------------------------------------------------------------------------
35//{{{ Bits
36
37/// Set of QR data modes used by an encoded bit stream.
38///
39/// This records which payload modes were emitted, without retaining input bytes
40/// or every segment boundary. Use [`iter`](Self::iter) when call sites need the
41/// modes in a stable QR mode order.
42#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
43#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
44pub struct EncodingModes {
45    bits: u8,
46}
47
48impl EncodingModes {
49    /// Creates an empty mode set.
50    #[must_use]
51    pub const fn empty() -> Self {
52        Self { bits: 0 }
53    }
54
55    /// Creates a mode set containing one mode.
56    #[must_use]
57    pub const fn from_mode(mode: Mode) -> Self {
58        Self { bits: mode_bit(mode) }
59    }
60
61    /// Returns `true` when `mode` was used by the encoded bit stream.
62    #[must_use]
63    pub const fn contains(self, mode: Mode) -> bool {
64        self.bits & mode_bit(mode) != 0
65    }
66
67    /// Returns `true` when no data modes have been recorded.
68    #[must_use]
69    pub const fn is_empty(self) -> bool {
70        self.bits == 0
71    }
72
73    /// Number of distinct data modes recorded.
74    #[must_use]
75    pub const fn len(self) -> usize {
76        (self.contains(Mode::Numeric) as usize)
77            + (self.contains(Mode::Alphanumeric) as usize)
78            + (self.contains(Mode::Byte) as usize)
79            + (self.contains(Mode::Kanji) as usize)
80    }
81
82    /// Returns an iterator over the recorded modes in stable QR mode order:
83    /// Numeric, Alphanumeric, Byte, Kanji.
84    pub const fn iter(self) -> EncodingModesIter {
85        EncodingModesIter { modes: self, index: 0 }
86    }
87
88    fn insert(&mut self, mode: Mode) {
89        self.bits |= mode_bit(mode);
90    }
91}
92
93/// Iterator returned by [`EncodingModes::iter`].
94#[derive(Clone, Debug)]
95pub struct EncodingModesIter {
96    modes: EncodingModes,
97    index: u8,
98}
99
100impl Iterator for EncodingModesIter {
101    type Item = Mode;
102
103    fn next(&mut self) -> Option<Self::Item> {
104        while self.index < 4 {
105            let mode = match self.index {
106                0 => Mode::Numeric,
107                1 => Mode::Alphanumeric,
108                2 => Mode::Byte,
109                _ => Mode::Kanji,
110            };
111            self.index += 1;
112            if self.modes.contains(mode) {
113                return Some(mode);
114            }
115        }
116        None
117    }
118
119    fn size_hint(&self) -> (usize, Option<usize>) {
120        let remaining = ((self.modes.bits & 0b1111) >> self.index).count_ones() as usize;
121        (remaining, Some(remaining))
122    }
123}
124
125impl ExactSizeIterator for EncodingModesIter {}
126impl core::iter::FusedIterator for EncodingModesIter {}
127
128const fn mode_bit(mode: Mode) -> u8 {
129    match mode {
130        Mode::Numeric => 1 << 0,
131        Mode::Alphanumeric => 1 << 1,
132        Mode::Byte => 1 << 2,
133        Mode::Kanji => 1 << 3,
134    }
135}
136
137/// The `Bits` structure stores the encoded data for a QR code.
138pub struct Bits {
139    data: Vec<u8>,
140    bit_offset: usize,
141    version: Version,
142    encoding_modes: EncodingModes,
143    payload_bits_len: Option<usize>,
144}
145
146fn additional_bytes_for_bits(bit_offset: usize, bit_count: usize) -> usize {
147    debug_assert!(bit_offset < 8);
148    let existing_space = if bit_offset == 0 { 0 } else { 8 - bit_offset };
149    bit_count.saturating_sub(existing_space).div_ceil(8)
150}
151
152impl Bits {
153    /// Constructs a new, empty bits structure.
154    pub const fn new(version: Version) -> Self {
155        Self {
156            data: Vec::new(),
157            bit_offset: 0,
158            version,
159            encoding_modes: EncodingModes::empty(),
160            payload_bits_len: None,
161        }
162    }
163
164    /// Pushes an N-bit big-endian integer to the end of the bits.
165    ///
166    /// Note: It is up to the developer to ensure that `number` really only is
167    /// `n` bit in size. Otherwise, the excess bits may stomp on the existing
168    /// ones.
169    fn push_number(&mut self, n: usize, number: u16) {
170        debug_assert!(n == 16 || n < 16 && number < (1 << n), "{number} is too big as a {n}-bit number");
171
172        let b = self.bit_offset + n;
173        let last_index = self.data.len().wrapping_sub(1);
174        match (self.bit_offset, b) {
175            (0, 0..=8) => {
176                self.data.push((number << (8 - b)).truncate_as_u8());
177            }
178            (0, _) => {
179                self.data.push((number >> (b - 8)).truncate_as_u8());
180                self.data.push((number << (16 - b)).truncate_as_u8());
181            }
182            (_, 0..=8) => {
183                self.data[last_index] |= (number << (8 - b)).truncate_as_u8();
184            }
185            (_, 9..=16) => {
186                self.data[last_index] |= (number >> (b - 8)).truncate_as_u8();
187                self.data.push((number << (16 - b)).truncate_as_u8());
188            }
189            _ => {
190                self.data[last_index] |= (number >> (b - 8)).truncate_as_u8();
191                self.data.push((number >> (b - 16)).truncate_as_u8());
192                self.data.push((number << (24 - b)).truncate_as_u8());
193            }
194        }
195        self.bit_offset = b & 7;
196    }
197
198    /// Pushes an N-bit big-endian integer to the end of the bits, and check
199    /// that the number does not overflow the bits.
200    ///
201    /// Writing zero bits with a zero value leaves the stream unchanged.
202    ///
203    /// Returns `Err(QrError::DataTooLong)` on overflow.
204    pub fn push_number_checked(&mut self, n: usize, number: usize) -> QrResult<()> {
205        if n > 16 || number >= (1 << n) {
206            Err(QrError::DataTooLong)
207        } else {
208            if n > 0 {
209                self.push_number(n, number.as_u16());
210            }
211            Ok(())
212        }
213    }
214
215    /// Reserves `n` extra bits of space for pushing.
216    ///
217    /// Space remaining in the current partial byte is used first. This does
218    /// not change the bit stream, recorded modes, or payload length.
219    pub fn reserve(&mut self, n: usize) {
220        let extra_bytes = additional_bytes_for_bits(self.bit_offset, n);
221        self.data.reserve(extra_bytes);
222    }
223
224    /// Convert the bits into a byte vector.
225    pub fn into_bytes(self) -> Vec<u8> {
226        self.data
227    }
228
229    /// Total number of bits currently pushed.
230    pub fn len(&self) -> usize {
231        if self.bit_offset == 0 { self.data.len() * 8 } else { (self.data.len() - 1) * 8 + self.bit_offset }
232    }
233
234    /// Whether there are any bits pushed.
235    pub fn is_empty(&self) -> bool {
236        self.data.is_empty()
237    }
238
239    /// The maximum number of bits allowed by the provided QR code version and
240    /// error correction level.
241    ///
242    /// # Errors
243    ///
244    /// Returns `Err(QrError::InvalidVersion)` if it is not valid to use the
245    /// `ec_level` for the given version (e.g. `Version::Micro(1)` with
246    /// `EcLevel::H`).
247    pub fn max_len(&self, ec_level: EcLevel) -> QrResult<usize> {
248        self.version.fetch(ec_level, &DATA_LENGTHS)
249    }
250
251    /// Version of the QR code.
252    pub fn version(&self) -> Version {
253        self.version
254    }
255
256    /// Data modes recorded while payload segments were pushed.
257    #[must_use]
258    pub const fn encoding_modes(&self) -> EncodingModes {
259        self.encoding_modes
260    }
261
262    /// Number of payload bits before terminator and padding bits were added.
263    ///
264    /// If [`push_terminator`](Self::push_terminator) has not been called, this
265    /// returns the current bit length.
266    #[must_use]
267    pub fn payload_bits_len(&self) -> usize {
268        match self.payload_bits_len {
269            Some(len) => len,
270            None => self.len(),
271        }
272    }
273
274    /// Remaining data capacity, in bits, before terminator and padding bits.
275    ///
276    /// # Errors
277    ///
278    /// Returns [`QrError::InvalidVersion`] when the stored version is
279    /// incompatible with `ec_level`.
280    pub fn remaining_capacity_bits(&self, ec_level: EcLevel) -> QrResult<usize> {
281        Ok(self.max_len(ec_level)?.saturating_sub(self.payload_bits_len()))
282    }
283}
284
285#[test]
286fn test_push_number() {
287    let mut bits = Bits::new(Version::Normal(1));
288
289    bits.push_number(3, 0b010); // 0:0 .. 0:3
290    bits.push_number(3, 0b110); // 0:3 .. 0:6
291    bits.push_number(3, 0b101); // 0:6 .. 1:1
292    bits.push_number(7, 0b001_1010); // 1:1 .. 2:0
293    bits.push_number(4, 0b1100); // 2:0 .. 2:4
294    bits.push_number(12, 0b1011_0110_1101); // 2:4 .. 4:0
295    bits.push_number(10, 0b01_1001_0001); // 4:0 .. 5:2
296    bits.push_number(15, 0b111_0010_1110_0011); // 5:2 .. 7:1
297
298    let bytes = bits.into_bytes();
299
300    assert_eq!(
301        bytes,
302        vec![
303            0b010_110_10, // 90
304            0b1_001_1010, // 154
305            0b1100_1011,  // 203
306            0b0110_1101,  // 109
307            0b01_1001_00, // 100
308            0b01_111_001, // 121
309            0b0_1110_001, // 113
310            0b1_0000000,  // 128
311        ]
312    );
313}
314
315#[cfg(test)]
316mod reservation_tests {
317    use crate::bits::{Bits, additional_bytes_for_bits};
318    use crate::types::{EcLevel, Version};
319
320    fn reference_byte_increment(offset: usize, count: usize) -> usize {
321        let total_bytes = (count as u128 + offset as u128).div_ceil(8);
322        usize::try_from(total_bytes - u128::from(offset > 0)).unwrap()
323    }
324
325    #[test]
326    fn additional_byte_increment_matches_all_small_bit_counts_and_offsets() {
327        for offset in 0..8 {
328            for count in 0..=256 {
329                assert_eq!(
330                    additional_bytes_for_bits(offset, count),
331                    reference_byte_increment(offset, count),
332                    "offset {offset}, count {count}"
333                );
334            }
335        }
336        assert_eq!(additional_bytes_for_bits(0, 1), 1);
337        assert_eq!(additional_bytes_for_bits(7, 2), 1);
338        assert_eq!(additional_bytes_for_bits(1, 1), 0);
339    }
340
341    #[test]
342    fn additional_byte_increment_handles_usize_max_without_allocation() {
343        for offset in 0..8 {
344            for count in [usize::MAX - 8, usize::MAX - 7, usize::MAX - 1, usize::MAX] {
345                assert_eq!(additional_bytes_for_bits(offset, count), reference_byte_increment(offset, count));
346            }
347        }
348    }
349
350    fn filled_to_capacity(offset: usize) -> Bits {
351        let mut bits = Bits::new(Version::Normal(40));
352        bits.reserve(64);
353        let capacity = bits.data.capacity();
354        let whole_bytes = capacity - usize::from(offset > 0);
355        for _ in 0..whole_bytes {
356            bits.push_number_checked(8, 0xa5).unwrap();
357        }
358        if offset > 0 {
359            bits.push_number_checked(offset, (1 << offset) - 1).unwrap();
360        }
361        assert_eq!(bits.data.len(), capacity);
362        assert_eq!(bits.bit_offset, offset);
363        bits
364    }
365
366    fn write_bits(bits: &mut Bits, mut count: usize) {
367        while count > 0 {
368            let width = count.min(16);
369            bits.push_number_checked(width, (1 << width) - 1).unwrap();
370            count -= width;
371        }
372    }
373
374    #[test]
375    fn reserved_bits_can_be_written_without_growing_capacity() {
376        for offset in 0..8 {
377            for count in 0..=128 {
378                let mut reserved = filled_to_capacity(offset);
379                let mut reference = filled_to_capacity(offset);
380                let before_bytes = reserved.data.clone();
381                let before_len = reserved.len();
382                let before_modes = reserved.encoding_modes();
383                let before_payload = reserved.payload_bits_len;
384
385                reserved.reserve(count);
386                let reserved_capacity = reserved.data.capacity();
387                assert_eq!(reserved.data, before_bytes);
388                assert_eq!(reserved.len(), before_len);
389                assert_eq!(reserved.encoding_modes(), before_modes);
390                assert_eq!(reserved.payload_bits_len, before_payload);
391
392                write_bits(&mut reserved, count);
393                write_bits(&mut reference, count);
394
395                assert_eq!(reserved.data.capacity(), reserved_capacity, "offset {offset}, count {count}");
396                assert_eq!(reserved.data, reference.data);
397                assert_eq!(reserved.len(), before_len + count);
398                assert_eq!(reserved.bit_offset, reference.bit_offset);
399                assert_eq!(reserved.encoding_modes(), reference.encoding_modes());
400                assert_eq!(reserved.payload_bits_len, reference.payload_bits_len);
401            }
402        }
403    }
404
405    #[test]
406    fn reserving_empty_or_padded_streams_keeps_contents_and_metadata() {
407        let mut empty = Bits::new(Version::Normal(1));
408        empty.reserve(0);
409        assert!(empty.is_empty());
410        assert_eq!(empty.data.capacity(), 0);
411        empty.reserve(1);
412        let capacity = empty.data.capacity();
413        assert!(capacity >= 1);
414        assert!(empty.is_empty());
415        empty.push_number_checked(1, 1).unwrap();
416        assert_eq!(empty.data.capacity(), capacity);
417
418        let mut padded = Bits::new(Version::Normal(1));
419        padded.push_byte_data(b"abc").unwrap();
420        padded.push_terminator(EcLevel::M).unwrap();
421        let before_bytes = padded.data.clone();
422        let before_len = padded.len();
423        let before_modes = padded.encoding_modes();
424        let before_payload = padded.payload_bits_len;
425        padded.reserve(65);
426        assert_eq!(padded.data, before_bytes);
427        assert_eq!(padded.len(), before_len);
428        assert_eq!(padded.encoding_modes(), before_modes);
429        assert_eq!(padded.payload_bits_len, before_payload);
430    }
431}
432
433#[cfg(test)]
434mod metadata_tests {
435    use crate::bits::{Bits, EncodingModes};
436    use crate::types::{EcLevel, Mode, Version};
437
438    #[test]
439    fn encoding_modes_iterates_in_stable_mode_order() {
440        let modes = EncodingModes::from_mode(Mode::Byte);
441        let mut modes_with_numeric = modes;
442        modes_with_numeric.insert(Mode::Numeric);
443
444        assert_eq!(modes_with_numeric.iter().collect::<Vec<_>>(), vec![Mode::Numeric, Mode::Byte]);
445    }
446
447    #[test]
448    fn encoding_modes_iterator_reports_exact_remaining_length_for_every_subset() {
449        let order = [Mode::Numeric, Mode::Alphanumeric, Mode::Byte, Mode::Kanji];
450        for mask in 0..=0b1111 {
451            let modes = EncodingModes { bits: mask };
452            let expected = order.iter().copied().filter(|&mode| modes.contains(mode)).collect::<Vec<_>>();
453            let mut iter = modes.iter();
454
455            for (index, &mode) in expected.iter().enumerate() {
456                let remaining = expected.len() - index;
457                assert_eq!(iter.size_hint(), (remaining, Some(remaining)), "mask {mask}");
458                assert_eq!(iter.len(), remaining, "mask {mask}");
459                assert_eq!(iter.next(), Some(mode));
460            }
461            assert_eq!(iter.size_hint(), (0, Some(0)), "mask {mask}");
462            assert_eq!(iter.len(), 0);
463            assert_eq!(iter.next(), None);
464            assert_eq!(iter.next(), None);
465        }
466    }
467
468    #[test]
469    fn bits_records_successful_payload_modes() {
470        let mut bits = Bits::new(Version::Normal(1));
471
472        bits.push_numeric_data(b"012").unwrap();
473        bits.push_byte_data(b"abc").unwrap();
474
475        assert!(bits.encoding_modes().contains(Mode::Numeric));
476        assert!(bits.encoding_modes().contains(Mode::Byte));
477        assert!(!bits.encoding_modes().contains(Mode::Kanji));
478    }
479
480    #[test]
481    fn remaining_capacity_uses_payload_len_before_padding() {
482        let mut bits = Bits::new(Version::Normal(1));
483
484        bits.push_numeric_data(b"01234567").unwrap();
485        bits.push_terminator(EcLevel::M).unwrap();
486
487        assert_eq!(bits.len(), 128);
488        assert_eq!(bits.payload_bits_len(), 41);
489        assert_eq!(bits.remaining_capacity_bits(EcLevel::M), Ok(87));
490    }
491}
492
493//}}}
494//------------------------------------------------------------------------------
495//{{{ Mode indicator
496
497/// An "extended" mode indicator, includes all indicators supported by QR code
498/// beyond those bearing data.
499#[derive(Copy, Clone)]
500pub enum ExtendedMode {
501    /// ECI mode indicator, to introduce an ECI designator.
502    Eci,
503
504    /// The normal mode to introduce data.
505    Data(Mode),
506
507    /// FNC-1 mode in the first position.
508    Fnc1First,
509
510    /// FNC-1 mode in the second position.
511    Fnc1Second,
512
513    /// Structured append.
514    StructuredAppend,
515}
516
517impl Bits {
518    /// Push the mode indicator to the end of the bits.
519    ///
520    /// # Errors
521    ///
522    /// If the mode is not supported in the provided version, this method
523    /// returns `Err(QrError::UnsupportedCharacterSet)`.
524    pub fn push_mode_indicator(&mut self, mode: ExtendedMode) -> QrResult<()> {
525        let (bits, number) = self.mode_indicator_bits(mode)?;
526        if bits > 0 {
527            self.push_number(bits, number.as_u16());
528        }
529        Ok(())
530    }
531
532    fn mode_indicator_bits(&self, mode: ExtendedMode) -> QrResult<(usize, usize)> {
533        #[allow(clippy::match_same_arms)]
534        let number = match (self.version, mode) {
535            (Version::Micro(_), ExtendedMode::Data(Mode::Numeric)) => 0,
536            (Version::Micro(_), ExtendedMode::Data(Mode::Alphanumeric)) => 1,
537            (Version::Micro(_), ExtendedMode::Data(Mode::Byte)) => 0b10,
538            (Version::Micro(_), ExtendedMode::Data(Mode::Kanji)) => 0b11,
539            (Version::Micro(_), _) => return Err(QrError::UnsupportedCharacterSet),
540            (_, ExtendedMode::Data(Mode::Numeric)) => 0b0001,
541            (_, ExtendedMode::Data(Mode::Alphanumeric)) => 0b0010,
542            (_, ExtendedMode::Data(Mode::Byte)) => 0b0100,
543            (_, ExtendedMode::Data(Mode::Kanji)) => 0b1000,
544            (_, ExtendedMode::Eci) => 0b0111,
545            (_, ExtendedMode::Fnc1First) => 0b0101,
546            (_, ExtendedMode::Fnc1Second) => 0b1001,
547            (_, ExtendedMode::StructuredAppend) => 0b0011,
548        };
549        let bits = self.version.mode_bits_count();
550        if bits > 16 || number >= (1 << bits) {
551            return Err(QrError::UnsupportedCharacterSet);
552        }
553        Ok((bits, number))
554    }
555}
556
557//}}}
558//------------------------------------------------------------------------------
559//{{{ ECI
560
561impl Bits {
562    /// Push an ECI (Extended Channel Interpretation) designator to the bits.
563    ///
564    /// An ECI designator is a 6-digit number to specify the character set of
565    /// the following binary data. After calling this method, one could call
566    /// `.push_byte_data()` or similar methods to insert the actual data, e.g.
567    ///
568    ///     #![allow(unused_must_use)]
569    ///
570    ///     use qrcode_core::bits::Bits;
571    ///     use qrcode_core::types::Version;
572    ///
573    ///     let mut bits = Bits::new(Version::Normal(1));
574    ///     bits.push_eci_designator(9); // 9 = ISO-8859-7 (Greek).
575    ///     bits.push_byte_data(b"\xa1\xa2\xa3\xa4\xa5"); // ΑΒΓΔΕ
576    ///
577    ///
578    /// The full list of ECI designator values can be found from
579    /// <http://strokescribe.com/en/ECI.html>. Some example values are:
580    ///
581    /// ECI # | Character set
582    /// ------|-------------------------------------
583    /// 3     | ISO-8859-1 (Western European)
584    /// 20    | Shift JIS (Japanese)
585    /// 23    | Windows 1252 (Latin 1) (Western European)
586    /// 25    | UTF-16 Big Endian
587    /// 26    | UTF-8
588    /// 28    | Big 5 (Traditional Chinese)
589    /// 29    | GB-18030 (Simplified Chinese)
590    /// 30    | EUC-KR (Korean)
591    ///
592    /// # Errors
593    ///
594    /// If the QR code version does not support ECI, this method will return
595    /// `Err(QrError::UnsupportedCharacterSet)`.
596    ///
597    /// If the designator is outside the expected range, this method will
598    /// return `Err(QrError::InvalidECIDesignator)`.
599    pub fn push_eci_designator(&mut self, eci_designator: u32) -> QrResult<()> {
600        self.reserve(12); // assume the common case that eci_designator <= 127.
601        self.push_mode_indicator(ExtendedMode::Eci)?;
602        match eci_designator {
603            0..=127 => {
604                self.push_number(8, eci_designator.as_u16());
605            }
606            128..=16383 => {
607                self.push_number(2, 0b10);
608                self.push_number(14, eci_designator.as_u16());
609            }
610            16384..=999_999 => {
611                self.push_number(3, 0b110);
612                self.push_number(5, (eci_designator >> 16).as_u16());
613                self.push_number(16, (eci_designator & 0xffff).as_u16());
614            }
615            _ => return Err(QrError::InvalidEciDesignator { value: eci_designator }),
616        }
617        Ok(())
618    }
619}
620
621#[cfg(test)]
622mod eci_tests {
623    use crate::bits::Bits;
624    use crate::types::{QrError, Version};
625
626    #[test]
627    fn test_9() {
628        let mut bits = Bits::new(Version::Normal(1));
629        assert_eq!(bits.push_eci_designator(9), Ok(()));
630        assert_eq!(bits.into_bytes(), vec![0b0111_0000, 0b1001_0000]);
631    }
632
633    #[test]
634    fn test_899() {
635        let mut bits = Bits::new(Version::Normal(1));
636        assert_eq!(bits.push_eci_designator(899), Ok(()));
637        assert_eq!(bits.into_bytes(), vec![0b0111_10_00, 0b00111000, 0b0011_0000]);
638    }
639
640    #[test]
641    fn test_999999() {
642        let mut bits = Bits::new(Version::Normal(1));
643        assert_eq!(bits.push_eci_designator(999999), Ok(()));
644        assert_eq!(bits.into_bytes(), vec![0b0111_110_0, 0b11110100, 0b00100011, 0b1111_0000]);
645    }
646
647    #[test]
648    fn test_invalid_designator() {
649        let mut bits = Bits::new(Version::Normal(1));
650        assert_eq!(bits.push_eci_designator(1000000), Err(QrError::InvalidEciDesignator { value: 1000000 }));
651    }
652
653    #[test]
654    fn test_unsupported_character_set() {
655        let mut bits = Bits::new(Version::Micro(4));
656        assert_eq!(bits.push_eci_designator(9), Err(QrError::UnsupportedCharacterSet));
657    }
658}
659
660//}}}
661//------------------------------------------------------------------------------
662//{{{ Mode::Numeric mode
663
664impl Bits {
665    fn push_header(&mut self, mode: Mode, raw_data_len: usize) -> QrResult<()> {
666        let (mode_bits, mode_number) = self.mode_indicator_bits(ExtendedMode::Data(mode))?;
667        let length_bits = mode.length_bits_count(self.version);
668        if raw_data_len >= (1_usize << length_bits) {
669            return Err(QrError::DataTooLong);
670        }
671        self.reserve(length_bits + mode_bits + mode.data_bits_count(raw_data_len));
672        if mode_bits > 0 {
673            self.push_number(mode_bits, mode_number.as_u16());
674        }
675        self.push_number(length_bits, raw_data_len.as_u16());
676        Ok(())
677    }
678
679    /// Encodes a numeric string to the bits.
680    ///
681    /// The data should only contain the characters 0 to 9.
682    ///
683    /// # Errors
684    ///
685    /// Returns `Err(QrError::DataTooLong)` on overflow.
686    /// Returns [`QrError::InvalidCharacter`] if `data` contains a non-digit.
687    pub fn push_numeric_data(&mut self, data: &[u8]) -> QrResult<()> {
688        self.mode_indicator_bits(ExtendedMode::Data(Mode::Numeric))?;
689        if let Some((position, byte)) = NumericMode::invalid_character(data) {
690            return Err(QrError::InvalidCharacter { position, byte });
691        }
692        self.push_header(Mode::Numeric, data.len())?;
693        for chunk in data.chunks(3) {
694            let number = chunk.iter().map(|b| u16::from(*b - b'0')).fold(0, |a, b| a * 10 + b);
695            let length = chunk.len() * 3 + 1;
696            self.push_number(length, number);
697        }
698        self.encoding_modes.insert(Mode::Numeric);
699        self.payload_bits_len = None;
700        Ok(())
701    }
702}
703
704#[cfg(test)]
705mod numeric_tests {
706    use crate::bits::Bits;
707    use crate::types::{QrError, Version};
708
709    #[test]
710    fn test_iso_18004_2006_example_1() {
711        let mut bits = Bits::new(Version::Normal(1));
712        assert_eq!(bits.push_numeric_data(b"01234567"), Ok(()));
713        assert_eq!(bits.into_bytes(), vec![0b0001_0000, 0b001000_00, 0b00001100, 0b01010110, 0b01_100001, 0b1_0000000]);
714    }
715
716    #[test]
717    fn test_iso_18004_2000_example_2() {
718        let mut bits = Bits::new(Version::Normal(1));
719        assert_eq!(bits.push_numeric_data(b"0123456789012345"), Ok(()));
720        assert_eq!(
721            bits.into_bytes(),
722            vec![
723                0b0001_0000,
724                0b010000_00,
725                0b00001100,
726                0b01010110,
727                0b01_101010,
728                0b0110_1110,
729                0b000101_00,
730                0b11101010,
731                0b0101_0000,
732            ]
733        );
734    }
735
736    #[test]
737    fn test_iso_18004_2006_example_2() {
738        let mut bits = Bits::new(Version::Micro(3));
739        assert_eq!(bits.push_numeric_data(b"0123456789012345"), Ok(()));
740        assert_eq!(
741            bits.into_bytes(),
742            vec![0b00_10000_0, 0b00000110, 0b0_0101011, 0b001_10101, 0b00110_111, 0b0000101_0, 0b01110101, 0b00101_000,]
743        );
744    }
745
746    #[test]
747    fn test_data_too_long_error() {
748        let mut bits = Bits::new(Version::Micro(1));
749        assert_eq!(bits.push_numeric_data(b"12345678"), Err(QrError::DataTooLong));
750    }
751}
752
753//}}}
754//------------------------------------------------------------------------------
755//{{{ Mode::Alphanumeric mode
756
757/// In QR code `Mode::Alphanumeric` mode, a pair of alphanumeric characters will
758/// be encoded as a base-45 integer. `alphanumeric_digit` converts each
759/// character into its corresponding base-45 digit.
760///
761/// The conversion is specified in ISO/IEC 18004:2006, §8.4.3, Table 5.
762#[inline]
763fn alphanumeric_digit(character: u8) -> u16 {
764    match character {
765        b'0'..=b'9' => u16::from(character - b'0'),
766        b'A'..=b'Z' => u16::from(character - b'A') + 10,
767        b' ' => 36,
768        b'$' => 37,
769        b'%' => 38,
770        b'*' => 39,
771        b'+' => 40,
772        b'-' => 41,
773        b'.' => 42,
774        b'/' => 43,
775        b':' => 44,
776        _ => 0,
777    }
778}
779
780impl Bits {
781    /// Encodes an alphanumeric string to the bits.
782    ///
783    /// The data should only contain the characters A to Z (excluding lowercase),
784    /// 0 to 9, space, `$`, `%`, `*`, `+`, `-`, `.`, `/` or `:`.
785    ///
786    /// # Errors
787    ///
788    /// Returns `Err(QrError::DataTooLong)` on overflow.
789    /// Returns [`QrError::InvalidCharacter`] if `data` contains a byte outside
790    /// the QR alphanumeric alphabet.
791    pub fn push_alphanumeric_data(&mut self, data: &[u8]) -> QrResult<()> {
792        self.mode_indicator_bits(ExtendedMode::Data(Mode::Alphanumeric))?;
793        if let Some((position, byte)) = AlphanumericMode::invalid_character(data) {
794            return Err(QrError::InvalidCharacter { position, byte });
795        }
796        self.push_header(Mode::Alphanumeric, data.len())?;
797        for chunk in data.chunks(2) {
798            let number = chunk.iter().map(|b| alphanumeric_digit(*b)).fold(0, |a, b| a * 45 + b);
799            let length = chunk.len() * 5 + 1;
800            self.push_number(length, number);
801        }
802        self.encoding_modes.insert(Mode::Alphanumeric);
803        self.payload_bits_len = None;
804        Ok(())
805    }
806}
807
808#[cfg(test)]
809mod alphanumeric_tests {
810    use crate::bits::Bits;
811    use crate::types::{QrError, Version};
812
813    #[test]
814    fn test_iso_18004_2006_example() {
815        let mut bits = Bits::new(Version::Normal(1));
816        assert_eq!(bits.push_alphanumeric_data(b"AC-42"), Ok(()));
817        assert_eq!(bits.into_bytes(), vec![0b0010_0000, 0b00101_001, 0b11001110, 0b11100111, 0b001_00001, 0b0_0000000]);
818    }
819
820    #[test]
821    fn test_micro_qr_unsupported() {
822        let mut bits = Bits::new(Version::Micro(1));
823        assert_eq!(bits.push_alphanumeric_data(b"A"), Err(QrError::UnsupportedCharacterSet));
824    }
825
826    #[test]
827    fn test_data_too_long() {
828        let mut bits = Bits::new(Version::Micro(2));
829        assert_eq!(bits.push_alphanumeric_data(b"ABCDEFGH"), Err(QrError::DataTooLong));
830    }
831}
832
833//}}}
834//------------------------------------------------------------------------------
835//{{{ Mode::Byte mode
836
837impl Bits {
838    /// Encodes 8-bit byte data to the bits.
839    ///
840    /// # Errors
841    ///
842    /// Returns `Err(QrError::DataTooLong)` on overflow.
843    pub fn push_byte_data(&mut self, data: &[u8]) -> QrResult<()> {
844        self.push_header(Mode::Byte, data.len())?;
845        let offset = self.bit_offset;
846        if offset == 0 {
847            self.data.extend_from_slice(data);
848        } else if let Some((&last, _)) = data.split_last() {
849            let last_index = self.data.len() - 1;
850            self.data[last_index] |= data[0] >> offset;
851            let shift = 8 - offset;
852            self.data.extend(data.windows(2).map(|pair| (pair[0] << shift) | (pair[1] >> offset)));
853            self.data.push(last << shift);
854        }
855        self.encoding_modes.insert(Mode::Byte);
856        self.payload_bits_len = None;
857        Ok(())
858    }
859
860    /// Benchmark-only control retaining the original scalar byte-writing loop.
861    #[cfg(feature = "bench-internals")]
862    #[doc(hidden)]
863    pub fn push_byte_data_scalar_for_bench(&mut self, data: &[u8]) -> QrResult<()> {
864        self.push_header(Mode::Byte, data.len())?;
865        for &byte in data {
866            self.push_number(8, u16::from(byte));
867        }
868        self.encoding_modes.insert(Mode::Byte);
869        self.payload_bits_len = None;
870        Ok(())
871    }
872}
873
874#[cfg(test)]
875mod byte_tests {
876    use crate::bits::Bits;
877    use crate::types::{EcLevel, Mode, QrError, Version};
878
879    // Pack individual bits independently of Bits::push_number and the bulk
880    // byte writer so carry, padding and segment boundaries are checked.
881    fn reference_write(bytes: &mut Vec<u8>, bit_len: &mut usize, width: usize, value: usize) {
882        for index in (0..width).rev() {
883            if (*bit_len).is_multiple_of(8) {
884                bytes.push(0);
885            }
886            let byte_index = bytes.len() - 1;
887            bytes[byte_index] |= (((value >> index) & 1) as u8) << (7 - *bit_len % 8);
888            *bit_len += 1;
889        }
890    }
891
892    fn reference_byte_segment(bytes: &mut Vec<u8>, bit_len: &mut usize, version: Version, data: &[u8]) {
893        let mode_number = if version.is_micro() { 2 } else { 4 };
894        reference_write(bytes, bit_len, version.mode_bits_count(), mode_number);
895        reference_write(bytes, bit_len, Mode::Byte.length_bits_count(version), data.len());
896        for &byte in data {
897            reference_write(bytes, bit_len, 8, usize::from(byte));
898        }
899    }
900
901    fn check_byte_segment(data: &[u8], version: Version, prefix_len: usize) {
902        let mut bits = Bits::new(version);
903        let mut expected = Vec::new();
904        let mut bit_len = 0;
905        if prefix_len > 0 {
906            let prefix = (1 << prefix_len) - 1;
907            bits.push_number_checked(prefix_len, prefix).unwrap();
908            reference_write(&mut expected, &mut bit_len, prefix_len, prefix);
909        }
910        bits.push_byte_data(data).unwrap();
911        reference_byte_segment(&mut expected, &mut bit_len, version, data);
912
913        assert_eq!(bits.len(), bit_len, "{version:?} prefix {prefix_len}, data {data:?}");
914        assert_eq!(bits.bit_offset, bit_len % 8);
915        assert_eq!(bits.data, expected);
916        assert_eq!(bits.encoding_modes(), crate::bits::EncodingModes::from_mode(Mode::Byte));
917        assert_eq!(bits.payload_bits_len, None);
918        #[cfg(feature = "bench-internals")]
919        {
920            let mut scalar = Bits::new(version);
921            if prefix_len > 0 {
922                scalar.push_number_checked(prefix_len, (1 << prefix_len) - 1).unwrap();
923            }
924            scalar.push_byte_data_scalar_for_bench(data).unwrap();
925            assert_eq!(bits.data, scalar.data);
926            assert_eq!(bits.len(), scalar.len());
927        }
928    }
929
930    #[test]
931    fn byte_packing_matches_bit_reference_at_every_offset_and_version_group() {
932        for version in [
933            Version::Normal(1),
934            Version::Normal(9),
935            Version::Normal(10),
936            Version::Normal(26),
937            Version::Normal(27),
938            Version::Normal(40),
939            Version::Micro(3),
940            Version::Micro(4),
941        ] {
942            let max_length = (1 << Mode::Byte.length_bits_count(version)) - 1;
943            for len in [0, 1, 2, 15, 31, 255, 256, 2048].into_iter().filter(|&len| len <= max_length) {
944                let data = (0..len).map(|index| (index % 256) as u8).collect::<Vec<_>>();
945                for prefix_len in 0..8 {
946                    check_byte_segment(&data, version, prefix_len);
947                }
948            }
949        }
950    }
951
952    #[test]
953    fn micro_byte_packing_preserves_every_byte_value_at_every_offset() {
954        for version in [Version::Micro(3), Version::Micro(4)] {
955            for byte in 0..=255 {
956                for prefix_len in 0..8 {
957                    check_byte_segment(&[byte], version, prefix_len);
958                }
959            }
960        }
961    }
962
963    #[test]
964    fn byte_packing_preserves_consecutive_and_mixed_segment_boundaries() {
965        let version = Version::Normal(40);
966        for prefix_len in 0..8 {
967            let mut bits = Bits::new(version);
968            let mut expected = Vec::new();
969            let mut bit_len = 0;
970            if prefix_len > 0 {
971                let prefix = (1 << prefix_len) - 1;
972                bits.push_number_checked(prefix_len, prefix).unwrap();
973                reference_write(&mut expected, &mut bit_len, prefix_len, prefix);
974            }
975            for data in [&b""[..], &[0xff], &[0, 0xa5, 0x7f], &b"longer byte segment"[..], &b""[..]] {
976                bits.push_byte_data(data).unwrap();
977                reference_byte_segment(&mut expected, &mut bit_len, version, data);
978            }
979
980            bits.push_numeric_data(b"12345").unwrap();
981            reference_write(&mut expected, &mut bit_len, 4, 1);
982            reference_write(&mut expected, &mut bit_len, 14, 5);
983            reference_write(&mut expected, &mut bit_len, 10, 123);
984            reference_write(&mut expected, &mut bit_len, 7, 45);
985            bits.push_byte_data(&[0xf0, 0x0f, 0xaa, 0x55]).unwrap();
986            reference_byte_segment(&mut expected, &mut bit_len, version, &[0xf0, 0x0f, 0xaa, 0x55]);
987
988            assert_eq!(bits.data, expected);
989            assert_eq!(bits.len(), bit_len);
990            assert!(bits.encoding_modes().contains(Mode::Numeric));
991            assert!(bits.encoding_modes().contains(Mode::Byte));
992        }
993    }
994
995    #[test]
996    fn empty_byte_segment_after_padding_keeps_header_and_resets_payload_metadata() {
997        let version = Version::Normal(1);
998        let mut bits = Bits::new(version);
999        bits.push_numeric_data(b"1").unwrap();
1000        bits.push_terminator(EcLevel::L).unwrap();
1001        assert!(bits.payload_bits_len.is_some());
1002        let mut expected = bits.data.clone();
1003        let mut bit_len = bits.len();
1004
1005        bits.push_byte_data(&[]).unwrap();
1006        reference_byte_segment(&mut expected, &mut bit_len, version, &[]);
1007
1008        assert_eq!(bits.data, expected);
1009        assert_eq!(bits.len(), bit_len);
1010        assert_eq!(bits.payload_bits_len, None);
1011        assert!(bits.encoding_modes().contains(Mode::Byte));
1012    }
1013
1014    #[test]
1015    fn zero_width_checked_writes_preserve_empty_aligned_and_mixed_streams() {
1016        let empty = Bits::new(Version::Normal(40));
1017        let mut aligned = Bits::new(Version::Normal(40));
1018        aligned.push_number_checked(4, 0xa).unwrap();
1019        aligned.push_byte_data(b"abc").unwrap();
1020        assert_eq!(aligned.bit_offset, 0);
1021        let mut unaligned = Bits::new(Version::Normal(40));
1022        unaligned.push_numeric_data(b"12345").unwrap();
1023        assert_ne!(unaligned.bit_offset, 0);
1024        let mut terminated = Bits::new(Version::Normal(1));
1025        terminated.push_numeric_data(b"1").unwrap();
1026        terminated.push_terminator(EcLevel::M).unwrap();
1027        assert!(terminated.payload_bits_len.is_some());
1028        let mut mixed_byte = Bits::new(Version::Normal(40));
1029        mixed_byte.push_numeric_data(b"12345").unwrap();
1030        mixed_byte.push_byte_data(&[0xab, 0xcd]).unwrap();
1031        let mut mixed_terminated = Bits::new(Version::Normal(40));
1032        mixed_terminated.push_numeric_data(b"12345").unwrap();
1033        mixed_terminated.push_byte_data(&[0xab, 0xcd]).unwrap();
1034        mixed_terminated.push_terminator(EcLevel::M).unwrap();
1035
1036        for (name, mut bits) in [
1037            ("empty", empty),
1038            ("aligned", aligned),
1039            ("unaligned", unaligned),
1040            ("terminated", terminated),
1041            ("mixed_byte", mixed_byte),
1042            ("mixed_terminated", mixed_terminated),
1043        ] {
1044            let expected = bits.data.clone();
1045            let bit_len = bits.len();
1046            let offset = bits.bit_offset;
1047            let capacity = bits.data.capacity();
1048            let modes = bits.encoding_modes();
1049            let payload_len = bits.payload_bits_len;
1050            for number in [0, 1, usize::MAX] {
1051                let result = if number == 0 { Ok(()) } else { Err(QrError::DataTooLong) };
1052                assert_eq!(bits.push_number_checked(0, number), result, "{name} value {number}");
1053                assert_eq!(bits.data, expected, "{name}");
1054                assert_eq!(bits.len(), bit_len, "{name}");
1055                assert_eq!(bits.bit_offset, offset, "{name}");
1056                assert_eq!(bits.data.capacity(), capacity, "{name}");
1057                assert_eq!(bits.encoding_modes(), modes, "{name}");
1058                assert_eq!(bits.payload_bits_len, payload_len, "{name}");
1059            }
1060        }
1061    }
1062
1063    #[test]
1064    fn byte_packing_errors_leave_existing_bits_and_metadata_unchanged() {
1065        for (version, len, error) in [
1066            (Version::Normal(1), 256, QrError::DataTooLong),
1067            (Version::Micro(3), 16, QrError::DataTooLong),
1068            (Version::Micro(4), 32, QrError::DataTooLong),
1069            (Version::Micro(1), 256, QrError::UnsupportedCharacterSet),
1070            (Version::Micro(2), 256, QrError::UnsupportedCharacterSet),
1071        ] {
1072            let mut bits = Bits::new(version);
1073            bits.push_numeric_data(b"1").unwrap();
1074            let expected = bits.data.clone();
1075            let bit_len = bits.len();
1076            let modes = bits.encoding_modes();
1077            let payload_len = bits.payload_bits_len;
1078
1079            assert_eq!(bits.push_byte_data(&vec![0xff; len]), Err(error));
1080            assert_eq!(bits.data, expected);
1081            assert_eq!(bits.len(), bit_len);
1082            assert_eq!(bits.encoding_modes(), modes);
1083            assert_eq!(bits.payload_bits_len, payload_len);
1084        }
1085    }
1086
1087    #[test]
1088    fn test() {
1089        let mut bits = Bits::new(Version::Normal(1));
1090        assert_eq!(bits.push_byte_data(b"\x12\x34\x56\x78\x9a\xbc\xde\xf0"), Ok(()));
1091        assert_eq!(
1092            bits.into_bytes(),
1093            vec![
1094                0b0100_0000,
1095                0b1000_0001,
1096                0b0010_0011,
1097                0b0100_0101,
1098                0b0110_0111,
1099                0b1000_1001,
1100                0b1010_1011,
1101                0b1100_1101,
1102                0b1110_1111,
1103                0b0000_0000,
1104            ]
1105        );
1106    }
1107
1108    #[test]
1109    fn test_micro_qr_unsupported() {
1110        let mut bits = Bits::new(Version::Micro(2));
1111        assert_eq!(bits.push_byte_data(b"?"), Err(QrError::UnsupportedCharacterSet));
1112    }
1113
1114    #[test]
1115    fn test_data_too_long() {
1116        let mut bits = Bits::new(Version::Micro(3));
1117        assert_eq!(bits.push_byte_data(b"0123456701234567"), Err(QrError::DataTooLong));
1118    }
1119}
1120
1121//}}}
1122//------------------------------------------------------------------------------
1123//{{{ Mode::Kanji mode
1124
1125impl Bits {
1126    /// Encodes Shift JIS double-byte data to the bits.
1127    ///
1128    /// # Errors
1129    ///
1130    /// Returns `Err(QrError::DataTooLong)` on overflow.
1131    ///
1132    /// Returns `Err(QrError::InvalidCharacter)` if the data is not Shift JIS
1133    /// double-byte data in the QR Kanji ranges (e.g. if the length of data is
1134    /// not an even number).
1135    pub fn push_kanji_data(&mut self, data: &[u8]) -> QrResult<()> {
1136        self.mode_indicator_bits(ExtendedMode::Data(Mode::Kanji))?;
1137        if let Some((position, byte)) = KanjiMode::invalid_character(data) {
1138            return Err(QrError::InvalidCharacter { position, byte });
1139        }
1140        self.push_header(Mode::Kanji, data.len() / 2)?;
1141        for kanji in data.as_chunks::<2>().0 {
1142            let cp = u16::from(kanji[0]) * 256 + u16::from(kanji[1]);
1143            let bytes = if cp < 0xe040 { cp - 0x8140 } else { cp - 0xc140 };
1144            let number = (bytes >> 8) * 0xc0 + (bytes & 0xff);
1145            self.push_number(13, number);
1146        }
1147        self.encoding_modes.insert(Mode::Kanji);
1148        self.payload_bits_len = None;
1149        Ok(())
1150    }
1151}
1152
1153impl Bits {
1154    /// Encodes data with a type-level QR encoding mode.
1155    ///
1156    /// This is the type-safe counterpart to calling one of
1157    /// [`push_numeric_data`](Self::push_numeric_data),
1158    /// [`push_alphanumeric_data`](Self::push_alphanumeric_data),
1159    /// [`push_byte_data`](Self::push_byte_data), or
1160    /// [`push_kanji_data`](Self::push_kanji_data) directly.
1161    ///
1162    /// # Errors
1163    ///
1164    /// Returns [`QrError::InvalidCharacter`] when `data` is not valid for `M`.
1165    /// Returns the same length or version errors as the mode-specific push
1166    /// method after validation succeeds.
1167    pub fn push_mode_data<M: EncodingMode>(&mut self, data: &[u8]) -> QrResult<()> {
1168        if let Some((position, byte)) = M::invalid_character(data) {
1169            return Err(QrError::InvalidCharacter { position, byte });
1170        }
1171
1172        match M::MODE {
1173            Mode::Numeric => self.push_numeric_data(data),
1174            Mode::Alphanumeric => self.push_alphanumeric_data(data),
1175            Mode::Byte => self.push_byte_data(data),
1176            Mode::Kanji => self.push_kanji_data(data),
1177        }
1178    }
1179}
1180
1181#[cfg(test)]
1182mod typed_mode_tests {
1183    use crate::bits::Bits;
1184    use crate::mode::{AlphanumericMode, ByteMode, KanjiMode, NumericMode};
1185    use crate::types::{EcLevel, Mode, QrError, Version};
1186
1187    #[test]
1188    fn push_mode_data_matches_numeric_specific_encoder() {
1189        let mut typed = Bits::new(Version::Normal(1));
1190        let mut direct = Bits::new(Version::Normal(1));
1191
1192        assert_eq!(typed.push_mode_data::<NumericMode>(b"01234567"), Ok(()));
1193        assert_eq!(direct.push_numeric_data(b"01234567"), Ok(()));
1194        assert_eq!(typed.into_bytes(), direct.into_bytes());
1195    }
1196
1197    #[test]
1198    fn push_mode_data_matches_other_specific_encoders() {
1199        let mut alphanumeric = Bits::new(Version::Normal(1));
1200        let mut byte = Bits::new(Version::Normal(1));
1201        let mut kanji = Bits::new(Version::Normal(1));
1202
1203        assert_eq!(alphanumeric.push_mode_data::<AlphanumericMode>(b"AC-42"), Ok(()));
1204        assert_eq!(byte.push_mode_data::<ByteMode>(b"\x12\x34"), Ok(()));
1205        assert_eq!(kanji.push_mode_data::<KanjiMode>(b"\x93\x5f\xe4\xaa"), Ok(()));
1206    }
1207
1208    #[test]
1209    fn push_mode_data_rejects_invalid_mode_input_before_writing() {
1210        let mut bits = Bits::new(Version::Normal(1));
1211
1212        assert_eq!(
1213            bits.push_mode_data::<NumericMode>(b"12a"),
1214            Err(QrError::InvalidCharacter { position: 2, byte: b'a' })
1215        );
1216        assert!(bits.into_bytes().is_empty());
1217    }
1218
1219    #[test]
1220    fn direct_modes_reject_invalid_input_without_changing_existing_bits() {
1221        let cases: &[(Mode, &[u8], usize, u8)] = &[
1222            (Mode::Numeric, b"12/4", 2, b'/'),
1223            (Mode::Alphanumeric, b"ABc", 2, b'c'),
1224            (Mode::Kanji, b"\x00\x00", 0, 0),
1225            (Mode::Kanji, b"\xeb\xc0", 0, 0xeb),
1226            (Mode::Kanji, b"\x93\x5f\x81", 2, 0x81),
1227            (Mode::Kanji, b"\x93\x5f\xe0\x00", 2, 0xe0),
1228        ];
1229        for &(mode, data, position, byte) in cases {
1230            let mut bits = Bits::new(Version::Normal(1));
1231            bits.push_byte_data(b"seed").unwrap();
1232            bits.push_terminator(EcLevel::L).unwrap();
1233            let previous_data = bits.data.clone();
1234            let previous_modes = bits.encoding_modes();
1235            let previous_payload_len = bits.payload_bits_len();
1236            let result = match mode {
1237                Mode::Numeric => bits.push_numeric_data(data),
1238                Mode::Alphanumeric => bits.push_alphanumeric_data(data),
1239                Mode::Kanji => bits.push_kanji_data(data),
1240                Mode::Byte => unreachable!(),
1241            };
1242
1243            assert_eq!(result, Err(QrError::InvalidCharacter { position, byte }), "{mode:?} {data:?}");
1244            assert_eq!(bits.data, previous_data);
1245            assert_eq!(bits.encoding_modes(), previous_modes);
1246            assert_eq!(bits.payload_bits_len(), previous_payload_len);
1247        }
1248    }
1249
1250    #[test]
1251    fn mode_length_overflow_does_not_write_a_mode_header() {
1252        let mut numeric = Bits::new(Version::Micro(2));
1253        let mut alphanumeric = Bits::new(Version::Micro(2));
1254        let mut byte = Bits::new(Version::Micro(3));
1255        let mut kanji = Bits::new(Version::Micro(3));
1256        let kanji_data = b"\x93\x5f".repeat(8);
1257
1258        assert_eq!(numeric.push_numeric_data(b"0123456789012345"), Err(QrError::DataTooLong));
1259        assert_eq!(alphanumeric.push_alphanumeric_data(b"ABCDEFGH"), Err(QrError::DataTooLong));
1260        assert_eq!(byte.push_byte_data(b"0123456789012345"), Err(QrError::DataTooLong));
1261        assert_eq!(kanji.push_kanji_data(&kanji_data), Err(QrError::DataTooLong));
1262
1263        for bits in [numeric, alphanumeric, byte, kanji] {
1264            assert!(bits.encoding_modes().is_empty());
1265            assert!(bits.into_bytes().is_empty());
1266        }
1267    }
1268
1269    #[test]
1270    fn unsupported_mode_is_rejected_before_length_overflow_without_writing() {
1271        let mut alphanumeric = Bits::new(Version::Micro(1));
1272        let mut byte = Bits::new(Version::Micro(2));
1273
1274        assert_eq!(alphanumeric.push_alphanumeric_data(b"ABCDEFGH"), Err(QrError::UnsupportedCharacterSet));
1275        assert_eq!(byte.push_byte_data(b"0123456789012345"), Err(QrError::UnsupportedCharacterSet));
1276        assert!(alphanumeric.into_bytes().is_empty());
1277        assert!(byte.into_bytes().is_empty());
1278    }
1279
1280    #[test]
1281    fn direct_mode_errors_preserve_unsupported_mode_precedence() {
1282        let cases: &[(Mode, Version, &[u8], QrError)] = &[
1283            (Mode::Alphanumeric, Version::Micro(1), b"c", QrError::UnsupportedCharacterSet),
1284            (Mode::Kanji, Version::Micro(2), b"?", QrError::UnsupportedCharacterSet),
1285            (Mode::Numeric, Version::Micro(1), b"a", QrError::InvalidCharacter { position: 0, byte: b'a' }),
1286            (Mode::Alphanumeric, Version::Micro(2), b"c", QrError::InvalidCharacter { position: 0, byte: b'c' }),
1287            (Mode::Kanji, Version::Micro(3), b"?", QrError::InvalidCharacter { position: 0, byte: b'?' }),
1288        ];
1289        for &(mode, version, data, error) in cases {
1290            let mut bits = Bits::new(version);
1291            bits.push_numeric_data(b"1").unwrap();
1292            let previous_data = bits.data.clone();
1293            let previous_len = bits.len();
1294            let previous_modes = bits.encoding_modes();
1295            let result = match mode {
1296                Mode::Numeric => bits.push_numeric_data(data),
1297                Mode::Alphanumeric => bits.push_alphanumeric_data(data),
1298                Mode::Kanji => bits.push_kanji_data(data),
1299                Mode::Byte => unreachable!(),
1300            };
1301
1302            assert_eq!(result, Err(error), "{mode:?} {version:?} {data:?}");
1303            assert_eq!(bits.data, previous_data);
1304            assert_eq!(bits.len(), previous_len);
1305            assert_eq!(bits.encoding_modes(), previous_modes);
1306        }
1307    }
1308}
1309
1310#[cfg(test)]
1311mod kanji_tests {
1312    use crate::bits::Bits;
1313    use crate::types::{QrError, Version};
1314
1315    #[test]
1316    fn test_iso_18004_example() {
1317        let mut bits = Bits::new(Version::Normal(1));
1318        assert_eq!(bits.push_kanji_data(b"\x93\x5f\xe4\xaa"), Ok(()));
1319        assert_eq!(bits.into_bytes(), vec![0b1000_0000, 0b0010_0110, 0b11001111, 0b1_1101010, 0b101010_00]);
1320    }
1321
1322    #[test]
1323    fn test_micro_qr_unsupported() {
1324        let mut bits = Bits::new(Version::Micro(2));
1325        assert_eq!(bits.push_kanji_data(b"?"), Err(QrError::UnsupportedCharacterSet));
1326    }
1327
1328    #[test]
1329    fn test_data_too_long() {
1330        let mut bits = Bits::new(Version::Micro(3));
1331        assert_eq!(bits.push_kanji_data(b"\x93_\x93_\x93_\x93_\x93_\x93_\x93_\x93_"), Err(QrError::DataTooLong));
1332    }
1333}
1334
1335//}}}
1336//------------------------------------------------------------------------------
1337//{{{ FNC1 mode
1338
1339impl Bits {
1340    /// Encodes an indicator that the following data are formatted according to
1341    /// the UCC/EAN Application Identifiers standard.
1342    ///
1343    ///     #![allow(unused_must_use)]
1344    ///
1345    ///     use qrcode_core::bits::Bits;
1346    ///     use qrcode_core::types::Version;
1347    ///
1348    ///     let mut bits = Bits::new(Version::Normal(1));
1349    ///     bits.push_fnc1_first_position();
1350    ///     bits.push_numeric_data(b"01049123451234591597033130128");
1351    ///     bits.push_alphanumeric_data(b"%10ABC123");
1352    ///
1353    /// In QR code, the character `%` is used as the data field separator (0x1D).
1354    ///
1355    /// # Errors
1356    ///
1357    /// If the mode is not supported in the provided version, this method
1358    /// returns `Err(QrError::UnsupportedCharacterSet)`.
1359    pub fn push_fnc1_first_position(&mut self) -> QrResult<()> {
1360        self.push_mode_indicator(ExtendedMode::Fnc1First)
1361    }
1362
1363    /// Encodes an indicator that the following data are formatted in accordance
1364    /// with specific industry or application specifications previously agreed
1365    /// with AIM International.
1366    ///
1367    ///     #![allow(unused_must_use)]
1368    ///
1369    ///     use qrcode_core::bits::Bits;
1370    ///     use qrcode_core::types::Version;
1371    ///
1372    ///     let mut bits = Bits::new(Version::Normal(1));
1373    ///     bits.push_fnc1_second_position(37);
1374    ///     bits.push_alphanumeric_data(b"AA1234BBB112");
1375    ///     bits.push_byte_data(b"text text text text\r");
1376    ///
1377    /// If the application indicator is a single Latin alphabet (a–z / A–Z),
1378    /// please pass in its ASCII value + 100:
1379    ///
1380    /// ```ignore
1381    /// bits.push_fnc1_second_position(b'A' + 100);
1382    /// ```
1383    ///
1384    /// # Errors
1385    ///
1386    /// If the mode is not supported in the provided version, this method
1387    /// returns `Err(QrError::UnsupportedCharacterSet)`.
1388    pub fn push_fnc1_second_position(&mut self, application_indicator: u8) -> QrResult<()> {
1389        self.push_mode_indicator(ExtendedMode::Fnc1Second)?;
1390        self.push_number(8, u16::from(application_indicator));
1391        Ok(())
1392    }
1393}
1394
1395//}}}
1396//------------------------------------------------------------------------------
1397//{{{ Structured Append
1398
1399impl Bits {
1400    /// Pushes a Structured Append header (ISO/IEC 18004 §7.4) to the front of
1401    /// the bit stream.
1402    ///
1403    /// Structured Append splits one logical message across 2..=16 QR symbols.
1404    /// Every symbol in the sequence carries this 20-bit header as the very
1405    /// first thing in its bit stream, *before* the data mode indicator:
1406    ///
1407    /// - 4-bit mode indicator `0011`,
1408    /// - an 8-bit symbol-sequence indicator whose **high nibble** is this
1409    ///   symbol's zero-based index (`position - 1`) and whose **low nibble** is
1410    ///   `total - 1`,
1411    /// - an 8-bit `parity` byte (the XOR of every byte of the original,
1412    ///   un-split message — identical in every symbol).
1413    ///
1414    /// Structured Append is **not** valid for Micro QR; this method returns
1415    /// `Err(QrError::UnsupportedCharacterSet)` for a Micro QR version.
1416    ///
1417    /// # Errors
1418    ///
1419    /// Returns [`QrError::UnsupportedCharacterSet`] on a Micro QR version, and
1420    /// [`QrError::InvalidStructuredAppend`] if `total` is not `2..=16` or
1421    /// `position` is not `1..=total`.
1422    ///
1423    /// ```
1424    /// use qrcode_core::bits::Bits;
1425    /// use qrcode_core::types::Version;
1426    ///
1427    /// let mut bits = Bits::new(Version::Normal(1));
1428    /// bits.push_structured_append_header(1, 3, 0x5a);
1429    /// // First symbol of a 3-symbol sequence; parity 0x5a.
1430    /// ```
1431    pub fn push_structured_append_header(&mut self, position: u8, total: u8, parity: u8) -> QrResult<()> {
1432        if self.version.is_micro() {
1433            return Err(QrError::UnsupportedCharacterSet);
1434        }
1435        if !(2..=16).contains(&total) || !(1..=total).contains(&position) {
1436            return Err(QrError::InvalidStructuredAppend {
1437                value: if !(2..=16).contains(&total) { total } else { position },
1438            });
1439        }
1440        // ISO/IEC 18004 stores both fields with zero-based nibbles:
1441        // high = position - 1, low = total - 1.
1442        let sequence = (u16::from(position - 1) << 4) | u16::from(total - 1);
1443        self.reserve(20);
1444        self.push_mode_indicator(ExtendedMode::StructuredAppend)?;
1445        self.push_number(8, sequence);
1446        self.push_number(8, u16::from(parity));
1447        Ok(())
1448    }
1449}
1450
1451#[cfg(test)]
1452mod structured_append_tests {
1453    use crate::bits::Bits;
1454    use crate::types::{EcLevel, QrError, Version};
1455
1456    #[test]
1457    fn test_header_bit_layout() {
1458        // First symbol of a 3-symbol sequence, parity 0x5a.
1459        // Bits: 0011 | 0000 0010 (pos 0 | total 2) | 0101 1010 (parity) = 20 bits.
1460        let mut bits = Bits::new(Version::Normal(1));
1461        assert_eq!(bits.push_structured_append_header(1, 3, 0x5a), Ok(()));
1462        assert_eq!(bits.into_bytes(), vec![0x30, 0x25, 0xA0]);
1463    }
1464
1465    #[test]
1466    fn test_header_bit_layout_second_of_two() {
1467        // Second symbol of a 2-symbol sequence, parity 0xff.
1468        // sequence indicator = (1 << 4) | 1 = 0x11.
1469        // Bits: 0011 | 0001 0001 | 1111 1111 → 0x31 0x1f 0xf0.
1470        let mut bits = Bits::new(Version::Normal(1));
1471        assert_eq!(bits.push_structured_append_header(2, 2, 0xff), Ok(()));
1472        assert_eq!(bits.into_bytes(), vec![0x31, 0x1F, 0xF0]);
1473    }
1474
1475    #[test]
1476    fn test_header_value_16_uses_max_nibble() {
1477        // 16th symbol of a 16-symbol sequence, parity 0 → both nibbles are 15.
1478        // Bits: 0011 | 1111 1111 | 0000 0000 → 0x3f 0xf0 0x00.
1479        let mut bits = Bits::new(Version::Normal(1));
1480        assert_eq!(bits.push_structured_append_header(16, 16, 0x00), Ok(()));
1481        assert_eq!(bits.into_bytes(), vec![0x3F, 0xF0, 0x00]);
1482    }
1483
1484    #[test]
1485    fn test_micro_rejected() {
1486        let mut bits = Bits::new(Version::Micro(2));
1487        assert_eq!(bits.push_structured_append_header(1, 2, 0), Err(QrError::UnsupportedCharacterSet));
1488    }
1489
1490    #[test]
1491    fn test_invalid_total() {
1492        let mut bits = Bits::new(Version::Normal(1));
1493        assert_eq!(bits.push_structured_append_header(1, 1, 0), Err(QrError::InvalidStructuredAppend { value: 1 }));
1494        assert_eq!(bits.push_structured_append_header(1, 17, 0), Err(QrError::InvalidStructuredAppend { value: 17 }));
1495    }
1496
1497    #[test]
1498    fn test_invalid_position() {
1499        let mut bits = Bits::new(Version::Normal(1));
1500        assert_eq!(bits.push_structured_append_header(0, 3, 0), Err(QrError::InvalidStructuredAppend { value: 0 }));
1501        assert_eq!(bits.push_structured_append_header(4, 3, 0), Err(QrError::InvalidStructuredAppend { value: 4 }));
1502    }
1503
1504    #[test]
1505    fn test_header_then_data_round_trips() {
1506        // Header + a byte-mode segment + terminator must yield a valid symbol.
1507        let mut bits = Bits::new(Version::Normal(1));
1508        bits.push_structured_append_header(1, 2, 0).unwrap();
1509        bits.push_byte_data(b"ab").unwrap();
1510        assert!(bits.push_terminator(EcLevel::M).is_ok());
1511    }
1512}
1513
1514//}}}
1515//------------------------------------------------------------------------------
1516//{{{ Finish
1517
1518// This table is copied from ISO/IEC 18004:2006 §6.4.10, Table 7.
1519static DATA_LENGTHS: [[usize; 4]; 44] = [
1520    // Normal versions
1521    [152, 128, 104, 72],
1522    [272, 224, 176, 128],
1523    [440, 352, 272, 208],
1524    [640, 512, 384, 288],
1525    [864, 688, 496, 368],
1526    [1088, 864, 608, 480],
1527    [1248, 992, 704, 528],
1528    [1552, 1232, 880, 688],
1529    [1856, 1456, 1056, 800],
1530    [2192, 1728, 1232, 976],
1531    [2592, 2032, 1440, 1120],
1532    [2960, 2320, 1648, 1264],
1533    [3424, 2672, 1952, 1440],
1534    [3688, 2920, 2088, 1576],
1535    [4184, 3320, 2360, 1784],
1536    [4712, 3624, 2600, 2024],
1537    [5176, 4056, 2936, 2264],
1538    [5768, 4504, 3176, 2504],
1539    [6360, 5016, 3560, 2728],
1540    [6888, 5352, 3880, 3080],
1541    [7456, 5712, 4096, 3248],
1542    [8048, 6256, 4544, 3536],
1543    [8752, 6880, 4912, 3712],
1544    [9392, 7312, 5312, 4112],
1545    [10208, 8000, 5744, 4304],
1546    [10960, 8496, 6032, 4768],
1547    [11744, 9024, 6464, 5024],
1548    [12248, 9544, 6968, 5288],
1549    [13048, 10136, 7288, 5608],
1550    [13880, 10984, 7880, 5960],
1551    [14744, 11640, 8264, 6344],
1552    [15640, 12328, 8920, 6760],
1553    [16568, 13048, 9368, 7208],
1554    [17528, 13800, 9848, 7688],
1555    [18448, 14496, 10288, 7888],
1556    [19472, 15312, 10832, 8432],
1557    [20528, 15936, 11408, 8768],
1558    [21616, 16816, 12016, 9136],
1559    [22496, 17728, 12656, 9776],
1560    [23648, 18672, 13328, 10208],
1561    // Micro versions
1562    [20, 0, 0, 0],
1563    [40, 32, 0, 0],
1564    [84, 68, 0, 0],
1565    [128, 112, 80, 0],
1566];
1567
1568impl Bits {
1569    /// Pushes the ending bits to indicate no more data.
1570    ///
1571    /// # Errors
1572    ///
1573    /// Returns `Err(QrError::DataTooLong)` on overflow.
1574    ///
1575    /// Returns `Err(QrError::InvalidVersion)` if it is not valid to use the
1576    /// `ec_level` for the given version (e.g. `Version::Micro(1)` with
1577    /// `EcLevel::H`).
1578    pub fn push_terminator(&mut self, ec_level: EcLevel) -> QrResult<()> {
1579        let terminator_size = match self.version {
1580            Version::Micro(a) => a.as_usize() * 2 + 1,
1581            Version::Normal(_) => 4,
1582        };
1583
1584        let cur_length = self.len();
1585        let data_length = self.max_len(ec_level)?;
1586        if cur_length > data_length {
1587            return Err(QrError::DataTooLong);
1588        }
1589        self.payload_bits_len = Some(cur_length);
1590
1591        let terminator_size = min(terminator_size, data_length - cur_length);
1592        if terminator_size > 0 {
1593            self.push_number(terminator_size, 0);
1594        }
1595
1596        if self.len() < data_length {
1597            const PADDING_BYTES: &[u8] = &[0b1110_1100, 0b0001_0001];
1598
1599            self.bit_offset = 0;
1600            let data_bytes_length = data_length / 8;
1601            let padding_bytes_count = data_bytes_length.saturating_sub(self.data.len());
1602            let padding = PADDING_BYTES.iter().copied().cycle().take(padding_bytes_count);
1603            self.data.extend(padding);
1604        }
1605
1606        if self.len() < data_length {
1607            self.data.push(0);
1608        }
1609
1610        Ok(())
1611    }
1612}
1613
1614#[cfg(test)]
1615mod finish_tests {
1616    use crate::bits::Bits;
1617    use crate::types::{EcLevel, QrError, Version};
1618
1619    #[test]
1620    fn test_hello_world() {
1621        let mut bits = Bits::new(Version::Normal(1));
1622        assert_eq!(bits.push_alphanumeric_data(b"HELLO WORLD"), Ok(()));
1623        assert_eq!(bits.push_terminator(EcLevel::Q), Ok(()));
1624        assert_eq!(
1625            bits.into_bytes(),
1626            vec![
1627                0b00100000, 0b01011011, 0b00001011, 0b01111000, 0b11010001, 0b01110010, 0b11011100, 0b01001101,
1628                0b01000011, 0b01000000, 0b11101100, 0b00010001, 0b11101100,
1629            ]
1630        );
1631    }
1632
1633    #[test]
1634    fn test_too_long() {
1635        let mut bits = Bits::new(Version::Micro(1));
1636        assert_eq!(bits.push_numeric_data(b"9999999"), Ok(()));
1637        assert_eq!(bits.push_terminator(EcLevel::L), Err(QrError::DataTooLong));
1638    }
1639
1640    #[test]
1641    fn test_no_terminator() {
1642        let mut bits = Bits::new(Version::Micro(1));
1643        assert_eq!(bits.push_numeric_data(b"99999"), Ok(()));
1644        assert_eq!(bits.push_terminator(EcLevel::L), Ok(()));
1645        assert_eq!(bits.into_bytes(), vec![0b101_11111, 0b00111_110, 0b0011_0000]);
1646    }
1647
1648    #[test]
1649    fn test_no_padding() {
1650        let mut bits = Bits::new(Version::Micro(1));
1651        assert_eq!(bits.push_numeric_data(b"9999"), Ok(()));
1652        assert_eq!(bits.push_terminator(EcLevel::L), Ok(()));
1653        assert_eq!(bits.into_bytes(), vec![0b100_11111, 0b00111_100, 0b1_000_0000]);
1654    }
1655
1656    #[test]
1657    fn test_micro_version_1_half_byte_padding() {
1658        let mut bits = Bits::new(Version::Micro(1));
1659        assert_eq!(bits.push_numeric_data(b"999"), Ok(()));
1660        assert_eq!(bits.push_terminator(EcLevel::L), Ok(()));
1661        assert_eq!(bits.into_bytes(), vec![0b011_11111, 0b00111_000, 0b0000_0000]);
1662    }
1663
1664    #[test]
1665    fn test_micro_version_1_full_byte_padding() {
1666        let mut bits = Bits::new(Version::Micro(1));
1667        assert_eq!(bits.push_numeric_data(b""), Ok(()));
1668        assert_eq!(bits.push_terminator(EcLevel::L), Ok(()));
1669        assert_eq!(bits.into_bytes(), vec![0b000_000_00, 0b11101100, 0]);
1670    }
1671}
1672
1673//}}}
1674//------------------------------------------------------------------------------
1675//{{{ Front end.
1676
1677impl Bits {
1678    /// Push a segmented data to the bits, and then terminate it.
1679    ///
1680    /// # Errors
1681    ///
1682    /// Returns `Err(QrError::DataTooLong)` on overflow.
1683    ///
1684    /// Returns `Err(QrError::InvalidData)` if the segment refers to incorrectly
1685    /// encoded byte sequences.
1686    pub fn push_segments<I>(&mut self, data: &[u8], segments_iter: I) -> QrResult<()>
1687    where
1688        I: Iterator<Item = Segment>,
1689    {
1690        for segment in segments_iter {
1691            let slice = &data[segment.begin..segment.end];
1692            match segment.mode {
1693                Mode::Numeric => self.push_numeric_data(slice),
1694                Mode::Alphanumeric => self.push_alphanumeric_data(slice),
1695                Mode::Byte => self.push_byte_data(slice),
1696                Mode::Kanji => self.push_kanji_data(slice),
1697            }?;
1698        }
1699        Ok(())
1700    }
1701
1702    /// Pushes the data the bits, using the optimal encoding.
1703    ///
1704    /// # Errors
1705    ///
1706    /// Returns `Err(QrError::DataTooLong)` on overflow.
1707    pub fn push_optimal_data(&mut self, data: &[u8]) -> QrResult<()> {
1708        let segments = Parser::new(data).optimize(self.version);
1709        self.push_segments(data, segments)
1710    }
1711}
1712
1713#[cfg(test)]
1714mod encode_tests {
1715    use crate::bits::Bits;
1716    use crate::types::{EcLevel, QrError, QrResult, Version};
1717
1718    fn encode(data: &[u8], version: Version, ec_level: EcLevel) -> QrResult<Vec<u8>> {
1719        let mut bits = Bits::new(version);
1720        bits.push_optimal_data(data)?;
1721        bits.push_terminator(ec_level)?;
1722        Ok(bits.into_bytes())
1723    }
1724
1725    #[test]
1726    fn test_alphanumeric() {
1727        let res = encode(b"HELLO WORLD", Version::Normal(1), EcLevel::Q);
1728        assert_eq!(
1729            res,
1730            Ok(vec![
1731                0b00100000, 0b01011011, 0b00001011, 0b01111000, 0b11010001, 0b01110010, 0b11011100, 0b01001101,
1732                0b01000011, 0b01000000, 0b11101100, 0b00010001, 0b11101100,
1733            ])
1734        );
1735    }
1736
1737    #[test]
1738    fn test_auto_mode_switch() {
1739        let res = encode(b"123A", Version::Micro(2), EcLevel::L);
1740        assert_eq!(res, Ok(vec![0b0_0011_000, 0b1111011_1, 0b001_00101, 0b0_00000_00, 0b11101100]));
1741    }
1742
1743    #[test]
1744    fn test_too_long() {
1745        let res = encode(b">>>>>>>>", Version::Normal(1), EcLevel::H);
1746        assert_eq!(res, Err(QrError::DataTooLong));
1747    }
1748}
1749
1750//}}}
1751//------------------------------------------------------------------------------
1752//{{{ Auto version minimization
1753
1754/// Returns the data capacity (in bits) for the given version and error
1755/// correction level — the maximum number of data bits a symbol of that version
1756/// can hold.
1757///
1758/// # Errors
1759///
1760/// Returns [`QrError::InvalidVersion`] for an incompatible version / ec-level
1761/// combination (e.g. a Micro QR version with [`EcLevel::H`]).
1762pub fn data_capacity_bits(version: Version, ec_level: EcLevel) -> QrResult<usize> {
1763    version.fetch(ec_level, &DATA_LENGTHS)
1764}
1765
1766/// Automatically determines the minimum version to store the data, and encode
1767/// the result.
1768///
1769/// This method will not consider any Micro QR code versions.
1770///
1771/// # Errors
1772///
1773/// Returns `Err(QrError::DataTooLong)` if the data is too long to fit even the
1774/// highest QR code version.
1775pub fn encode_auto(data: &[u8], ec_level: EcLevel) -> QrResult<Bits> {
1776    if data.len() > crate::limits::DEFAULT_MAX_DATA_LENGTH {
1777        return Err(QrError::DataTooLong);
1778    }
1779    encode_auto_with_max_version(data, ec_level, 40)
1780}
1781
1782/// Automatically encodes data while capping normal QR version selection.
1783///
1784/// This is the bounded counterpart to [`encode_auto`]. The maximum version is
1785/// validated by the caller (`ResourceLimits`) and is kept as a small integer
1786/// here so this low-level helper remains useful to the facade without adding
1787/// a dependency cycle.
1788pub fn encode_auto_with_max_version(data: &[u8], ec_level: EcLevel, max_version: i16) -> QrResult<Bits> {
1789    if !(1..=40).contains(&max_version) {
1790        return Err(QrError::InvalidResourceLimits);
1791    }
1792    let segments = Parser::new(data).collect::<Vec<Segment>>();
1793    let mut checkpoints = [0_i16; 4];
1794    let mut checkpoint_count = 0;
1795    for candidate in [9_i16, 26, 40, max_version] {
1796        if candidate <= max_version && !checkpoints[..checkpoint_count].contains(&candidate) {
1797            checkpoints[checkpoint_count] = candidate;
1798            checkpoint_count += 1;
1799        }
1800    }
1801    for candidate in checkpoints[..checkpoint_count].iter() {
1802        let version = Version::Normal(*candidate);
1803        let opt_segments = optimize_segments(&segments, version);
1804        let total_len = total_encoded_len(&opt_segments, version);
1805        let data_capacity = version.fetch(ec_level, &DATA_LENGTHS)?;
1806        if total_len <= data_capacity {
1807            let min_version = find_min_version_up_to(total_len, ec_level, *candidate);
1808            let mut bits = Bits::new(min_version);
1809            bits.reserve(total_len);
1810            bits.push_segments(data, opt_segments.into_iter())?;
1811            bits.push_terminator(ec_level)?;
1812            return Ok(bits);
1813        }
1814    }
1815    Err(QrError::DataTooLong)
1816}
1817
1818fn find_min_version_up_to(length: usize, ec_level: EcLevel, max_version: i16) -> Version {
1819    for version in 1..=max_version {
1820        if DATA_LENGTHS[(version - 1) as usize][ec_level as usize] >= length {
1821            return Version::Normal(version);
1822        }
1823    }
1824    Version::Normal(max_version)
1825}
1826
1827/// Automatically determines the minimum Micro QR version to store the data,
1828/// and encode the result.
1829///
1830/// This method only considers Micro QR code versions (1–4).
1831///
1832/// # Errors
1833///
1834/// Returns `Err(QrError::DataTooLong)` if the data is too long to fit even the
1835/// highest Micro QR version.
1836///
1837/// Returns `Err(QrError::InvalidVersion)` if the `ec_level` is not supported
1838/// by any Micro QR version (e.g. `EcLevel::H`).
1839pub fn encode_auto_micro(data: &[u8], ec_level: EcLevel) -> QrResult<Bits> {
1840    // M4 supports every error-correction level available to any Micro version.
1841    Version::Micro(4).fetch(ec_level, &DATA_LENGTHS)?;
1842    if data.len() > crate::limits::DEFAULT_MAX_DATA_LENGTH {
1843        return Err(QrError::DataTooLong);
1844    }
1845    let segments = Parser::new(data).collect::<Vec<Segment>>();
1846    for micro_version in 1..=4 {
1847        let version = Version::Micro(micro_version);
1848        let data_capacity = match version.fetch(ec_level, &DATA_LENGTHS) {
1849            Ok(cap) if cap > 0 => cap,
1850            _ => continue,
1851        };
1852        if !segments.iter().all(|segment| match segment.mode {
1853            Mode::Numeric => true,
1854            Mode::Alphanumeric => micro_version >= 2,
1855            Mode::Byte | Mode::Kanji => micro_version >= 3,
1856        }) {
1857            continue;
1858        }
1859        let opt_segments = optimize_segments(&segments, version);
1860        let total_len = total_encoded_len(&opt_segments, version);
1861        if total_len <= data_capacity {
1862            let mut bits = Bits::new(version);
1863            bits.reserve(total_len);
1864            bits.push_segments(data, opt_segments.into_iter())?;
1865            bits.push_terminator(ec_level)?;
1866            return Ok(bits);
1867        }
1868    }
1869    Err(QrError::DataTooLong)
1870}
1871
1872/// Finds the smallest version (QR code only) that can store N bits of data
1873/// in the given error correction level.
1874pub fn find_min_version(length: usize, ec_level: EcLevel) -> Version {
1875    let mut base = 0_usize;
1876    let mut size = 39;
1877    while size > 1 {
1878        let half = size / 2;
1879        let mid = base + half;
1880        // mid is always in [0, size).
1881        // mid >= 0: by definition
1882        // mid < size: mid = size / 2 + size / 4 + size / 8 ...
1883        base = if DATA_LENGTHS[mid][ec_level as usize] > length { base } else { mid };
1884        size -= half;
1885    }
1886    // base is always in [0, mid) because base <= mid.
1887    base = if DATA_LENGTHS[base][ec_level as usize] >= length { base } else { base + 1 };
1888    Version::Normal((base + 1).as_i16())
1889}
1890
1891#[cfg(test)]
1892mod encode_auto_tests {
1893    use crate::bits::{encode_auto, encode_auto_micro, encode_auto_with_max_version, find_min_version};
1894    use crate::types::{EcLevel, QrError, Version};
1895
1896    #[test]
1897    fn test_find_min_version() {
1898        assert_eq!(find_min_version(60, EcLevel::L), Version::Normal(1));
1899        assert_eq!(find_min_version(200, EcLevel::L), Version::Normal(2));
1900        assert_eq!(find_min_version(200, EcLevel::H), Version::Normal(3));
1901        assert_eq!(find_min_version(20000, EcLevel::L), Version::Normal(37));
1902        assert_eq!(find_min_version(640, EcLevel::L), Version::Normal(4));
1903        assert_eq!(find_min_version(641, EcLevel::L), Version::Normal(5));
1904        assert_eq!(find_min_version(999999, EcLevel::H), Version::Normal(40));
1905    }
1906
1907    #[test]
1908    fn test_alpha_q() {
1909        let bits = encode_auto(b"HELLO WORLD", EcLevel::Q).unwrap();
1910        assert_eq!(bits.version(), Version::Normal(1));
1911    }
1912
1913    #[test]
1914    fn test_alpha_h() {
1915        let bits = encode_auto(b"HELLO WORLD", EcLevel::H).unwrap();
1916        assert_eq!(bits.version(), Version::Normal(2));
1917    }
1918
1919    #[test]
1920    fn test_mixed() {
1921        let bits = encode_auto(b"This is a mixed data test. 1234567890", EcLevel::H).unwrap();
1922        assert_eq!(bits.version(), Version::Normal(4));
1923    }
1924
1925    #[test]
1926    fn bounded_auto_encoding_rejects_version_overflow_and_caps_search() {
1927        assert!(matches!(encode_auto_with_max_version(b"x", EcLevel::M, 0), Err(QrError::InvalidResourceLimits)));
1928        assert!(matches!(encode_auto_with_max_version(&[0_u8; 128], EcLevel::M, 1), Err(QrError::DataTooLong)));
1929    }
1930
1931    #[test]
1932    fn micro_auto_selection_skips_versions_that_cannot_encode_the_payload_mode() {
1933        let cases: &[(&[u8], EcLevel, i16)] = &[
1934            (b"1", EcLevel::L, 1),
1935            (b"A", EcLevel::L, 2),
1936            (b"a", EcLevel::L, 3),
1937            (b"abc", EcLevel::L, 3),
1938            (b"\x93\x5f", EcLevel::L, 3),
1939            (b"123A", EcLevel::L, 2),
1940            (b"123a", EcLevel::L, 3),
1941            (b"\x93\x5f1", EcLevel::L, 3),
1942            (b"A", EcLevel::Q, 4),
1943        ];
1944        for &(data, ec_level, expected) in cases {
1945            let bits = encode_auto_micro(data, ec_level).unwrap();
1946            assert_eq!(bits.version(), Version::Micro(expected), "{data:?} {ec_level:?}");
1947
1948            let mut fixed = crate::bits::Bits::new(Version::Micro(expected));
1949            fixed.push_optimal_data(data).unwrap();
1950            fixed.push_terminator(ec_level).unwrap();
1951            assert_eq!(bits.into_bytes(), fixed.into_bytes(), "{data:?} {ec_level:?}");
1952        }
1953    }
1954
1955    #[test]
1956    fn micro_auto_selection_distinguishes_unsupported_ec_from_payload_overflow() {
1957        assert!(matches!(
1958            encode_auto_micro(b"1", EcLevel::H),
1959            Err(QrError::InvalidVersion { version: Version::Micro(4), ec_level: EcLevel::H })
1960        ));
1961        assert!(matches!(encode_auto_micro(&[b'1'; 100], EcLevel::L), Err(QrError::DataTooLong)));
1962    }
1963}
1964
1965//}}}
1966//------------------------------------------------------------------------------