From a4ae80b1b71fdb473e38cccb2957cbc6362b35bd Mon Sep 17 00:00:00 2001 From: kennytm Date: Sat, 29 Nov 2014 05:29:01 +0800 Subject: [PATCH] rustup. Quantify all enums, and renamed (shortened) a few types. --- src/bits.rs | 248 ++++++++++++++--------------- src/canvas.rs | 326 ++++++++++++++++++++------------------ src/ec.rs | 12 +- src/lib.rs | 52 +++--- src/optimize.rs | 414 +++++++++++++++++++++++++----------------------- src/types.rs | 123 +++++++------- 6 files changed, 599 insertions(+), 576 deletions(-) diff --git a/src/bits.rs b/src/bits.rs index 9a575e9..aa6a640 100644 --- a/src/bits.rs +++ b/src/bits.rs @@ -7,10 +7,7 @@ use std::cmp::min; #[cfg(test)] use test::Bencher; -use types::{QrResult, DataTooLong, UnsupportedCharacterSet, InvalidEciDesignator, - InvalidCharacter, - Mode, Numeric, Alphanumeric, Byte, Kanji, - ErrorCorrectionLevel, QrVersion, Version, MicroVersion}; +use types::{QrResult, QrError, Mode, EcLevel, Version}; use optimize::{Parser, Optimizer, total_encoded_len, Segment}; //------------------------------------------------------------------------------ @@ -20,12 +17,12 @@ use optimize::{Parser, Optimizer, total_encoded_len, Segment}; pub struct Bits { data: Vec, bit_offset: uint, - version: QrVersion, + version: Version, } impl Bits { /// Constructs a new, empty bits structure. - pub fn new(version: QrVersion) -> Bits { + pub fn new(version: Version) -> Bits { Bits { data: Vec::new(), bit_offset: 0, version: version } } @@ -66,10 +63,10 @@ impl Bits { /// Pushes an N-bit big-endian integer to the end of the bits, and check /// that the number does not overflow the bits. /// - /// Returns `Err(DataTooLong)` on overflow. + /// Returns `Err(QrError::DataTooLong)` on overflow. fn push_number_checked(&mut self, n: uint, number: uint) -> QrResult<()> { if n > 16 || number >= (1 << n) { - Err(DataTooLong) + Err(QrError::DataTooLong) } else { self.push_number(n, number as u16); Ok(()) @@ -97,14 +94,14 @@ impl Bits { } /// Version of the QR code. - pub fn version(&self) -> QrVersion { + pub fn version(&self) -> Version { self.version } } #[test] fn test_push_number() { - let mut bits = Bits::new(Version(1)); + let mut bits = Bits::new(Version::Normal(1)); bits.push_number(3, 0b010); // 0:0 .. 0:3 bits.push_number(3, 0b110); // 0:3 .. 0:6 @@ -130,7 +127,7 @@ fn test_push_number() { #[bench] fn bench_push_splitted_bytes(bencher: &mut Bencher) { bencher.iter(|| { - let mut bits = Bits::new(Version(40)); + let mut bits = Bits::new(Version::Normal(40)); bits.push_number(4, 0b0101); for _ in range(0u, 1024) { bits.push_number(8, 0b10101010); @@ -166,27 +163,27 @@ impl Bits { /// Push the mode indicator to the end of the bits. /// /// If the mode is not supported in the provided version, this method - /// returns `Err(UnsupportedCharacterSet)`. + /// returns `Err(QrError::UnsupportedCharacterSet)`. #[unstable] pub fn push_mode_indicator(&mut self, mode: ExtendedMode) -> QrResult<()> { let number = match (self.version, mode) { - (MicroVersion(1), Data(Numeric)) => return Ok(()), - (MicroVersion(_), Data(Numeric)) => 0, - (MicroVersion(_), Data(Alphanumeric)) => 1, - (MicroVersion(_), Data(Byte)) => 0b10, - (MicroVersion(_), Data(Kanji)) => 0b11, - (MicroVersion(_), _) => return Err(UnsupportedCharacterSet), - (_, Data(Numeric)) => 0b0001, - (_, Data(Alphanumeric)) => 0b0010, - (_, Data(Byte)) => 0b0100, - (_, Data(Kanji)) => 0b1000, - (_, Eci) => 0b0111, - (_, Fnc1First) => 0b0101, - (_, Fnc1Second) => 0b1001, - (_, StructuredAppend) => 0b0011, + (Version::Micro(1), ExtendedMode::Data(Mode::Numeric)) => return Ok(()), + (Version::Micro(_), ExtendedMode::Data(Mode::Numeric)) => 0, + (Version::Micro(_), ExtendedMode::Data(Mode::Alphanumeric)) => 1, + (Version::Micro(_), ExtendedMode::Data(Mode::Byte)) => 0b10, + (Version::Micro(_), ExtendedMode::Data(Mode::Kanji)) => 0b11, + (Version::Micro(_), _) => return Err(QrError::UnsupportedCharacterSet), + (_, ExtendedMode::Data(Mode::Numeric)) => 0b0001, + (_, ExtendedMode::Data(Mode::Alphanumeric)) => 0b0010, + (_, ExtendedMode::Data(Mode::Byte)) => 0b0100, + (_, ExtendedMode::Data(Mode::Kanji)) => 0b1000, + (_, ExtendedMode::Eci) => 0b0111, + (_, ExtendedMode::Fnc1First) => 0b0101, + (_, ExtendedMode::Fnc1Second) => 0b1001, + (_, ExtendedMode::StructuredAppend) => 0b0011, }; let bits = self.version.mode_bits_count(); - self.push_number_checked(bits, number).or(Err(UnsupportedCharacterSet)) + self.push_number_checked(bits, number).or(Err(QrError::UnsupportedCharacterSet)) } } @@ -206,7 +203,7 @@ impl Bits { /// use qrcode::bits::Bits; /// use qrcode::types::Version; /// - /// let mut bits = Bits::new(Version(1)); + /// let mut bits = Bits::new(Version::Normal(1)); /// bits.push_eci_designator(9); // 9 = ISO-8859-7 (Greek). /// bits.push_byte_data(b"\xa1\xa2\xa3\xa4\xa5"); // ΑΒΓΔΕ /// @@ -226,13 +223,13 @@ impl Bits { /// 30 | EUC-KR (Korean) /// /// If the QR code version does not support ECI, this method will return - /// `Err(UnsupportedCharacterSet)`. + /// `Err(QrError::UnsupportedCharacterSet)`. /// /// If the designator is outside of the expected range, this method will - /// return `Err(InvalidECIDesignator)`. + /// return `Err(QrError::InvalidECIDesignator)`. pub fn push_eci_designator(&mut self, eci_designator: u32) -> QrResult<()> { self.reserve(12); // assume the common case that eci_designator <= 127. - try!(self.push_mode_indicator(Eci)); + try!(self.push_mode_indicator(ExtendedMode::Eci)); match eci_designator { 0...127 => { self.push_number(8, eci_designator as u16); @@ -246,7 +243,7 @@ impl Bits { self.push_number(5, (eci_designator >> 16) as u16); self.push_number(16, (eci_designator & 0xffff) as u16); } - _ => return Err(InvalidEciDesignator), + _ => return Err(QrError::InvalidEciDesignator), } Ok(()) } @@ -255,25 +252,25 @@ impl Bits { #[cfg(test)] mod eci_tests { use bits::Bits; - use types::{MicroVersion, Version, InvalidEciDesignator, UnsupportedCharacterSet}; + use types::{Version, QrError}; #[test] fn test_9() { - let mut bits = Bits::new(Version(1)); + let mut bits = Bits::new(Version::Normal(1)); assert_eq!(bits.push_eci_designator(9), Ok(())); assert_eq!(bits.into_bytes(), vec![0b0111__0000, 0b1001__0000]); } #[test] fn test_899() { - let mut bits = Bits::new(Version(1)); + let mut bits = Bits::new(Version::Normal(1)); assert_eq!(bits.push_eci_designator(899), Ok(())); assert_eq!(bits.into_bytes(), vec![0b0111__10_00, 0b00111000, 0b0011__0000]); } #[test] fn test_999999() { - let mut bits = Bits::new(Version(1)); + let mut bits = Bits::new(Version::Normal(1)); assert_eq!(bits.push_eci_designator(999999), Ok(())); assert_eq!(bits.into_bytes(), vec![0b0111__110_0, 0b11110100, @@ -283,26 +280,26 @@ mod eci_tests { #[test] fn test_invalid_designator() { - let mut bits = Bits::new(Version(1)); - assert_eq!(bits.push_eci_designator(1000000), Err(InvalidEciDesignator)); + let mut bits = Bits::new(Version::Normal(1)); + assert_eq!(bits.push_eci_designator(1000000), Err(QrError::InvalidEciDesignator)); } #[test] fn test_unsupported_character_set() { - let mut bits = Bits::new(MicroVersion(4)); - assert_eq!(bits.push_eci_designator(9), Err(UnsupportedCharacterSet)); + let mut bits = Bits::new(Version::Micro(4)); + assert_eq!(bits.push_eci_designator(9), Err(QrError::UnsupportedCharacterSet)); } } //}}} //------------------------------------------------------------------------------ -//{{{ Numeric mode +//{{{ Mode::Numeric mode impl Bits { fn push_header(&mut self, mode: Mode, raw_data_len: uint) -> QrResult<()> { let length_bits = mode.length_bits_count(self.version); self.reserve(length_bits + 4 + mode.data_bits_count(raw_data_len)); - try!(self.push_mode_indicator(Data(mode))); + try!(self.push_mode_indicator(ExtendedMode::Data(mode))); try!(self.push_number_checked(length_bits, raw_data_len)); Ok(()) } @@ -312,7 +309,7 @@ impl Bits { /// The data should only contain the characters 0 to 9. #[unstable] pub fn push_numeric_data(&mut self, data: &[u8]) -> QrResult<()> { - try!(self.push_header(Numeric, data.len())); + try!(self.push_header(Mode::Numeric, data.len())); for chunk in data.chunks(3) { let number = chunk.iter().map(|b| (*b - b'0') as u16).fold(0, |a, b| a*10 + b); let length = chunk.len() * 3 + 1; @@ -325,11 +322,11 @@ impl Bits { #[cfg(test)] mod numeric_tests { use bits::Bits; - use types::{Version, MicroVersion, DataTooLong}; + use types::{Version, QrError}; #[test] fn test_iso_18004_2006_example_1() { - let mut bits = Bits::new(Version(1)); + let mut bits = Bits::new(Version::Normal(1)); assert_eq!(bits.push_numeric_data(b"01234567"), Ok(())); assert_eq!(bits.into_bytes(), vec![0b0001_0000, 0b001000_00, @@ -341,7 +338,7 @@ mod numeric_tests { #[test] fn test_iso_18004_2000_example_2() { - let mut bits = Bits::new(Version(1)); + let mut bits = Bits::new(Version::Normal(1)); assert_eq!(bits.push_numeric_data(b"0123456789012345"), Ok(())); assert_eq!(bits.into_bytes(), vec![0b0001_0000, 0b010000_00, @@ -356,7 +353,7 @@ mod numeric_tests { #[test] fn test_iso_18004_2006_example_2() { - let mut bits = Bits::new(MicroVersion(3)); + let mut bits = Bits::new(Version::Micro(3)); assert_eq!(bits.push_numeric_data(b"0123456789012345"), Ok(())); assert_eq!(bits.into_bytes(), vec![0b00_10000_0, 0b00000110, @@ -370,16 +367,16 @@ mod numeric_tests { #[test] fn test_data_too_long_error() { - let mut bits = Bits::new(MicroVersion(1)); - assert_eq!(bits.push_numeric_data(b"12345678"), Err(DataTooLong)); + let mut bits = Bits::new(Version::Micro(1)); + assert_eq!(bits.push_numeric_data(b"12345678"), Err(QrError::DataTooLong)); } } //}}} //------------------------------------------------------------------------------ -//{{{ Alphanumeric mode +//{{{ Mode::Alphanumeric mode -/// In QR code "Alphanumeric" mode, a pair of alphanumeric characters will be +/// In QR code "Mode::Alphanumeric" mode, a pair of alphanumeric characters will be /// encoded as a base-45 integer. `alphanumeric_digit` converts each character /// into its corresponding base-45 digit. /// @@ -409,7 +406,7 @@ impl Bits { /// 0 to 9, space, `$`, `%`, `*`, `+`, `-`, `.`, `/` or `:`. #[unstable] pub fn push_alphanumeric_data(&mut self, data: &[u8]) -> QrResult<()> { - try!(self.push_header(Alphanumeric, data.len())); + try!(self.push_header(Mode::Alphanumeric, data.len())); for chunk in data.chunks(2) { let number = chunk.iter().map(|b| alphanumeric_digit(*b)).fold(0, |a, b| a*45 + b); let length = chunk.len() * 5 + 1; @@ -422,11 +419,11 @@ impl Bits { #[cfg(test)] mod alphanumeric_tests { use bits::Bits; - use types::{Version, MicroVersion, UnsupportedCharacterSet, DataTooLong}; + use types::{Version, QrError}; #[test] fn test_iso_18004_2006_example() { - let mut bits = Bits::new(Version(1)); + let mut bits = Bits::new(Version::Normal(1)); assert_eq!(bits.push_alphanumeric_data(b"AC-42"), Ok(())); assert_eq!(bits.into_bytes(), vec![0b0010_0000, 0b00101_001, @@ -438,26 +435,26 @@ mod alphanumeric_tests { #[test] fn test_micro_qr_unsupported() { - let mut bits = Bits::new(MicroVersion(1)); - assert_eq!(bits.push_alphanumeric_data(b"A"), Err(UnsupportedCharacterSet)); + let mut bits = Bits::new(Version::Micro(1)); + assert_eq!(bits.push_alphanumeric_data(b"A"), Err(QrError::UnsupportedCharacterSet)); } #[test] fn test_data_too_long() { - let mut bits = Bits::new(MicroVersion(2)); - assert_eq!(bits.push_alphanumeric_data(b"ABCDEFGH"), Err(DataTooLong)); + let mut bits = Bits::new(Version::Micro(2)); + assert_eq!(bits.push_alphanumeric_data(b"ABCDEFGH"), Err(QrError::DataTooLong)); } } //}}} //------------------------------------------------------------------------------ -//{{{ Byte mode +//{{{ Mode::Byte mode impl Bits { /// Encodes 8-bit byte data to the bits. #[unstable] pub fn push_byte_data(&mut self, data: &[u8]) -> QrResult<()> { - try!(self.push_header(Byte, data.len())); + try!(self.push_header(Mode::Byte, data.len())); for b in data.iter() { self.push_number(8, *b as u16); } @@ -468,11 +465,11 @@ impl Bits { #[cfg(test)] mod byte_tests { use bits::Bits; - use types::{Version, MicroVersion, UnsupportedCharacterSet, DataTooLong}; + use types::{Version, QrError}; #[test] fn test() { - let mut bits = Bits::new(Version(1)); + let mut bits = Bits::new(Version::Normal(1)); assert_eq!(bits.push_byte_data(b"\x12\x34\x56\x78\x9a\xbc\xde\xf0"), Ok(())); assert_eq!(bits.into_bytes(), vec![0b0100_0000, 0b1000_0001, @@ -488,29 +485,29 @@ mod byte_tests { #[test] fn test_micro_qr_unsupported() { - let mut bits = Bits::new(MicroVersion(2)); - assert_eq!(bits.push_byte_data(b"?"), Err(UnsupportedCharacterSet)); + let mut bits = Bits::new(Version::Micro(2)); + assert_eq!(bits.push_byte_data(b"?"), Err(QrError::UnsupportedCharacterSet)); } #[test] fn test_data_too_long() { - let mut bits = Bits::new(MicroVersion(3)); - assert_eq!(bits.push_byte_data(b"0123456701234567"), Err(DataTooLong)); + let mut bits = Bits::new(Version::Micro(3)); + assert_eq!(bits.push_byte_data(b"0123456701234567"), Err(QrError::DataTooLong)); } } //}}} //------------------------------------------------------------------------------ -//{{{ Kanji mode +//{{{ Mode::Kanji mode impl Bits { /// Encodes Shift JIS double-byte data to the bits. #[unstable] pub fn push_kanji_data(&mut self, data: &[u8]) -> QrResult<()> { - try!(self.push_header(Kanji, data.len()/2)); + try!(self.push_header(Mode::Kanji, data.len()/2)); for kanji in data.chunks(2) { if kanji.len() != 2 { - return Err(InvalidCharacter); + return Err(QrError::InvalidCharacter); } let cp = (kanji[0] as u16) * 256 + (kanji[1] as u16); let bytes = if cp < 0xe040 { cp - 0x8140 } else { cp - 0xc140 }; @@ -524,11 +521,11 @@ impl Bits { #[cfg(test)] mod kanji_tests { use bits::Bits; - use types::{Version, MicroVersion, UnsupportedCharacterSet, DataTooLong}; + use types::{Version, QrError}; #[test] fn test_iso_18004_example() { - let mut bits = Bits::new(Version(1)); + let mut bits = Bits::new(Version::Normal(1)); assert_eq!(bits.push_kanji_data(b"\x93\x5f\xe4\xaa"), Ok(())); assert_eq!(bits.into_bytes(), vec![0b1000_0000, 0b0010_0110, @@ -539,15 +536,15 @@ mod kanji_tests { #[test] fn test_micro_qr_unsupported() { - let mut bits = Bits::new(MicroVersion(2)); - assert_eq!(bits.push_kanji_data(b"?"), Err(UnsupportedCharacterSet)); + let mut bits = Bits::new(Version::Micro(2)); + assert_eq!(bits.push_kanji_data(b"?"), Err(QrError::UnsupportedCharacterSet)); } #[test] fn test_data_too_long() { - let mut bits = Bits::new(MicroVersion(3)); + let mut bits = Bits::new(Version::Micro(3)); assert_eq!(bits.push_kanji_data(b"\x93_\x93_\x93_\x93_\x93_\x93_\x93_\x93_"), - Err(DataTooLong)); + Err(QrError::DataTooLong)); } } @@ -564,14 +561,14 @@ impl Bits { /// use qrcode::bits::Bits; /// use qrcode::types::Version; /// - /// let mut bits = Bits::new(Version(1)); + /// let mut bits = Bits::new(Version::Normal(1)); /// bits.push_fnc1_first_position(); /// bits.push_numeric_data(b"01049123451234591597033130128"); /// bits.push_alphanumeric_data(b"%10ABC123"); /// /// In QR code, the character `%` is used as the data field separator (0x1D). pub fn push_fnc1_first_position(&mut self) -> QrResult<()> { - self.push_mode_indicator(Fnc1First) + self.push_mode_indicator(ExtendedMode::Fnc1First) } /// Encodes an indicator that the following data are formatted in accordance @@ -583,7 +580,7 @@ impl Bits { /// use qrcode::bits::Bits; /// use qrcode::types::Version; /// - /// let mut bits = Bits::new(Version(1)); + /// let mut bits = Bits::new(Version::Normal(1)); /// bits.push_fnc1_second_position(37); /// bits.push_alphanumeric_data(b"AA1234BBB112"); /// bits.push_byte_data(b"text text text text\r"); @@ -595,7 +592,7 @@ impl Bits { /// bits.push_fnc1_second_position(b'A' + 100); /// ``` pub fn push_fnc1_second_position(&mut self, application_indicator: u8) -> QrResult<()> { - try!(self.push_mode_indicator(Fnc1Second)); + try!(self.push_mode_indicator(ExtendedMode::Fnc1Second)); self.push_number(8, application_indicator as u16); Ok(()) } @@ -659,16 +656,16 @@ static DATA_LENGTHS: [[uint, ..4], ..44] = [ impl Bits { /// Pushes the ending bits to indicate no more data. #[unstable] - pub fn push_terminator(&mut self, ec_level: ErrorCorrectionLevel) -> QrResult<()> { + pub fn push_terminator(&mut self, ec_level: EcLevel) -> QrResult<()> { let terminator_size = match self.version { - MicroVersion(a) => (a as uint) * 2 + 1, + Version::Micro(a) => (a as uint) * 2 + 1, _ => 4, }; let cur_length = self.len(); let data_length = try!(self.version.fetch(ec_level, &DATA_LENGTHS)); if cur_length > data_length { - return Err(DataTooLong); + return Err(QrError::DataTooLong); } let terminator_size = min(terminator_size, data_length - cur_length); @@ -695,13 +692,13 @@ impl Bits { #[cfg(test)] mod finish_tests { use bits::Bits; - use types::{Version, MicroVersion, L, Q, DataTooLong}; + use types::{Version, EcLevel, QrError}; #[test] fn test_hello_world() { - let mut bits = Bits::new(Version(1)); + let mut bits = Bits::new(Version::Normal(1)); assert_eq!(bits.push_alphanumeric_data(b"HELLO WORLD"), Ok(())); - assert_eq!(bits.push_terminator(Q), Ok(())); + assert_eq!(bits.push_terminator(EcLevel::Q), Ok(())); assert_eq!(bits.into_bytes(), vec![0b00100000, 0b01011011, 0b00001011, 0b01111000, 0b11010001, 0b01110010, 0b11011100, 0b01001101, 0b01000011, @@ -711,40 +708,40 @@ mod finish_tests { #[test] fn test_too_long() { - let mut bits = Bits::new(MicroVersion(1)); + let mut bits = Bits::new(Version::Micro(1)); assert_eq!(bits.push_numeric_data(b"9999999"), Ok(())); - assert_eq!(bits.push_terminator(L), Err(DataTooLong)); + assert_eq!(bits.push_terminator(EcLevel::L), Err(QrError::DataTooLong)); } #[test] fn test_no_terminator() { - let mut bits = Bits::new(MicroVersion(1)); + let mut bits = Bits::new(Version::Micro(1)); assert_eq!(bits.push_numeric_data(b"99999"), Ok(())); - assert_eq!(bits.push_terminator(L), Ok(())); + assert_eq!(bits.push_terminator(EcLevel::L), Ok(())); assert_eq!(bits.into_bytes(), vec![0b101_11111, 0b00111_110, 0b0011__0000]); } #[test] fn test_no_padding() { - let mut bits = Bits::new(MicroVersion(1)); + let mut bits = Bits::new(Version::Micro(1)); assert_eq!(bits.push_numeric_data(b"9999"), Ok(())); - assert_eq!(bits.push_terminator(L), Ok(())); + assert_eq!(bits.push_terminator(EcLevel::L), Ok(())); assert_eq!(bits.into_bytes(), vec![0b100_11111, 0b00111_100, 0b1_000__0000]); } #[test] fn test_micro_version_1_half_byte_padding() { - let mut bits = Bits::new(MicroVersion(1)); + let mut bits = Bits::new(Version::Micro(1)); assert_eq!(bits.push_numeric_data(b"999"), Ok(())); - assert_eq!(bits.push_terminator(L), Ok(())); + assert_eq!(bits.push_terminator(EcLevel::L), Ok(())); assert_eq!(bits.into_bytes(), vec![0b011_11111, 0b00111_000, 0b0000__0000]); } #[test] fn test_micro_version_1_full_byte_padding() { - let mut bits = Bits::new(MicroVersion(1)); + let mut bits = Bits::new(Version::Micro(1)); assert_eq!(bits.push_numeric_data(b""), Ok(())); - assert_eq!(bits.push_terminator(L), Ok(())); + assert_eq!(bits.push_terminator(EcLevel::L), Ok(())); assert_eq!(bits.into_bytes(), vec![0b000_000_00, 0b11101100, 0]); } } @@ -761,10 +758,10 @@ impl Bits { for segment in segments_iter { let slice = data[segment.begin..segment.end]; try!(match segment.mode { - Numeric => self.push_numeric_data(slice), - Alphanumeric => self.push_alphanumeric_data(slice), - Byte => self.push_byte_data(slice), - Kanji => self.push_kanji_data(slice), + 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(()) @@ -781,12 +778,9 @@ impl Bits { #[cfg(test)] mod encode_tests { use bits::Bits; - use types::{QrVersion, Version, MicroVersion, DataTooLong, QrResult, - L, Q, H, ErrorCorrectionLevel}; + use types::{Version, QrError, QrResult, EcLevel}; - fn encode(data: &[u8], - version: QrVersion, - ec_level: ErrorCorrectionLevel) -> QrResult> { + fn encode(data: &[u8], version: Version, ec_level: EcLevel) -> QrResult> { let mut bits = Bits::new(version); try!(bits.push_optimal_data(data)); try!(bits.push_terminator(ec_level)); @@ -795,7 +789,7 @@ mod encode_tests { #[test] fn test_alphanumeric() { - let res = encode(b"HELLO WORLD", Version(1), Q); + let res = encode(b"HELLO WORLD", Version::Normal(1), EcLevel::Q); assert_eq!(res, Ok(vec![0b00100000, 0b01011011, 0b00001011, 0b01111000, 0b11010001, 0b01110010, 0b11011100, 0b01001101, 0b01000011, @@ -805,15 +799,15 @@ mod encode_tests { #[test] fn test_auto_mode_switch() { - let res = encode(b"123A", MicroVersion(2), L); + let res = encode(b"123A", Version::Micro(2), EcLevel::L); assert_eq!(res, Ok(vec![0b0_0011_000, 0b1111011_1, 0b001_00101, 0b0_00000__00, 0b11101100])); } #[test] fn test_too_long() { - let res = encode(b">>>>>>>>", Version(1), H); - assert_eq!(res, Err(DataTooLong)); + let res = encode(b">>>>>>>>", Version::Normal(1), EcLevel::H); + assert_eq!(res, Err(QrError::DataTooLong)); } } @@ -825,9 +819,9 @@ mod encode_tests { /// the result. /// /// This method will not consider any Micro QR code versions. -pub fn encode_auto(data: &[u8], ec_level: ErrorCorrectionLevel) -> QrResult { +pub fn encode_auto(data: &[u8], ec_level: EcLevel) -> QrResult { let segments = Parser::new(data).collect::>(); - for version in [Version(9), Version(26), Version(40)].iter() { + for version in [Version::Normal(9), Version::Normal(26), Version::Normal(40)].iter() { let opt_segments = Optimizer::new(segments.iter().map(|s| *s), *version).collect::>(); let total_len = total_encoded_len(&*opt_segments, *version); let data_capacity = version.fetch(ec_level, &DATA_LENGTHS).unwrap(); @@ -840,13 +834,13 @@ pub fn encode_auto(data: &[u8], ec_level: ErrorCorrectionLevel) -> QrResult QrVersion { +fn find_min_version(length: uint, ec_level: EcLevel) -> Version { let mut min = 0u; let mut max = 39u; while min < max { @@ -857,42 +851,42 @@ fn find_min_version(length: uint, ec_level: ErrorCorrectionLevel) -> QrVersion { max = half; } } - Version((min + 1) as i16) + Version::Normal((min + 1) as i16) } #[cfg(test)] mod encode_auto_tests { use bits::{find_min_version, encode_auto}; - use types::{Version, L, Q, H}; + use types::{Version, EcLevel}; #[test] fn test_find_min_version() { - assert_eq!(find_min_version(60, L), Version(1)); - assert_eq!(find_min_version(200, L), Version(2)); - assert_eq!(find_min_version(200, H), Version(3)); - assert_eq!(find_min_version(20000, L), Version(37)); - assert_eq!(find_min_version(640, L), Version(4)); - assert_eq!(find_min_version(641, L), Version(5)); - assert_eq!(find_min_version(999999, H), Version(40)); + assert_eq!(find_min_version(60, EcLevel::L), Version::Normal(1)); + assert_eq!(find_min_version(200, EcLevel::L), Version::Normal(2)); + assert_eq!(find_min_version(200, EcLevel::H), Version::Normal(3)); + assert_eq!(find_min_version(20000, EcLevel::L), Version::Normal(37)); + assert_eq!(find_min_version(640, EcLevel::L), Version::Normal(4)); + assert_eq!(find_min_version(641, EcLevel::L), Version::Normal(5)); + assert_eq!(find_min_version(999999, EcLevel::H), Version::Normal(40)); } #[test] fn test_alpha_q() { - let bits = encode_auto(b"HELLO WORLD", Q).unwrap(); - assert_eq!(bits.version(), Version(1)); + let bits = encode_auto(b"HELLO WORLD", EcLevel::Q).unwrap(); + assert_eq!(bits.version(), Version::Normal(1)); } #[test] fn test_alpha_h() { - let bits = encode_auto(b"HELLO WORLD", H).unwrap(); - assert_eq!(bits.version(), Version(2)); + let bits = encode_auto(b"HELLO WORLD", EcLevel::H).unwrap(); + assert_eq!(bits.version(), Version::Normal(2)); } #[test] fn test_mixed() { - let bits = encode_auto(b"This is a mixed data test. 1234567890", H).unwrap(); - assert_eq!(bits.version(), Version(4)); + let bits = encode_auto(b"This is a mixed data test. 1234567890", EcLevel::H).unwrap(); + assert_eq!(bits.version(), Version::Normal(4)); } } diff --git a/src/canvas.rs b/src/canvas.rs index 2bb37b1..88c5ed6 100644 --- a/src/canvas.rs +++ b/src/canvas.rs @@ -1,12 +1,12 @@ //! The `canvas` module puts raw bits into the QR code canvas. //! -//! use qrcode::types::{Version, L}; -//! use qrcode::canvas::{Canvas, Checkerboard}; +//! use qrcode::types::{Version, EcLevel}; +//! use qrcode::canvas::{Canvas, MaskPattern}; //! -//! let mut c = Canvas::new(Version(1), L); +//! let mut c = Canvas::new(Version::Normal(1), EcLevel::L); //! c.draw_all_functional_patterns(); //! c.draw_data(b"data_here", b"ec_code_here"); -//! c.apply_mask(Checkerboard); +//! c.apply_mask(MaskPattern::Checkerboard); //! let bools = c.to_bools(); use std::iter::range_inclusive; @@ -14,7 +14,7 @@ use std::iter::order::equals; use std::num::Int; use std::cmp::max; -use types::{QrVersion, Version, MicroVersion, ErrorCorrectionLevel, L, M, Q}; +use types::{Version, EcLevel}; //------------------------------------------------------------------------------ //{{{ Modules @@ -46,27 +46,27 @@ impl Module { /// Checks whether a module is dark. pub fn is_dark(&self) -> bool { match *self { - Dark | DarkUnmasked => true, + Module::Dark | Module::DarkUnmasked => true, _ => false, } } /// Apply a mask to the unmasked modules. /// - /// use qrcode::canvas::{LightUnmasked, Light, DarkUnmasked, Dark}; + /// use qrcode::canvas::Module; /// - /// assert_eq!(LightUnmasked.mask(true), Dark); - /// assert_eq!(DarkUnmasked.mask(true), Light); - /// assert_eq!(LightUnmasked.mask(false), Light); - /// assert_eq!(Dark.mask(true), Dark); - /// assert_eq!(Dark.mask(false), Dark); + /// assert_eq!(Module::LightUnmasked.mask(true), Module::Dark); + /// assert_eq!(Module::DarkUnmasked.mask(true), Module::Light); + /// assert_eq!(Module::LightUnmasked.mask(false), Module::Light); + /// assert_eq!(Module::Dark.mask(true), Module::Dark); + /// assert_eq!(Module::Dark.mask(false), Module::Dark); /// pub fn mask(&self, should_invert: bool) -> Module { match (*self, should_invert) { - (Empty, true) | (LightUnmasked, true) => Dark, - (Empty, false) | (LightUnmasked, false) => Light, - (DarkUnmasked, true) => Light, - (DarkUnmasked, false) => Dark, + (Module::Empty, true) | (Module::LightUnmasked, true) => Module::Dark, + (Module::Empty, false) | (Module::LightUnmasked, false) => Module::Light, + (Module::DarkUnmasked, true) => Module::Light, + (Module::DarkUnmasked, false) => Module::Dark, (a, _) => a, } } @@ -84,10 +84,10 @@ pub struct Canvas { width: i16, /// The version of the QR code. - version: QrVersion, + version: Version, /// The error correction level of the QR code. - ec_level: ErrorCorrectionLevel, + ec_level: EcLevel, /// The modules of the QR code. Modules are arranged in left-to-right, then /// top-to-bottom order. @@ -96,13 +96,13 @@ pub struct Canvas { impl Canvas { /// Constructs a new canvas big enough for a QR code of the given version. - pub fn new(version: QrVersion, ec_level: ErrorCorrectionLevel) -> Canvas { + pub fn new(version: Version, ec_level: EcLevel) -> Canvas { let width = version.width(); Canvas { width: width, version: version, ec_level: ec_level, - modules: Vec::from_elem((width*width) as uint, Empty), + modules: Vec::from_elem((width*width) as uint, Module::Empty), } } @@ -115,11 +115,11 @@ impl Canvas { res.push('\n'); for x in range(0, width) { res.push(match self.get(x, y) { - Empty => '?', - Light => '.', - Dark => '#', - LightUnmasked => '-', - DarkUnmasked => '*', + Module::Empty => '?', + Module::Light => '.', + Module::Dark => '#', + Module::LightUnmasked => '-', + Module::DarkUnmasked => '*', }); } } @@ -155,36 +155,36 @@ impl Canvas { #[cfg(test)] mod basic_canvas_tests { - use canvas::{Canvas, Empty, Dark, Light, DarkUnmasked, LightUnmasked}; - use types::{Version, L}; + use canvas::{Canvas, Module}; + use types::{Version, EcLevel}; #[test] fn test_index() { - let mut c = Canvas::new(Version(1), L); + let mut c = Canvas::new(Version::Normal(1), EcLevel::L); - assert_eq!(c.get(0, 4), Empty); - assert_eq!(c.get(-1, -7), Empty); - assert_eq!(c.get(21-1, 21-7), Empty); + assert_eq!(c.get(0, 4), Module::Empty); + assert_eq!(c.get(-1, -7), Module::Empty); + assert_eq!(c.get(21-1, 21-7), Module::Empty); - c.put(0, 0, Dark); - c.put(-1, -7, Light); - assert_eq!(c.get(0, 0), Dark); - assert_eq!(c.get(21-1, -7), Light); - assert_eq!(c.get(-1, 21-7), Light); + c.put(0, 0, Module::Dark); + c.put(-1, -7, Module::Light); + assert_eq!(c.get(0, 0), Module::Dark); + assert_eq!(c.get(21-1, -7), Module::Light); + assert_eq!(c.get(-1, 21-7), Module::Light); } #[test] fn test_debug_str() { - let mut c = Canvas::new(Version(1), L); + let mut c = Canvas::new(Version::Normal(1), EcLevel::L); for i in range(3i16, 20) { for j in range(3i16, 20) { c.put(i, j, match ((i * 3) ^ j) % 5 { - 0 => Empty, - 1 => Light, - 2 => Dark, - 3 => LightUnmasked, - 4 => DarkUnmasked, + 0 => Module::Empty, + 1 => Module::Light, + 2 => Module::Dark, + 3 => Module::LightUnmasked, + 4 => Module::DarkUnmasked, _ => panic!(), }); } @@ -227,10 +227,10 @@ impl Canvas { for j in range_inclusive(dy_top, dy_bottom) { for i in range_inclusive(dx_left, dx_right) { self.put(x+i, y+j, match (i, j) { - (4, _) | (_, 4) | (-4, _) | (_, -4) => Light, - (3, _) | (_, 3) | (-3, _) | (_, -3) => Dark, - (2, _) | (_, 2) | (-2, _) | (_, -2) => Light, - _ => Dark, + (4, _) | (_, 4) | (-4, _) | (_, -4) => Module::Light, + (3, _) | (_, 3) | (-3, _) | (_, -3) => Module::Dark, + (2, _) | (_, 2) | (-2, _) | (_, -2) => Module::Light, + _ => Module::Dark, }); } } @@ -245,8 +245,8 @@ impl Canvas { self.draw_finder_pattern_at(3, 3); match self.version { - MicroVersion(_) => { return; } - Version(_) => { + Version::Micro(_) => { return; } + Version::Normal(_) => { self.draw_finder_pattern_at(-4, 3); self.draw_finder_pattern_at(3, -4); } @@ -257,11 +257,11 @@ impl Canvas { #[cfg(test)] mod finder_pattern_tests { use canvas::Canvas; - use types::{Version, MicroVersion, L}; + use types::{Version, EcLevel}; #[test] fn test_qr() { - let mut c = Canvas::new(Version(1), L); + let mut c = Canvas::new(Version::Normal(1), EcLevel::L); c.draw_finder_patterns(); assert_eq!(&*c.to_debug_str(), "\n\ #######.?????.#######\n\ @@ -289,7 +289,7 @@ mod finder_pattern_tests { #[test] fn test_micro_qr() { - let mut c = Canvas::new(MicroVersion(1), L); + let mut c = Canvas::new(Version::Micro(1), EcLevel::L); c.draw_finder_patterns(); assert_eq!(&*c.to_debug_str(), "\n\ #######.???\n\ @@ -313,14 +313,14 @@ mod finder_pattern_tests { impl Canvas { /// Draws a alignment pattern with the center at (x, y). fn draw_alignment_pattern_at(&mut self, x: i16, y: i16) { - if self.get(x, y) != Empty { + if self.get(x, y) != Module::Empty { return; } for j in range_inclusive(-2, 2) { for i in range_inclusive(-2, 2) { self.put(x+i, y+j, match (i, j) { - (2, _) | (_, 2) | (-2, _) | (_, -2) | (0, 0) => Dark, - _ => Light, + (2, _) | (_, 2) | (-2, _) | (_, -2) | (0, 0) => Module::Dark, + _ => Module::Light, }); } } @@ -332,9 +332,9 @@ impl Canvas { /// to help the scanner create the square grid. fn draw_alignment_patterns(&mut self) { match self.version { - MicroVersion(_) | Version(1) => { return; } - Version(2...6) => self.draw_alignment_pattern_at(-7, -7), - Version(a) => { + Version::Micro(_) | Version::Normal(1) => { return; } + Version::Normal(2...6) => self.draw_alignment_pattern_at(-7, -7), + Version::Normal(a) => { let positions = ALIGNMENT_PATTERN_POSITIONS[a as uint - 7]; for x in positions.iter() { for y in positions.iter() { @@ -349,11 +349,11 @@ impl Canvas { #[cfg(test)] mod alignment_pattern_tests { use canvas::Canvas; - use types::{Version, L}; + use types::{Version, EcLevel}; #[test] fn test_draw_alignment_patterns_1() { - let mut c = Canvas::new(Version(1), L); + let mut c = Canvas::new(Version::Normal(1), EcLevel::L); c.draw_finder_patterns(); c.draw_alignment_patterns(); assert_eq!(&*c.to_debug_str(), "\n\ @@ -382,7 +382,7 @@ mod alignment_pattern_tests { #[test] fn test_draw_alignment_patterns_3() { - let mut c = Canvas::new(Version(3), L); + let mut c = Canvas::new(Version::Normal(3), EcLevel::L); c.draw_finder_patterns(); c.draw_alignment_patterns(); assert_eq!(&*c.to_debug_str(), "\n\ @@ -419,7 +419,7 @@ mod alignment_pattern_tests { #[test] fn test_draw_alignment_patterns_7() { - let mut c = Canvas::new(Version(7), L); + let mut c = Canvas::new(Version::Normal(7), EcLevel::L); c.draw_finder_patterns(); c.draw_alignment_patterns(); assert_eq!(&*c.to_debug_str(), "\n\ @@ -550,22 +550,22 @@ impl Canvas { fn draw_timing_patterns(&mut self) { let width = self.width; let (y, x1, x2) = match self.version { - MicroVersion(_) => (0, 8, width-1), - Version(_) => (6, 8, width-9), + Version::Micro(_) => (0, 8, width-1), + Version::Normal(_) => (6, 8, width-9), }; - self.draw_line(x1, y, x2, y, Dark, Light); - self.draw_line(y, x1, y, x2, Dark, Light); + self.draw_line(x1, y, x2, y, Module::Dark, Module::Light); + self.draw_line(y, x1, y, x2, Module::Dark, Module::Light); } } #[cfg(test)] mod timing_pattern_tests { use canvas::Canvas; - use types::{Version, MicroVersion, L}; + use types::{Version, EcLevel}; #[test] fn test_draw_timing_patterns_qr() { - let mut c = Canvas::new(Version(1), L); + let mut c = Canvas::new(Version::Normal(1), EcLevel::L); c.draw_timing_patterns(); assert_eq!(&*c.to_debug_str(), "\n\ ?????????????????????\n\ @@ -593,7 +593,7 @@ mod timing_pattern_tests { #[test] fn test_draw_timing_patterns_micro_qr() { - let mut c = Canvas::new(MicroVersion(1), L); + let mut c = Canvas::new(Version::Micro(1), EcLevel::L); c.draw_timing_patterns(); assert_eq!(&*c.to_debug_str(), "\n\ ????????#.#\n\ @@ -636,13 +636,16 @@ impl Canvas { /// Draws the format info patterns for an encoded number. fn draw_format_info_patterns_with_number(&mut self, format_info: u16) { match self.version { - MicroVersion(_) => { - self.draw_number(format_info, Dark, Light, FORMAT_INFO_COORDS_MICRO_QR); + Version::Micro(_) => { + self.draw_number(format_info, Module::Dark, Module::Light, + &FORMAT_INFO_COORDS_MICRO_QR); } - Version(_) => { - self.draw_number(format_info, Dark, Light, FORMAT_INFO_COORDS_QR_MAIN); - self.draw_number(format_info, Dark, Light, FORMAT_INFO_COORDS_QR_SIDE); - self.put(8, -8, Dark); // Dark module. + Version::Normal(_) => { + self.draw_number(format_info, Module::Dark, Module::Light, + &FORMAT_INFO_COORDS_QR_MAIN); + self.draw_number(format_info, Module::Dark, Module::Light, + &FORMAT_INFO_COORDS_QR_SIDE); + self.put(8, -8, Module::Dark); // Dark module. } } } @@ -655,11 +658,13 @@ impl Canvas { /// Draws the version information patterns. fn draw_version_info_patterns(&mut self) { match self.version { - MicroVersion(_) | Version(1...6) => { return; } - Version(a) => { + Version::Micro(_) | Version::Normal(1...6) => { return; } + Version::Normal(a) => { let version_info = VERSION_INFOS[(a - 7) as uint] << 14; - self.draw_number(version_info, Dark, Light, VERSION_INFO_COORDS_BL); - self.draw_number(version_info, Dark, Light, VERSION_INFO_COORDS_TR); + self.draw_number(version_info, Module::Dark, Module::Light, + &VERSION_INFO_COORDS_BL); + self.draw_number(version_info, Module::Dark, Module::Light, + &VERSION_INFO_COORDS_TR); } } } @@ -667,13 +672,14 @@ impl Canvas { #[cfg(test)] mod draw_version_info_tests { - use canvas::{Canvas, Light, Dark}; - use types::{MicroVersion, Version, L}; + use canvas::{Canvas, Module}; + use types::{Version, EcLevel}; #[test] fn test_draw_number() { - let mut c = Canvas::new(MicroVersion(1), L); - c.draw_number(0b10101101u8, Dark, Light, [(0,0), (0,-1), (-2,-2), (-2,0)]); + let mut c = Canvas::new(Version::Micro(1), EcLevel::L); + c.draw_number(0b10101101u8, Module::Dark, Module::Light, + &[(0,0), (0,-1), (-2,-2), (-2,0)]); assert_eq!(&*c.to_debug_str(), "\n\ #????????.?\n\ ???????????\n\ @@ -690,7 +696,7 @@ mod draw_version_info_tests { #[test] fn test_draw_version_info_1() { - let mut c = Canvas::new(Version(1), L); + let mut c = Canvas::new(Version::Normal(1), EcLevel::L); c.draw_version_info_patterns(); assert_eq!(&*c.to_debug_str(), "\n\ ?????????????????????\n\ @@ -718,7 +724,7 @@ mod draw_version_info_tests { #[test] fn test_draw_version_info_7() { - let mut c = Canvas::new(Version(7), L); + let mut c = Canvas::new(Version::Normal(7), EcLevel::L); c.draw_version_info_patterns(); assert_eq!(&*c.to_debug_str(), "\n\ @@ -771,7 +777,7 @@ mod draw_version_info_tests { #[test] fn test_draw_reserved_format_info_patterns_qr() { - let mut c = Canvas::new(Version(1), L); + let mut c = Canvas::new(Version::Normal(1), EcLevel::L); c.draw_reserved_format_info_patterns(); assert_eq!(&*c.to_debug_str(), "\n\ ????????.????????????\n\ @@ -799,7 +805,7 @@ mod draw_version_info_tests { #[test] fn test_draw_reserved_format_info_patterns_micro_qr() { - let mut c = Canvas::new(MicroVersion(1), L); + let mut c = Canvas::new(Version::Micro(1), EcLevel::L); c.draw_reserved_format_info_patterns(); assert_eq!(&*c.to_debug_str(), "\n\ ???????????\n\ @@ -881,11 +887,11 @@ impl Canvas { #[cfg(test)] mod all_functional_patterns_tests { use canvas::Canvas; - use types::{Version, MicroVersion, L}; + use types::{Version, EcLevel}; #[test] fn test_all_functional_patterns_qr() { - let mut c = Canvas::new(Version(2), L); + let mut c = Canvas::new(Version::Normal(2), EcLevel::L); c.draw_all_functional_patterns(); assert_eq!(&*c.to_debug_str(), "\n\ #######..????????.#######\n\ @@ -917,7 +923,7 @@ mod all_functional_patterns_tests { #[test] fn test_all_functional_patterns_micro_qr() { - let mut c = Canvas::new(MicroVersion(1), L); + let mut c = Canvas::new(Version::Micro(1), EcLevel::L); c.draw_all_functional_patterns(); assert_eq!(&*c.to_debug_str(), "\n\ #######.#.#\n\ @@ -946,15 +952,15 @@ struct DataModuleIter { } impl DataModuleIter { - fn new(version: QrVersion) -> DataModuleIter { + fn new(version: Version) -> DataModuleIter { let width = version.width(); DataModuleIter { x: width - 1, y: width - 1, width: width, timing_pattern_column: match version { - MicroVersion(_) => 0, - Version(_) => 6, + Version::Micro(_) => 0, + Version::Normal(_) => 6, } } } @@ -998,11 +1004,11 @@ impl Iterator<(i16, i16)> for DataModuleIter { #[cfg(test)] mod data_iter_tests { use canvas::DataModuleIter; - use types::{Version, MicroVersion}; + use types::Version; #[test] fn test_qr() { - let res = DataModuleIter::new(Version(1)).collect::>(); + let res = DataModuleIter::new(Version::Normal(1)).collect::>(); assert_eq!(res, vec![ (20, 20), (19, 20), (20, 19), (19, 19), (20, 18), (19, 18), (20, 17), (19, 17), (20, 16), (19, 16), (20, 15), (19, 15), @@ -1088,7 +1094,7 @@ mod data_iter_tests { #[test] fn test_micro_qr() { - let res = DataModuleIter::new(MicroVersion(1)).collect::>(); + let res = DataModuleIter::new(Version::Micro(1)).collect::>(); assert_eq!(res, vec![ (10, 10), (9, 10), (10, 9), (9, 9), (10, 8), (9, 8), (10, 7), (9, 7), (10, 6), (9, 6), (10, 5), (9, 5), @@ -1119,7 +1125,7 @@ mod data_iter_tests { #[test] fn test_micro_qr_2() { - let res = DataModuleIter::new(MicroVersion(2)).collect::>(); + let res = DataModuleIter::new(Version::Micro(2)).collect::>(); assert_eq!(res, vec![ (12, 12), (11, 12), (12, 11), (11, 11), (12, 10), (11, 10), (12, 9), (11, 9), (12, 8), (11, 8), (12, 7), (11, 7), @@ -1177,10 +1183,14 @@ impl Canvas { let bits_end = if i == last_word { 4 } else { 0 }; 'outside: for j in range_inclusive(bits_end, 7u).rev() { - let color = if (*b & (1 << j)) != 0 { DarkUnmasked } else { LightUnmasked }; + let color = if (*b & (1 << j)) != 0 { + Module::DarkUnmasked + } else { + Module::LightUnmasked + }; while let Some((x, y)) = coords.next() { let r = self.get_mut(x, y); - if *r == Empty { + if *r == Module::Empty { *r = color; continue 'outside; } @@ -1193,7 +1203,7 @@ impl Canvas { /// Draws the encoded data and error correction codes to the empty modules. pub fn draw_data(&mut self, data: &[u8], ec: &[u8]) { let is_half_codeword_at_end = match (self.version, self.ec_level) { - (MicroVersion(1), L) | (MicroVersion(3), M) => true, + (Version::Micro(1), EcLevel::L) | (Version::Micro(3), EcLevel::M) => true, _ => false, }; @@ -1206,11 +1216,11 @@ impl Canvas { #[cfg(test)] mod draw_codewords_test { use canvas::Canvas; - use types::{Version, MicroVersion, L}; + use types::{Version, EcLevel}; #[test] fn test_micro_qr_1() { - let mut c = Canvas::new(MicroVersion(1), L); + let mut c = Canvas::new(Version::Micro(1), EcLevel::L); c.draw_all_functional_patterns(); c.draw_data(b"\x6e\x5d\xe2", b"\x2b\x63"); assert_eq!(&*c.to_debug_str(), "\n\ @@ -1229,7 +1239,7 @@ mod draw_codewords_test { #[test] fn test_qr_2() { - let mut c = Canvas::new(Version(2), L); + let mut c = Canvas::new(Version::Normal(2), EcLevel::L); c.draw_all_functional_patterns(); c.draw_data(b"\x92I$\x92I$\x92I$\x92I$\x92I$\x92I$\x92I$\x92I$\x92I$\x92I$\x92I$\x92I$\x92I$\x92I$\x92I$", b""); assert_eq!(&*c.to_debug_str(), "\n\ @@ -1306,14 +1316,14 @@ mod mask_functions { fn get_mask_function(pattern: MaskPattern) -> fn(i16, i16) -> bool { match pattern { - Checkerboard => mask_functions::checkerboard, - HorizontalLines => mask_functions::horizontal_lines, - VerticalLines => mask_functions::vertical_lines, - DiagonalLines => mask_functions::diagonal_lines, - LargeCheckerboard => mask_functions::large_checkerboard, - Fields => mask_functions::fields, - Diamonds => mask_functions::diamonds, - Meadow => mask_functions::meadow, + MaskPattern::Checkerboard => mask_functions::checkerboard, + MaskPattern::HorizontalLines => mask_functions::horizontal_lines, + MaskPattern::VerticalLines => mask_functions::vertical_lines, + MaskPattern::DiagonalLines => mask_functions::diagonal_lines, + MaskPattern::LargeCheckerboard => mask_functions::large_checkerboard, + MaskPattern::Fields => mask_functions::fields, + MaskPattern::Diamonds => mask_functions::diamonds, + MaskPattern::Meadow => mask_functions::meadow, } } @@ -1339,27 +1349,27 @@ impl Canvas { /// current QR code version, this method will fail. fn draw_format_info_patterns(&mut self, pattern: MaskPattern) { let format_number = match self.version { - Version(_) => { + Version::Normal(_) => { let simple_format_number = ((self.ec_level as uint) ^ 1) << 3 | (pattern as uint); FORMAT_INFOS_QR[simple_format_number] } - MicroVersion(a) => { + Version::Micro(a) => { let micro_pattern_number = match pattern { - HorizontalLines => 0b00, - LargeCheckerboard => 0b01, - Diamonds => 0b10, - Meadow => 0b11, + MaskPattern::HorizontalLines => 0b00, + MaskPattern::LargeCheckerboard => 0b01, + MaskPattern::Diamonds => 0b10, + MaskPattern::Meadow => 0b11, _ => panic!("Unsupported mask pattern in Micro QR code"), }; let symbol_number = match (a, self.ec_level) { - (1, L) => 0b000, - (2, L) => 0b001, - (2, M) => 0b010, - (3, L) => 0b011, - (3, M) => 0b100, - (4, L) => 0b101, - (4, M) => 0b110, - (4, Q) => 0b111, + (1, EcLevel::L) => 0b000, + (2, EcLevel::L) => 0b001, + (2, EcLevel::M) => 0b010, + (3, EcLevel::L) => 0b011, + (3, EcLevel::M) => 0b100, + (4, EcLevel::L) => 0b101, + (4, EcLevel::M) => 0b110, + (4, EcLevel::Q) => 0b111, _ => panic!("Unsupported version/ec_level combination in Micro QR code"), }; let simple_format_number = symbol_number << 2 | micro_pattern_number; @@ -1372,14 +1382,14 @@ impl Canvas { #[cfg(test)] mod mask_tests { - use canvas::{Canvas, Checkerboard, LargeCheckerboard}; - use types::{Version, MicroVersion, L}; + use canvas::{Canvas, MaskPattern}; + use types::{Version, EcLevel}; #[test] fn test_apply_mask_qr() { - let mut c = Canvas::new(Version(1), L); + let mut c = Canvas::new(Version::Normal(1), EcLevel::L); c.draw_all_functional_patterns(); - c.apply_mask(Checkerboard); + c.apply_mask(MaskPattern::Checkerboard); assert_eq!(&*c.to_debug_str(), "\n\ #######...#.#.#######\n\ @@ -1407,8 +1417,8 @@ mod mask_tests { #[test] fn test_draw_format_info_patterns_qr() { - let mut c = Canvas::new(Version(1), L); - c.draw_format_info_patterns(LargeCheckerboard); + let mut c = Canvas::new(Version::Normal(1), EcLevel::L); + c.draw_format_info_patterns(MaskPattern::LargeCheckerboard); assert_eq!(&*c.to_debug_str(), "\n\ ????????#????????????\n\ ????????#????????????\n\ @@ -1435,8 +1445,8 @@ mod mask_tests { #[test] fn test_draw_format_info_patterns_micro_qr() { - let mut c = Canvas::new(MicroVersion(2), L); - c.draw_format_info_patterns(LargeCheckerboard); + let mut c = Canvas::new(Version::Micro(2), EcLevel::L); + c.draw_format_info_patterns(MaskPattern::LargeCheckerboard); assert_eq!(&*c.to_debug_str(), "\n\ ?????????????\n\ ????????#????\n\ @@ -1488,9 +1498,9 @@ impl Canvas { |j| self.get(i, j) }; - let mut colors = range(0, self.width).map(map_fn).chain(Some(Empty).into_iter()); - - let mut last_color = Empty; + let mut colors = range(0, self.width).map(map_fn) + .chain(Some(Module::Empty).into_iter()); + let mut last_color = Module::Empty; let mut consecutive_len = 1u16; for color in colors { @@ -1538,7 +1548,10 @@ impl Canvas { /// Every pattern that looks like `#.###.#....` in any orientation will add /// 40 points. fn compute_finder_penalty_score(&self, is_horizontal: bool) -> u16 { - static PATTERN: [Module, ..7] = [Dark, Light, Dark, Dark, Dark, Light, Dark]; + static PATTERN: [Module, ..7] = [ + Module::Dark, Module::Light, Module::Dark, Module::Dark, + Module::Dark, Module::Light, Module::Dark, + ]; let mut total_score = 0; @@ -1602,7 +1615,7 @@ impl Canvas { fn compute_total_penalty_scores(&self) -> u16 { match self.version { - Version(_) => { + Version::Normal(_) => { let s1a = self.compute_adjacent_penalty_score(true); let s1b = self.compute_adjacent_penalty_score(false); let s2 = self.compute_block_penalty_score(); @@ -1611,22 +1624,22 @@ impl Canvas { let s4 = self.compute_balance_penalty_score(); s1a + s1b + s2 + s3a + s3b + s4 } - MicroVersion(_) => self.compute_light_side_penalty_score(), + Version::Micro(_) => self.compute_light_side_penalty_score(), } } } #[cfg(test)] mod penalty_tests { - use canvas::{Canvas, Checkerboard, Module, Light, Dark}; - use types::{Version, MicroVersion, Q}; + use canvas::{Canvas, MaskPattern, Module}; + use types::{Version, EcLevel}; fn create_test_canvas() -> Canvas { - let mut c = Canvas::new(Version(1), Q); + let mut c = Canvas::new(Version::Normal(1), EcLevel::Q); c.draw_all_functional_patterns(); c.draw_data(b"\x20\x5b\x0b\x78\xd1\x72\xdc\x4d\x43\x40\xec\x11\x00", b"\xa8\x48\x16\x52\xd9\x36\x9c\x00\x2e\x0f\xb4\x7a\x10"); - c.apply_mask(Checkerboard); + c.apply_mask(MaskPattern::Checkerboard); c } @@ -1686,15 +1699,21 @@ mod penalty_tests { #[test] fn test_penalty_score_light_sides() { static HORIZONTAL_SIDE: [Module, ..17] = [ - Dark, Light, Light, Dark, Dark, Dark, Light, Light, - Dark, Light, Dark, Light, Light, Dark, Light, Light, Light + Module::Dark, Module::Light, Module::Light, Module::Dark, + Module::Dark, Module::Dark, Module::Light, Module::Light, + Module::Dark, Module::Light, Module::Dark, Module::Light, + Module::Light, Module::Dark, Module::Light, Module::Light, + Module::Light, ]; static VERTICAL_SIDE: [Module, ..17] = [ - Dark, Dark, Dark, Light, Light, Dark, Dark, Light, - Dark, Light, Dark, Light, Dark, Light, Light, Dark, Light + Module::Dark, Module::Dark, Module::Dark, Module::Light, + Module::Light, Module::Dark, Module::Dark, Module::Light, + Module::Dark, Module::Light, Module::Dark, Module::Light, + Module::Dark, Module::Light, Module::Light, Module::Dark, + Module::Light, ]; - let mut c = Canvas::new(MicroVersion(4), Q); + let mut c = Canvas::new(Version::Micro(4), EcLevel::Q); for i in range(0, 17) { c.put(i, -1, HORIZONTAL_SIDE[i as uint]); c.put(-1, i, VERTICAL_SIDE[i as uint]); @@ -1709,12 +1728,15 @@ mod penalty_tests { //{{{ Select mask with lowest penalty score static ALL_PATTERNS_QR: [MaskPattern, ..8] = [ - Checkerboard, HorizontalLines, VerticalLines, DiagonalLines, - LargeCheckerboard, Fields, Diamonds, Meadow + MaskPattern::Checkerboard, MaskPattern::HorizontalLines, + MaskPattern::VerticalLines, MaskPattern::DiagonalLines, + MaskPattern::LargeCheckerboard, MaskPattern::Fields, + MaskPattern::Diamonds, MaskPattern::Meadow, ]; static ALL_PATTERNS_MICRO_QR: [MaskPattern, ..4] = [ - HorizontalLines, LargeCheckerboard, Diamonds, Meadow + MaskPattern::HorizontalLines, MaskPattern::LargeCheckerboard, + MaskPattern::Diamonds, MaskPattern::Meadow, ]; impl Canvas { @@ -1722,8 +1744,8 @@ impl Canvas { /// penalty score. pub fn apply_best_mask(&self) -> Canvas { let patterns = match self.version { - Version(_) => ALL_PATTERNS_QR.iter(), - MicroVersion(_) => ALL_PATTERNS_MICRO_QR.iter(), + Version::Normal(_) => ALL_PATTERNS_QR.iter(), + Version::Micro(_) => ALL_PATTERNS_MICRO_QR.iter(), }; patterns.map(|ptn| { diff --git a/src/ec.rs b/src/ec.rs index 47ca653..e73707c 100644 --- a/src/ec.rs +++ b/src/ec.rs @@ -1,6 +1,6 @@ //! The `ec` module applies the Reed-Solomon error correction codes. -use types::{QrResult, QrVersion, ErrorCorrectionLevel}; +use types::{QrResult, Version, EcLevel}; //------------------------------------------------------------------------------ //{{{ Error correction primitive @@ -96,8 +96,8 @@ fn test_interleave() { /// Constructs data and error correction codewords ready to be put in the QR /// code matrix. pub fn construct_codewords(rawbits: &[u8], - version: QrVersion, - ec_level: ErrorCorrectionLevel) -> QrResult<(Vec, Vec)> { + version: Version, + ec_level: EcLevel) -> QrResult<(Vec, Vec)> { let (block_1_size, block_1_count, block_2_size, block_2_count) = try!(version.fetch(ec_level, &DATA_BYTES_PER_BLOCK)); @@ -129,12 +129,12 @@ pub fn construct_codewords(rawbits: &[u8], #[cfg(test)] mod construct_codewords_test { use ec::construct_codewords; - use types::{Version, M, Q}; + use types::{Version, EcLevel}; #[test] fn test_add_ec_simple() { let msg = b" [\x0bx\xd1r\xdcMC@\xec\x11\xec\x11\xec\x11"; - let (blocks_vec, ec_vec) = construct_codewords(msg, Version(1), M).unwrap(); + let (blocks_vec, ec_vec) = construct_codewords(msg, Version::Normal(1), EcLevel::M).unwrap(); assert_eq!(&*blocks_vec, msg); assert_eq!(&*ec_vec, b"\xc4#'w\xeb\xd7\xe7\xe2]\x17"); } @@ -142,7 +142,7 @@ mod construct_codewords_test { #[test] fn test_add_ec_complex() { let msg = b"CUF\x86W&U\xc2w2\x06\x12\x06g&\xf6\xf6B\x07v\x86\xf2\x07&V\x16\xc6\xc7\x92\x06\xb6\xe6\xf7w2\x07v\x86W&R\x06\x86\x972\x07F\xf7vV\xc2\x06\x972\x10\xec\x11\xec\x11\xec\x11\xec"; - let (blocks_vec, ec_vec) = construct_codewords(msg, Version(5), Q).unwrap(); + let (blocks_vec, ec_vec) = construct_codewords(msg, Version::Normal(5), EcLevel::Q).unwrap(); assert_eq!(&*blocks_vec, b"C\xf6\xb6FU\xf6\xe6\xf7FB\xf7v\x86\x07wVWv2\xc2&\x86\x07\x06U\xf2v\x97\xc2\x07\x862w&W\x102V&\xec\x06\x16R\x11\x12\xc6\x06\xec\x06\xc7\x86\x11g\x92\x97\xec&\x062\x11\x07\xec"); assert_eq!(&*ec_vec, diff --git a/src/lib.rs b/src/lib.rs index 4a7e9b7..4b943da 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,8 +24,7 @@ extern crate test; -pub use types::{QrResult, ErrorCorrectionLevel, L, M, Q, H, - QrVersion, Version, MicroVersion}; +pub use types::{QrResult, EcLevel, Version}; pub mod types; pub mod bits; @@ -37,8 +36,8 @@ pub mod canvas; #[deriving(Clone)] pub struct QrCode { content: Vec, - version: QrVersion, - ec_level: ErrorCorrectionLevel, + version: Version, + ec_level: EcLevel, width: uint, } @@ -53,7 +52,7 @@ impl QrCode { /// let code = QrCode::new(b"Some data").unwrap(); /// pub fn new(data: &[u8]) -> QrResult { - QrCode::with_error_correction_level(data, M) + QrCode::with_error_correction_level(data, EcLevel::M) } /// Constructs a new QR code which automatically encodes the given data at a @@ -61,11 +60,11 @@ impl QrCode { /// /// This method automatically chooses the smallest QR code. /// - /// use qrcode::{QrCode, H}; + /// use qrcode::{QrCode, EcLevel}; /// - /// let code = QrCode::with_error_correction_level(b"Some data", H).unwrap(); + /// let code = QrCode::with_error_correction_level(b"Some data", EcLevel::H).unwrap(); /// - pub fn with_error_correction_level(data: &[u8], ec_level: ErrorCorrectionLevel) -> QrResult { + pub fn with_error_correction_level(data: &[u8], ec_level: EcLevel) -> QrResult { let bits = try!(bits::encode_auto(data, ec_level)); QrCode::with_bits(bits, ec_level) } @@ -73,19 +72,17 @@ impl QrCode { /// Constructs a new QR code for the given version and error correction /// level. /// - /// use qrcode::{QrCode, Version, M}; + /// use qrcode::{QrCode, Version, EcLevel}; /// - /// let code = QrCode::with_version(b"Some data", Version(5), M).unwrap(); + /// let code = QrCode::with_version(b"Some data", Version::Normal(5), EcLevel::M).unwrap(); /// /// This method can also be used to generate Micro QR code. /// - /// use qrcode::{QrCode, MicroVersion, L}; + /// use qrcode::{QrCode, Version, EcLevel}; /// - /// let micro_code = QrCode::with_version(b"123", MicroVersion(1), L).unwrap(); + /// let micro_code = QrCode::with_version(b"123", Version::Micro(1), EcLevel::L).unwrap(); /// - pub fn with_version(data: &[u8], - version: QrVersion, - ec_level: ErrorCorrectionLevel) -> QrResult { + pub fn with_version(data: &[u8], version: Version, ec_level: EcLevel) -> QrResult { let mut bits = bits::Bits::new(version); try!(bits.push_optimal_data(data)); try!(bits.push_terminator(ec_level)); @@ -103,25 +100,24 @@ impl QrCode { /// /// See the `Bits` structure for detail. /// - /// #![allow(unused_must_use)]; + /// #![allow(unused_must_use)] /// - /// use qrcode::{QrCode, Version, L}; + /// use qrcode::{QrCode, Version, EcLevel}; /// use qrcode::bits::Bits; /// - /// let mut bits = Bits::new(Version(1)); + /// let mut bits = Bits::new(Version::Normal(1)); /// bits.push_eci_designator(9); /// bits.push_byte_data(b"\xca\xfe\xe4\xe9\xea\xe1\xf2 QR"); - /// bits.push_terminator(L); - /// let qrcode = QrCode::with_bits(bits, L); + /// bits.push_terminator(EcLevel::L); + /// let qrcode = QrCode::with_bits(bits, EcLevel::L); /// - pub fn with_bits(bits: bits::Bits, - ec_level: ErrorCorrectionLevel) -> QrResult { + pub fn with_bits(bits: bits::Bits, ec_level: EcLevel) -> QrResult { let version = bits.version(); let data = bits.into_bytes(); let (encoded_data, ec_data) = try!(ec::construct_codewords(data[], version, ec_level)); let mut canvas = canvas::Canvas::new(version, ec_level); canvas.draw_all_functional_patterns(); - canvas.draw_data(encoded_data[], ec_data[]); + canvas.draw_data(&*encoded_data, &*ec_data); let canvas = canvas.apply_best_mask(); Ok(QrCode { content: canvas.to_bools(), @@ -132,12 +128,12 @@ impl QrCode { } /// Gets the version of this QR code. - pub fn version(&self) -> QrVersion { + pub fn version(&self) -> Version { self.version } /// Gets the error correction level of this QR code. - pub fn error_correction_level(&self) -> ErrorCorrectionLevel { + pub fn error_correction_level(&self) -> EcLevel { self.ec_level } @@ -186,12 +182,12 @@ impl Index<(uint, uint), bool> for QrCode { #[cfg(test)] mod tests { - use {QrCode, Version, MicroVersion, L, M}; + use {QrCode, Version, EcLevel}; #[test] fn test_annex_i_qr() { // This uses the ISO Annex I as test vector. - let code = QrCode::with_version(b"01234567", Version(1), M).unwrap(); + let code = QrCode::with_version(b"01234567", Version::Normal(1), EcLevel::M).unwrap(); assert_eq!(&*code.to_debug_str('#', '.'), "\n\ #######..#.##.#######\n\ #.....#..####.#.....#\n\ @@ -218,7 +214,7 @@ mod tests { #[test] fn test_annex_i_micro_qr() { - let code = QrCode::with_version(b"01234567", MicroVersion(2), L).unwrap(); + let code = QrCode::with_version(b"01234567", Version::Micro(2), EcLevel::L).unwrap(); assert_eq!(&*code.to_debug_str('#', '.'), "\n\ #######.#.#.#\n\ #.....#.###.#\n\ diff --git a/src/optimize.rs b/src/optimize.rs index 7bc9902..0dafd30 100644 --- a/src/optimize.rs +++ b/src/optimize.rs @@ -7,7 +7,7 @@ use std::slice::Items; #[cfg(test)] use test::Bencher; -use types::{Mode, QrVersion, Numeric, Alphanumeric, Byte, Kanji}; +use types::{Mode, Version}; //------------------------------------------------------------------------------ //{{{ Segment @@ -28,9 +28,9 @@ pub struct Segment { impl Segment { /// Compute the number of bits (including the size of the mode indicator and /// length bits) when this segment is encoded. - pub fn encoded_len(&self, version: QrVersion) -> uint { + pub fn encoded_len(&self, version: Version) -> uint { let byte_size = self.end - self.begin; - let chars_count = if self.mode == Kanji { byte_size / 2 } else { byte_size }; + let chars_count = if self.mode == Mode::Kanji { byte_size / 2 } else { byte_size }; let mode_bits_count = version.mode_bits_count(); let length_bits_count = self.mode.length_bits_count(version); @@ -47,7 +47,9 @@ impl Segment { /// This iterator is basically equivalent to /// /// ```ignore -/// data.map(|c| ExclusiveCharacterSet::from_u8(*c)).chain(Some(EEnd).move_iter()).enumerate() +/// data.map(|c| ExclCharSet::from_u8(*c)) +/// .chain(Some(ExclCharSet::End).move_iter()) +/// .enumerate() /// ``` /// /// But the type is too hard to write, thus the new type. @@ -58,8 +60,8 @@ struct EcsIter { ended: bool, } -impl<'a, I: Iterator<&'a u8>> Iterator<(uint, ExclusiveCharacterSet)> for EcsIter { - fn next(&mut self) -> Option<(uint, ExclusiveCharacterSet)> { +impl<'a, I: Iterator<&'a u8>> Iterator<(uint, ExclCharSet)> for EcsIter { + fn next(&mut self) -> Option<(uint, ExclCharSet)> { if self.ended { return None; } @@ -67,12 +69,12 @@ impl<'a, I: Iterator<&'a u8>> Iterator<(uint, ExclusiveCharacterSet)> for EcsIte match self.base.next() { None => { self.ended = true; - Some((self.index, EEnd)) + Some((self.index, ExclCharSet::End)) } Some(c) => { let old_index = self.index; self.index += 1; - Some((old_index, ExclusiveCharacterSet::from_u8(*c))) + Some((old_index, ExclCharSet::from_u8(*c))) } } } @@ -81,7 +83,7 @@ impl<'a, I: Iterator<&'a u8>> Iterator<(uint, ExclusiveCharacterSet)> for EcsIte /// QR code data parser to classify the input into distinct segments. pub struct Parser<'a> { ecs_iter: EcsIter>, - state: SegmentParseState, + state: State, begin: uint, pending_single_byte: bool, } @@ -101,7 +103,7 @@ impl<'a> Parser<'a> { pub fn new(data: &[u8]) -> Parser { Parser { ecs_iter: EcsIter { base: data.iter(), index: 0, ended: false }, - state: SInit, + state: State::Init, begin: 0, pending_single_byte: false, } @@ -113,7 +115,11 @@ impl<'a> Iterator for Parser<'a> { if self.pending_single_byte { self.pending_single_byte = false; self.begin += 1; - return Some(Segment { mode: Byte, begin: self.begin-1, end: self.begin }); + return Some(Segment { + mode: Mode::Byte, + begin: self.begin-1, + end: self.begin, + }); } loop { @@ -126,25 +132,33 @@ impl<'a> Iterator for Parser<'a> { let old_begin = self.begin; let push_mode = match action { - AIdle => { continue; } - ANumeric => Numeric, - AAlpha => Alphanumeric, - AByte => Byte, - AKanji => Kanji, - AKanjiAndSingleByte => { + Action::Idle => { continue; } + Action::Numeric => Mode::Numeric, + Action::Alpha => Mode::Alphanumeric, + Action::Byte => Mode::Byte, + Action::Kanji => Mode::Kanji, + Action::KanjiAndSingleByte => { let next_begin = i - 1; if self.begin == next_begin { - Byte + Mode::Byte } else { self.pending_single_byte = true; self.begin = next_begin; - return Some(Segment { mode: Kanji, begin: old_begin, end: next_begin }); + return Some(Segment { + mode: Mode::Kanji, + begin: old_begin, + end: next_begin, + }); } } }; self.begin = i; - return Some(Segment { mode: push_mode, begin: old_begin, end: i }); + return Some(Segment { + mode: push_mode, + begin: old_begin, + end: i, + }); } } } @@ -152,7 +166,7 @@ impl<'a> Iterator for Parser<'a> { #[cfg(test)] mod parse_tests { use optimize::{Parser, Segment}; - use types::{Numeric, Alphanumeric, Byte, Kanji}; + use types::Mode; fn parse(data: &[u8]) -> Vec { Parser::new(data).collect() @@ -161,39 +175,39 @@ mod parse_tests { #[test] fn test_parse_1() { let segs = parse(b"01049123451234591597033130128%10ABC123"); - assert_eq!(segs, vec![Segment { mode: Numeric, begin: 0, end: 29 }, - Segment { mode: Alphanumeric, begin: 29, end: 30 }, - Segment { mode: Numeric, begin: 30, end: 32 }, - Segment { mode: Alphanumeric, begin: 32, end: 35 }, - Segment { mode: Numeric, begin: 35, end: 38 }]); + assert_eq!(segs, vec![Segment { mode: Mode::Numeric, begin: 0, end: 29 }, + Segment { mode: Mode::Alphanumeric, begin: 29, end: 30 }, + Segment { mode: Mode::Numeric, begin: 30, end: 32 }, + Segment { mode: Mode::Alphanumeric, begin: 32, end: 35 }, + Segment { mode: Mode::Numeric, begin: 35, end: 38 }]); } #[test] fn test_parse_shift_jis_example_1() { let segs = parse(b"\x82\xa0\x81\x41\x41\xb1\x81\xf0"); // "あ、AアÅ" - assert_eq!(segs, vec![Segment { mode: Kanji, begin: 0, end: 4 }, - Segment { mode: Alphanumeric, begin: 4, end: 5 }, - Segment { mode: Byte, begin: 5, end: 6 }, - Segment { mode: Kanji, begin: 6, end: 8 }]); + assert_eq!(segs, vec![Segment { mode: Mode::Kanji, begin: 0, end: 4 }, + Segment { mode: Mode::Alphanumeric, begin: 4, end: 5 }, + Segment { mode: Mode::Byte, begin: 5, end: 6 }, + Segment { mode: Mode::Kanji, begin: 6, end: 8 }]); } #[test] fn test_parse_utf_8() { // Mojibake? let segs = parse(b"\xe3\x81\x82\xe3\x80\x81A\xef\xbd\xb1\xe2\x84\xab"); - assert_eq!(segs, vec![Segment { mode: Kanji, begin: 0, end: 4 }, - Segment { mode: Byte, begin: 4, end: 5 }, - Segment { mode: Kanji, begin: 5, end: 7 }, - Segment { mode: Byte, begin: 7, end: 10 }, - Segment { mode: Kanji, begin: 10, end: 12 }, - Segment { mode: Byte, begin: 12, end: 13 }]); + assert_eq!(segs, vec![Segment { mode: Mode::Kanji, begin: 0, end: 4 }, + Segment { mode: Mode::Byte, begin: 4, end: 5 }, + Segment { mode: Mode::Kanji, begin: 5, end: 7 }, + Segment { mode: Mode::Byte, begin: 7, end: 10 }, + Segment { mode: Mode::Kanji, begin: 10, end: 12 }, + Segment { mode: Mode::Byte, begin: 12, end: 13 }]); } #[test] fn test_not_kanji_1() { let segs = parse(b"\x81\x30"); - assert_eq!(segs, vec![Segment { mode: Byte, begin: 0, end: 1 }, - Segment { mode: Numeric, begin: 1, end: 2 }]); + assert_eq!(segs, vec![Segment { mode: Mode::Byte, begin: 0, end: 1 }, + Segment { mode: Mode::Numeric, begin: 1, end: 2 }]); } #[test] @@ -201,22 +215,22 @@ mod parse_tests { // Note that it's implementation detail that the byte seq is split into // two. Perhaps adjust the test to check for this. let segs = parse(b"\xeb\xc0"); - assert_eq!(segs, vec![Segment { mode: Byte, begin: 0, end: 1 }, - Segment { mode: Byte, begin: 1, end: 2 }]); + assert_eq!(segs, vec![Segment { mode: Mode::Byte, begin: 0, end: 1 }, + Segment { mode: Mode::Byte, begin: 1, end: 2 }]); } #[test] fn test_not_kanji_3() { let segs = parse(b"\x81\x7f"); - assert_eq!(segs, vec![Segment { mode: Byte, begin: 0, end: 1 }, - Segment { mode: Byte, begin: 1, end: 2 }]); + assert_eq!(segs, vec![Segment { mode: Mode::Byte, begin: 0, end: 1 }, + Segment { mode: Mode::Byte, begin: 1, end: 2 }]); } #[test] fn test_not_kanji_4() { let segs = parse(b"\x81\x40\x81"); - assert_eq!(segs, vec![Segment { mode: Kanji, begin: 0, end: 2 }, - Segment { mode: Byte, begin: 2, end: 3 }]); + assert_eq!(segs, vec![Segment { mode: Mode::Kanji, begin: 0, end: 2 }, + Segment { mode: Mode::Byte, begin: 2, end: 3 }]); } } @@ -228,7 +242,7 @@ pub struct Optimizer { parser: I, last_segment: Segment, last_segment_size: uint, - version: QrVersion, + version: Version, ended: bool, } @@ -239,11 +253,11 @@ impl> Optimizer { /// left to right until the new segment is longer than before. This method /// does *not* use Annex J from the ISO standard. /// - pub fn new(mut segments: I, version: QrVersion) -> Optimizer { + pub fn new(mut segments: I, version: Version) -> Optimizer { match segments.next() { None => Optimizer { parser: segments, - last_segment: Segment { mode: Numeric, begin: 0, end: 0 }, + last_segment: Segment { mode: Mode::Numeric, begin: 0, end: 0 }, last_segment_size: 0, version: version, ended: true, @@ -260,7 +274,7 @@ impl> Optimizer { } impl<'a> Parser<'a> { - pub fn optimize(self, version: QrVersion) -> Optimizer> { + pub fn optimize(self, version: Version) -> Optimizer> { Optimizer::new(self, version) } } @@ -303,7 +317,7 @@ impl> Iterator for Optimizer { } /// Computes the total encoded length of all segments. -pub fn total_encoded_len(segments: &[Segment], version: QrVersion) -> uint { +pub fn total_encoded_len(segments: &[Segment], version: Version) -> uint { use std::iter::AdditiveIterator; segments.iter().map(|seg| seg.encoded_len(version)).sum() } @@ -311,11 +325,11 @@ pub fn total_encoded_len(segments: &[Segment], version: QrVersion) -> uint { #[cfg(test)] mod optimize_tests { use optimize::{Optimizer, total_encoded_len, Segment}; - use types::{Numeric, Alphanumeric, Byte, Kanji, QrVersion, Version, MicroVersion}; + use types::{Mode, Version}; - fn test_optimization_result(given: Vec, expected: Vec, version: QrVersion) { + fn test_optimization_result(given: Vec, expected: Vec, version: Version) { let prev_len = total_encoded_len(&*given, version); - let opt_segs = Optimizer::new(given.iter().map(|seg| *seg), version).collect::>(); + let opt_segs = Optimizer::new(given.iter().map(|seg| *seg), version).collect::>(); let new_len = total_encoded_len(&*opt_segs, version); if given != opt_segs { assert!(prev_len > new_len, "{} > {}", prev_len, new_len); @@ -329,14 +343,14 @@ mod optimize_tests { fn test_example_1() { test_optimization_result( - vec![Segment { mode: Alphanumeric, begin: 0, end: 3 }, - Segment { mode: Numeric, begin: 3, end: 6 }, - Segment { mode: Byte, begin: 6, end: 10 }], + vec![Segment { mode: Mode::Alphanumeric, begin: 0, end: 3 }, + Segment { mode: Mode::Numeric, begin: 3, end: 6 }, + Segment { mode: Mode::Byte, begin: 6, end: 10 }], - vec![Segment { mode: Alphanumeric, begin: 0, end: 6 }, - Segment { mode: Byte, begin: 6, end: 10 }], + vec![Segment { mode: Mode::Alphanumeric, begin: 0, end: 6 }, + Segment { mode: Mode::Byte, begin: 6, end: 10 }], - Version(1) + Version::Normal(1) ); } @@ -345,16 +359,16 @@ mod optimize_tests { fn test_example_2() { test_optimization_result( - vec![Segment { mode: Numeric, begin: 0, end: 29 }, - Segment { mode: Alphanumeric, begin: 29, end: 30 }, - Segment { mode: Numeric, begin: 30, end: 32 }, - Segment { mode: Alphanumeric, begin: 32, end: 35 }, - Segment { mode: Numeric, begin: 35, end: 38 }], + vec![Segment { mode: Mode::Numeric, begin: 0, end: 29 }, + Segment { mode: Mode::Alphanumeric, begin: 29, end: 30 }, + Segment { mode: Mode::Numeric, begin: 30, end: 32 }, + Segment { mode: Mode::Alphanumeric, begin: 32, end: 35 }, + Segment { mode: Mode::Numeric, begin: 35, end: 38 }], - vec![Segment { mode: Numeric, begin: 0, end: 29 }, - Segment { mode: Alphanumeric, begin: 29, end: 38 }], + vec![Segment { mode: Mode::Numeric, begin: 0, end: 29 }, + Segment { mode: Mode::Alphanumeric, begin: 29, end: 38 }], - Version(9) + Version::Normal(9) ); } @@ -363,14 +377,14 @@ mod optimize_tests { fn test_example_3() { test_optimization_result( - vec![Segment { mode: Kanji, begin: 0, end: 4 }, - Segment { mode: Alphanumeric, begin: 4, end: 5 }, - Segment { mode: Byte, begin: 5, end: 6 }, - Segment { mode: Kanji, begin: 6, end: 8 }], + vec![Segment { mode: Mode::Kanji, begin: 0, end: 4 }, + Segment { mode: Mode::Alphanumeric, begin: 4, end: 5 }, + Segment { mode: Mode::Byte, begin: 5, end: 6 }, + Segment { mode: Mode::Kanji, begin: 6, end: 8 }], - vec![Segment { mode: Byte, begin: 0, end: 8 }], + vec![Segment { mode: Mode::Byte, begin: 0, end: 8 }], - Version(1) + Version::Normal(1) ); } @@ -379,13 +393,13 @@ mod optimize_tests { fn test_example_4() { test_optimization_result( - vec![Segment { mode: Kanji, begin: 0, end: 10 }, - Segment { mode: Byte, begin: 10, end: 11 }], + vec![Segment { mode: Mode::Kanji, begin: 0, end: 10 }, + Segment { mode: Mode::Byte, begin: 10, end: 11 }], - vec![Segment { mode: Kanji, begin: 0, end: 10 }, - Segment { mode: Byte, begin: 10, end: 11 }], + vec![Segment { mode: Mode::Kanji, begin: 0, end: 10 }, + Segment { mode: Mode::Byte, begin: 10, end: 11 }], - Version(1) + Version::Normal(1) ); } @@ -394,13 +408,13 @@ mod optimize_tests { fn test_annex_j_guideline_1a() { test_optimization_result( - vec![Segment { mode: Numeric, begin: 0, end: 3 }, - Segment { mode: Alphanumeric, begin: 3, end: 4 }], + vec![Segment { mode: Mode::Numeric, begin: 0, end: 3 }, + Segment { mode: Mode::Alphanumeric, begin: 3, end: 4 }], - vec![Segment { mode: Numeric, begin: 0, end: 3 }, - Segment { mode: Alphanumeric, begin: 3, end: 4 }], + vec![Segment { mode: Mode::Numeric, begin: 0, end: 3 }, + Segment { mode: Mode::Alphanumeric, begin: 3, end: 4 }], - MicroVersion(2) + Version::Micro(2) ); } @@ -409,12 +423,12 @@ mod optimize_tests { fn test_annex_j_guideline_1b() { test_optimization_result( - vec![Segment { mode: Numeric, begin: 0, end: 2 }, - Segment { mode: Alphanumeric, begin: 2, end: 4 }], + vec![Segment { mode: Mode::Numeric, begin: 0, end: 2 }, + Segment { mode: Mode::Alphanumeric, begin: 2, end: 4 }], - vec![Segment { mode: Alphanumeric, begin: 0, end: 4 }], + vec![Segment { mode: Mode::Alphanumeric, begin: 0, end: 4 }], - MicroVersion(2) + Version::Micro(2) ); } @@ -423,12 +437,12 @@ mod optimize_tests { fn test_annex_j_guideline_1c() { test_optimization_result( - vec![Segment { mode: Numeric, begin: 0, end: 3 }, - Segment { mode: Alphanumeric, begin: 3, end: 4 }], + vec![Segment { mode: Mode::Numeric, begin: 0, end: 3 }, + Segment { mode: Mode::Alphanumeric, begin: 3, end: 4 }], - vec![Segment { mode: Alphanumeric, begin: 0, end: 4 }], + vec![Segment { mode: Mode::Alphanumeric, begin: 0, end: 4 }], - MicroVersion(3) + Version::Micro(3) ); } @@ -441,7 +455,7 @@ fn bench_optimize(bencher: &mut Bencher) { let data = b"QR\x83R\x81[\x83h\x81i\x83L\x83\x85\x81[\x83A\x81[\x83\x8b\x83R\x81[\x83h\x81j\x82\xc6\x82\xcd\x81A1994\x94N\x82\xc9\x83f\x83\x93\x83\\\x81[\x82\xcc\x8aJ\x94\xad\x95\x94\x96\xe5\x81i\x8c\xbb\x8d\xdd\x82\xcd\x95\xaa\x97\xa3\x82\xb5\x83f\x83\x93\x83\\\x81[\x83E\x83F\x81[\x83u\x81j\x82\xaa\x8aJ\x94\xad\x82\xb5\x82\xbd\x83}\x83g\x83\x8a\x83b\x83N\x83X\x8c^\x93\xf1\x8e\x9f\x8c\xb3\x83R\x81[\x83h\x82\xc5\x82\xa0\x82\xe9\x81B\x82\xc8\x82\xa8\x81AQR\x83R\x81[\x83h\x82\xc6\x82\xa2\x82\xa4\x96\xbc\x8f\xcc\x81i\x82\xa8\x82\xe6\x82\xd1\x92P\x8c\xea\x81j\x82\xcd\x83f\x83\x93\x83\\\x81[\x83E\x83F\x81[\x83u\x82\xcc\x93o\x98^\x8f\xa4\x95W\x81i\x91\xe64075066\x8d\x86\x81j\x82\xc5\x82\xa0\x82\xe9\x81BQR\x82\xcdQuick Response\x82\xc9\x97R\x97\x88\x82\xb5\x81A\x8d\x82\x91\xac\x93\xc7\x82\xdd\x8e\xe6\x82\xe8\x82\xaa\x82\xc5\x82\xab\x82\xe9\x82\xe6\x82\xa4\x82\xc9\x8aJ\x94\xad\x82\xb3\x82\xea\x82\xbd\x81B\x93\x96\x8f\x89\x82\xcd\x8e\xa9\x93\xae\x8e\xd4\x95\x94\x95i\x8dH\x8f\xea\x82\xe2\x94z\x91\x97\x83Z\x83\x93\x83^\x81[\x82\xc8\x82\xc7\x82\xc5\x82\xcc\x8eg\x97p\x82\xf0\x94O\x93\xaa\x82\xc9\x8aJ\x94\xad\x82\xb3\x82\xea\x82\xbd\x82\xaa\x81A\x8c\xbb\x8d\xdd\x82\xc5\x82\xcd\x83X\x83}\x81[\x83g\x83t\x83H\x83\x93\x82\xcc\x95\x81\x8by\x82\xc8\x82\xc7\x82\xc9\x82\xe6\x82\xe8\x93\xfa\x96{\x82\xc9\x8c\xc0\x82\xe7\x82\xb8\x90\xa2\x8aE\x93I\x82\xc9\x95\x81\x8by\x82\xb5\x82\xc4\x82\xa2\x82\xe9\x81B"; bencher.iter(|| { - Parser::new(data).optimize(Version(15)) + Parser::new(data).optimize(Version::Normal(15)) }); } @@ -450,210 +464,208 @@ fn bench_optimize(bencher: &mut Bencher) { //------------------------------------------------------------------------------ //{{{ Internal types and data for parsing -// All the silly prefixes are to avoid name collision with each other. - /// All values of `u8` can be split into 9 different character sets when /// determining which encoding to use. This enum represents these groupings for /// parsing purpose. -enum ExclusiveCharacterSet { +enum ExclCharSet { /// The end of string. - EEnd = 0, + End = 0, /// All symbols supported by the Alphanumeric encoding, i.e. space, `$`, `%`, /// `*`, `+`, `-`, `.`, `/` and `:`. - ESymbol = 1, + Symbol = 1, /// All numbers (0–9). - ENumeric = 2, + Numeric = 2, /// All uppercase letters (A–Z). These characters may also appear in the /// second byte of a Shift JIS 2-byte encoding. - EAlpha = 3, + Alpha = 3, /// The first byte of a Shift JIS 2-byte encoding, in the range 0x81–0x9f. - EKanjiHi1 = 4, + KanjiHi1 = 4, /// The first byte of a Shift JIS 2-byte encoding, in the range 0xe0–0xea. - EKanjiHi2 = 5, + KanjiHi2 = 5, /// The first byte of a Shift JIS 2-byte encoding, of value 0xeb. This is /// different from the other two range that the second byte has a smaller /// range. - EKanjiHi3 = 6, + KanjiHi3 = 6, /// The second byte of a Shift JIS 2-byte encoding, in the range 0x40–0xbf, /// excluding letters (covered by `Alpha`), 0x81–0x9f (covered by `KanjiHi1`), /// and the invalid byte 0x7f. - EKanjiLo1 = 7, + KanjiLo1 = 7, /// The second byte of a Shift JIS 2-byte encoding, in the range 0xc0–0xfc, /// excluding the range 0xe0–0xeb (covered by `KanjiHi2` and `KanjiHi3`). /// This half of byte-pair cannot appear as the second byte leaded by /// `KanjiHi3`. - EKanjiLo2 = 8, + KanjiLo2 = 8, /// Any other values not covered by the above character sets. - EByte = 9, + Byte = 9, } -impl ExclusiveCharacterSet { +impl ExclCharSet { /// Determines which character set a byte is in. - fn from_u8(c: u8) -> ExclusiveCharacterSet { + fn from_u8(c: u8) -> ExclCharSet { match c { - 0x20 | 0x24 | 0x25 | 0x2a | 0x2b | 0x2d ... 0x2f | 0x3a => ESymbol, - 0x30 ... 0x39 => ENumeric, - 0x41 ... 0x5a => EAlpha, - 0x81 ... 0x9f => EKanjiHi1, - 0xe0 ... 0xea => EKanjiHi2, - 0xeb => EKanjiHi3, - 0x40 | 0x5b ... 0x7e | 0x80 | 0xa0 ... 0xbf => EKanjiLo1, - 0xc0 ... 0xdf | 0xec ... 0xfc => EKanjiLo2, - _ => EByte + 0x20 | 0x24 | 0x25 | 0x2a | 0x2b | 0x2d ... 0x2f | 0x3a => ExclCharSet::Symbol, + 0x30 ... 0x39 => ExclCharSet::Numeric, + 0x41 ... 0x5a => ExclCharSet::Alpha, + 0x81 ... 0x9f => ExclCharSet::KanjiHi1, + 0xe0 ... 0xea => ExclCharSet::KanjiHi2, + 0xeb => ExclCharSet::KanjiHi3, + 0x40 | 0x5b ... 0x7e | 0x80 | 0xa0 ... 0xbf => ExclCharSet::KanjiLo1, + 0xc0 ... 0xdf | 0xec ... 0xfc => ExclCharSet::KanjiLo2, + _ => ExclCharSet::Byte } } } /// The current parsing state. -enum SegmentParseState { +enum State { /// Just initialized. - SInit = 0, + Init = 0, /// Inside a string that can be exclusively encoded as Numeric. - SNumeric = 10, + Numeric = 10, /// Inside a string that can be exclusively encoded as Alphanumeric. - SAlpha = 20, + Alpha = 20, /// Inside a string that can be exclusively encoded as 8-Bit Byte. - SByte = 30, + Byte = 30, /// Just encountered the first byte of a Shift JIS 2-byte sequence of the /// set `KanjiHi1` or `KanjiHi2`. - SKanjiHi12 = 40, + KanjiHi12 = 40, /// Just encountered the first byte of a Shift JIS 2-byte sequence of the /// set `KanjiHi3`. - SKanjiHi3 = 50, + KanjiHi3 = 50, /// Inside a string that can be exclusively encoded as Kanji. - SKanji = 60, + Kanji = 60, } /// What should the parser do after a state transition. -enum ParserAction { +enum Action { /// The parser should do nothing. - AIdle, + Idle, /// Push the current segment as a Numeric string, and reset the marks. - ANumeric, + Numeric, /// Push the current segment as an Alphanumeric string, and reset the marks. - AAlpha, + Alpha, /// Push the current segment as a 8-Bit Byte string, and reset the marks. - AByte, + Byte, /// Push the current segment as a Kanji string, and reset the marks. - AKanji, + Kanji, /// Push the current segment excluding the last byte as a Kanji string, then /// push the remaining single byte as a Byte string, and reset the marks. - AKanjiAndSingleByte, + KanjiAndSingleByte, } -static STATE_TRANSITION: [(SegmentParseState, ParserAction), ..70] = [ +static STATE_TRANSITION: [(State, Action), ..70] = [ // STATE_TRANSITION[current_state + next_character] == (next_state, what_to_do) // Init state: - (SInit, AIdle), // End - (SAlpha, AIdle), // Symbol - (SNumeric, AIdle), // Numeric - (SAlpha, AIdle), // Alpha - (SKanjiHi12, AIdle), // KanjiHi1 - (SKanjiHi12, AIdle), // KanjiHi2 - (SKanjiHi3, AIdle), // KanjiHi3 - (SByte, AIdle), // KanjiLo1 - (SByte, AIdle), // KanjiLo2 - (SByte, AIdle), // Byte + (State::Init, Action::Idle), // End + (State::Alpha, Action::Idle), // Symbol + (State::Numeric, Action::Idle), // Numeric + (State::Alpha, Action::Idle), // Alpha + (State::KanjiHi12, Action::Idle), // KanjiHi1 + (State::KanjiHi12, Action::Idle), // KanjiHi2 + (State::KanjiHi3, Action::Idle), // KanjiHi3 + (State::Byte, Action::Idle), // KanjiLo1 + (State::Byte, Action::Idle), // KanjiLo2 + (State::Byte, Action::Idle), // Byte // Numeric state: - (SInit, ANumeric), // End - (SAlpha, ANumeric), // Symbol - (SNumeric, AIdle), // Numeric - (SAlpha, ANumeric), // Alpha - (SKanjiHi12, ANumeric), // KanjiHi1 - (SKanjiHi12, ANumeric), // KanjiHi2 - (SKanjiHi3, ANumeric), // KanjiHi3 - (SByte, ANumeric), // KanjiLo1 - (SByte, ANumeric), // KanjiLo2 - (SByte, ANumeric), // Byte + (State::Init, Action::Numeric), // End + (State::Alpha, Action::Numeric), // Symbol + (State::Numeric, Action::Idle), // Numeric + (State::Alpha, Action::Numeric), // Alpha + (State::KanjiHi12, Action::Numeric), // KanjiHi1 + (State::KanjiHi12, Action::Numeric), // KanjiHi2 + (State::KanjiHi3, Action::Numeric), // KanjiHi3 + (State::Byte, Action::Numeric), // KanjiLo1 + (State::Byte, Action::Numeric), // KanjiLo2 + (State::Byte, Action::Numeric), // Byte // Alpha state: - (SInit, AAlpha), // End - (SAlpha, AIdle), // Symbol - (SNumeric, AAlpha), // Numeric - (SAlpha, AIdle), // Alpha - (SKanjiHi12, AAlpha), // KanjiHi1 - (SKanjiHi12, AAlpha), // KanjiHi2 - (SKanjiHi3, AAlpha), // KanjiHi3 - (SByte, AAlpha), // KanjiLo1 - (SByte, AAlpha), // KanjiLo2 - (SByte, AAlpha), // Byte + (State::Init, Action::Alpha), // End + (State::Alpha, Action::Idle), // Symbol + (State::Numeric, Action::Alpha), // Numeric + (State::Alpha, Action::Idle), // Alpha + (State::KanjiHi12, Action::Alpha), // KanjiHi1 + (State::KanjiHi12, Action::Alpha), // KanjiHi2 + (State::KanjiHi3, Action::Alpha), // KanjiHi3 + (State::Byte, Action::Alpha), // KanjiLo1 + (State::Byte, Action::Alpha), // KanjiLo2 + (State::Byte, Action::Alpha), // Byte // Byte state: - (SInit, AByte), // End - (SAlpha, AByte), // Symbol - (SNumeric, AByte), // Numeric - (SAlpha, AByte), // Alpha - (SKanjiHi12, AByte), // KanjiHi1 - (SKanjiHi12, AByte), // KanjiHi2 - (SKanjiHi3, AByte), // KanjiHi3 - (SByte, AIdle), // KanjiLo1 - (SByte, AIdle), // KanjiLo2 - (SByte, AIdle), // Byte + (State::Init, Action::Byte), // End + (State::Alpha, Action::Byte), // Symbol + (State::Numeric, Action::Byte), // Numeric + (State::Alpha, Action::Byte), // Alpha + (State::KanjiHi12, Action::Byte), // KanjiHi1 + (State::KanjiHi12, Action::Byte), // KanjiHi2 + (State::KanjiHi3, Action::Byte), // KanjiHi3 + (State::Byte, Action::Idle), // KanjiLo1 + (State::Byte, Action::Idle), // KanjiLo2 + (State::Byte, Action::Idle), // Byte // KanjiHi12 state: - (SInit, AKanjiAndSingleByte), // End - (SAlpha, AKanjiAndSingleByte), // Symbol - (SNumeric, AKanjiAndSingleByte), // Numeric - (SKanji, AIdle), // Alpha - (SKanji, AIdle), // KanjiHi1 - (SKanji, AIdle), // KanjiHi2 - (SKanji, AIdle), // KanjiHi3 - (SKanji, AIdle), // KanjiLo1 - (SKanji, AIdle), // KanjiLo2 - (SByte, AKanjiAndSingleByte), // Byte + (State::Init, Action::KanjiAndSingleByte), // End + (State::Alpha, Action::KanjiAndSingleByte), // Symbol + (State::Numeric, Action::KanjiAndSingleByte), // Numeric + (State::Kanji, Action::Idle), // Alpha + (State::Kanji, Action::Idle), // KanjiHi1 + (State::Kanji, Action::Idle), // KanjiHi2 + (State::Kanji, Action::Idle), // KanjiHi3 + (State::Kanji, Action::Idle), // KanjiLo1 + (State::Kanji, Action::Idle), // KanjiLo2 + (State::Byte, Action::KanjiAndSingleByte), // Byte // KanjiHi3 state: - (SInit, AKanjiAndSingleByte), // End - (SAlpha, AKanjiAndSingleByte), // Symbol - (SNumeric, AKanjiAndSingleByte), // Numeric - (SKanji, AIdle), // Alpha - (SKanji, AIdle), // KanjiHi1 - (SKanjiHi12, AKanjiAndSingleByte), // KanjiHi2 - (SKanjiHi3, AKanjiAndSingleByte), // KanjiHi3 - (SKanji, AIdle), // KanjiLo1 - (SByte, AKanjiAndSingleByte), // KanjiLo2 - (SByte, AKanjiAndSingleByte), // Byte + (State::Init, Action::KanjiAndSingleByte), // End + (State::Alpha, Action::KanjiAndSingleByte), // Symbol + (State::Numeric, Action::KanjiAndSingleByte), // Numeric + (State::Kanji, Action::Idle), // Alpha + (State::Kanji, Action::Idle), // KanjiHi1 + (State::KanjiHi12, Action::KanjiAndSingleByte), // KanjiHi2 + (State::KanjiHi3, Action::KanjiAndSingleByte), // KanjiHi3 + (State::Kanji, Action::Idle), // KanjiLo1 + (State::Byte, Action::KanjiAndSingleByte), // KanjiLo2 + (State::Byte, Action::KanjiAndSingleByte), // Byte // Kanji state: - (SInit, AKanji), // End - (SAlpha, AKanji), // Symbol - (SNumeric, AKanji), // Numeric - (SAlpha, AKanji), // Alpha - (SKanjiHi12, AIdle), // KanjiHi1 - (SKanjiHi12, AIdle), // KanjiHi2 - (SKanjiHi3, AIdle), // KanjiHi3 - (SByte, AKanji), // KanjiLo1 - (SByte, AKanji), // KanjiLo2 - (SByte, AKanji), // Byte + (State::Init, Action::Kanji), // End + (State::Alpha, Action::Kanji), // Symbol + (State::Numeric, Action::Kanji), // Numeric + (State::Alpha, Action::Kanji), // Alpha + (State::KanjiHi12, Action::Idle), // KanjiHi1 + (State::KanjiHi12, Action::Idle), // KanjiHi2 + (State::KanjiHi3, Action::Idle), // KanjiHi3 + (State::Byte, Action::Kanji), // KanjiLo1 + (State::Byte, Action::Kanji), // KanjiLo2 + (State::Byte, Action::Kanji), // Byte ]; //}}} diff --git a/src/types.rs b/src/types.rs index fb059eb..5d438de 100644 --- a/src/types.rs +++ b/src/types.rs @@ -39,7 +39,7 @@ pub type QrResult = Result; /// even if parts of the code is damaged. #[deriving(Show, PartialEq, Eq, Copy, Clone, PartialOrd, Ord)] #[unstable] -pub enum ErrorCorrectionLevel { +pub enum EcLevel { /// Low error correction. Allows up to 7% of wrong blocks. L = 0, @@ -61,27 +61,26 @@ pub enum ErrorCorrectionLevel { /// Larger version means the size of code is larger, and therefore can carry /// more information. /// -/// The smallest version is `Version(1)` of size 21×21, and the largest is -/// `Version(40)` of size 177×177. +/// The smallest version is `Version::Normal(1)` of size 21×21, and the largest +/// is `Version::Normal(40)` of size 177×177. #[unstable] #[deriving(Show, PartialEq, Eq, Copy, Clone)] -pub enum QrVersion { +pub enum Version { /// A normal QR code version. The parameter should be between 1 and 40. - #[unstable] - Version(i16), + Normal(i16), /// A Micro QR code version. The parameter should be between 1 and 4. - MicroVersion(i16), + Micro(i16), } -impl QrVersion { +impl Version { /// Get the number of "modules" on each size of the QR code, i.e. the width /// and height of the code. #[unstable] pub fn width(&self) -> i16 { match *self { - Version(v) => v * 4 + 17, - MicroVersion(v) => v * 2 + 9, + Version::Normal(v) => v * 4 + 17, + Version::Micro(v) => v * 2 + 9, } } @@ -94,21 +93,21 @@ impl QrVersion { /// the order [L, M, Q, H]. /// /// If the entry compares equal to the default value of T, this method - /// returns `Err(InvalidVersion)`. - pub fn fetch(&self, ec_level: ErrorCorrectionLevel, table: &[[T, ..4]]) -> QrResult + /// returns `Err(QrError::InvalidVersion)`. + pub fn fetch(&self, ec_level: EcLevel, table: &[[T, ..4]]) -> QrResult where T: PartialEq + Default + Copy { match *self { - Version(v @ 1...40) => Ok(table[v as uint - 1][ec_level as uint]), - MicroVersion(v @ 1...4) => { + Version::Normal(v @ 1...40) => Ok(table[v as uint - 1][ec_level as uint]), + Version::Micro(v @ 1...4) => { let obj = table[v as uint + 39][ec_level as uint]; if obj != Default::default() { Ok(obj) } else { - Err(InvalidVersion) + Err(QrError::InvalidVersion) } } - _ => Err(InvalidVersion) + _ => Err(QrError::InvalidVersion) } } @@ -116,7 +115,7 @@ impl QrVersion { #[unstable] pub fn mode_bits_count(&self) -> uint { match *self { - MicroVersion(a) => (a - 1) as uint, + Version::Micro(a) => (a - 1) as uint, _ => 4, } } @@ -125,8 +124,8 @@ impl QrVersion { #[unstable] pub fn is_micro(&self) -> bool { match *self { - Version(_) => false, - MicroVersion(_) => true, + Version::Normal(_) => false, + Version::Micro(_) => true, } } } @@ -156,68 +155,68 @@ pub enum Mode { impl Mode { /// Computes the number of bits needed to encode the data length. /// - /// use qrcode::types::{Version, Numeric}; + /// use qrcode::types::{Version, Mode}; /// - /// assert_eq!(Numeric.length_bits_count(Version(1)), 10); + /// assert_eq!(Mode::Numeric.length_bits_count(Version::Normal(1)), 10); /// - /// This method will return `Err(UnsupportedCharacterSet)` if the is not - /// supported in the given version. + /// This method will return `Err(QrError::UnsupportedCharacterSet)` if the + /// mode is not supported in the given version. #[unstable] - pub fn length_bits_count(&self, version: QrVersion) -> uint { + pub fn length_bits_count(&self, version: Version) -> uint { match version { - MicroVersion(a) => { + Version::Micro(a) => { let a = a as uint; match *self { - Numeric => 2 + a, - Alphanumeric | Byte => 1 + a, - Kanji => a, + Mode::Numeric => 2 + a, + Mode::Alphanumeric | Mode::Byte => 1 + a, + Mode::Kanji => a, } } - Version(1...9) => match *self { - Numeric => 10, - Alphanumeric => 9, - Byte => 8, - Kanji => 8, + Version::Normal(1...9) => match *self { + Mode::Numeric => 10, + Mode::Alphanumeric => 9, + Mode::Byte => 8, + Mode::Kanji => 8, }, - Version(10...26) => match *self { - Numeric => 12, - Alphanumeric => 11, - Byte => 16, - Kanji => 10, + Version::Normal(10...26) => match *self { + Mode::Numeric => 12, + Mode::Alphanumeric => 11, + Mode::Byte => 16, + Mode::Kanji => 10, }, - Version(_) => match *self { - Numeric => 14, - Alphanumeric => 13, - Byte => 16, - Kanji => 12, + Version::Normal(_) => match *self { + Mode::Numeric => 14, + Mode::Alphanumeric => 13, + Mode::Byte => 16, + Mode::Kanji => 12, }, } } /// Computes the number of bits needed to some data of a given raw length. /// - /// use qrcode::types::Numeric; + /// use qrcode::types::Mode; /// - /// assert_eq!(Numeric.data_bits_count(7), 24); + /// assert_eq!(Mode::Numeric.data_bits_count(7), 24); /// /// Note that in Kanji mode, the `raw_data_len` is the number of Kanjis, /// i.e. half the total size of bytes. #[unstable] pub fn data_bits_count(&self, raw_data_len: uint) -> uint { match *self { - Numeric => (raw_data_len * 10 + 2) / 3, - Alphanumeric => (raw_data_len * 11 + 1) / 2, - Byte => raw_data_len * 8, - Kanji => raw_data_len * 13, + Mode::Numeric => (raw_data_len * 10 + 2) / 3, + Mode::Alphanumeric => (raw_data_len * 11 + 1) / 2, + Mode::Byte => raw_data_len * 8, + Mode::Kanji => raw_data_len * 13, } } /// Find the lowest common mode which both modes are compatible with. /// - /// use qrcode::types::{Numeric, Kanji}; + /// use qrcode::types::Mode; /// - /// let a = Numeric; - /// let b = Kanji; + /// let a = Mode::Numeric; + /// let b = Mode::Kanji; /// let c = a.max(b); /// assert!(a <= c); /// assert!(b <= c); @@ -226,7 +225,7 @@ impl Mode { match self.partial_cmp(&other) { Some(Less) | Some(Equal) => other, Some(Greater) => *self, - None => Byte, + None => Mode::Byte, } } } @@ -236,14 +235,14 @@ impl PartialOrd for Mode { /// a superset of all characters supported by `a`. fn partial_cmp(&self, other: &Mode) -> Option { match (*self, *other) { - (Numeric, Alphanumeric) => Some(Less), - (Alphanumeric, Numeric) => Some(Greater), - (Numeric, Byte) => Some(Less), - (Byte, Numeric) => Some(Greater), - (Alphanumeric, Byte) => Some(Less), - (Byte, Alphanumeric) => Some(Greater), - (Kanji, Byte) => Some(Less), - (Byte, Kanji) => Some(Greater), + (Mode::Numeric, Mode::Alphanumeric) => Some(Less), + (Mode::Alphanumeric, Mode::Numeric) => Some(Greater), + (Mode::Numeric, Mode::Byte) => Some(Less), + (Mode::Byte, Mode::Numeric) => Some(Greater), + (Mode::Alphanumeric, Mode::Byte) => Some(Less), + (Mode::Byte, Mode::Alphanumeric) => Some(Greater), + (Mode::Kanji, Mode::Byte) => Some(Less), + (Mode::Byte, Mode::Kanji) => Some(Greater), (a, b) if a == b => Some(Equal), _ => None, } @@ -252,7 +251,7 @@ impl PartialOrd for Mode { #[cfg(test)] mod mode_tests { - use types::{Numeric, Alphanumeric, Byte, Kanji}; + use types::Mode::{Numeric, Alphanumeric, Byte, Kanji}; #[test] fn test_mode_order() {