From 88be30fe12ab0bc44dec38251291ffae945d80d0 Mon Sep 17 00:00:00 2001 From: Project Nayuki Date: Mon, 28 Aug 2017 05:43:00 +0000 Subject: [PATCH] Changed Rust QrSegmentMode struct into enum, changed fields to methods, made the type copyable, got rid of static lifetimes and references in favor of passing by value, updated a program to work with this altered API. --- rust/examples/qrcodegen-demo.rs | 2 +- rust/src/lib.rs | 65 ++++++++++++++++++++------------- 2 files changed, 40 insertions(+), 27 deletions(-) diff --git a/rust/examples/qrcodegen-demo.rs b/rust/examples/qrcodegen-demo.rs index 1966214..6b6c2a2 100644 --- a/rust/examples/qrcodegen-demo.rs +++ b/rust/examples/qrcodegen-demo.rs @@ -133,7 +133,7 @@ fn do_segment_demo() { qrcodegen::append_bits(&mut bb, *c, 13); } let segs = vec![ - QrSegment::new(&qrcodegen::QrSegmentMode_KANJI, kanjichars.len(), bb), + QrSegment::new(qrcodegen::QrSegmentMode::Kanji, kanjichars.len(), bb), ]; let qr = QrCode::encode_segments(&segs, QrCodeEcc::Low).unwrap(); print_qr(&qr); diff --git a/rust/src/lib.rs b/rust/src/lib.rs index dd4b66b..65c6013 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -102,7 +102,7 @@ impl QrCode { let datacapacitybits: usize = QrCode::get_num_data_codewords(version, ecl) * 8; let mut bb: Vec = Vec::new(); for seg in segs { - append_bits(&mut bb, seg.mode.modebits as u32, 4); + append_bits(&mut bb, seg.mode.mode_bits(), 4); append_bits(&mut bb, seg.numchars as u32, seg.mode.num_char_count_bits(version)); bb.extend_from_slice(&seg.data); } @@ -793,7 +793,7 @@ impl ReedSolomonGenerator { pub struct QrSegment { // The mode indicator for this segment. - mode: &'static QrSegmentMode, + mode: QrSegmentMode, // The length of this segment's unencoded data, measured in characters. numchars: usize, @@ -815,7 +815,7 @@ impl QrSegment { bb.push((b >> i) & 1u8 != 0u8); } } - QrSegment::new(&QrSegmentMode_BYTE, data.len(), bb) + QrSegment::new(QrSegmentMode::Byte, data.len(), bb) } @@ -836,7 +836,7 @@ impl QrSegment { if accumcount > 0 { // 1 or 2 digits remaining append_bits(&mut bb, accumdata, (accumcount as u8) * 3 + 1); } - QrSegment::new(&QrSegmentMode_NUMERIC, text.len(), bb) + QrSegment::new(QrSegmentMode::Numeric, text.len(), bb) } @@ -860,7 +860,7 @@ impl QrSegment { if accumcount > 0 { // 1 character remaining append_bits(&mut bb, accumdata, 6); } - QrSegment::new(&QrSegmentMode_ALPHANUMERIC, text.len(), bb) + QrSegment::new(QrSegmentMode::Alphanumeric, text.len(), bb) } @@ -891,11 +891,11 @@ impl QrSegment { } else { panic!("ECI assignment value out of range"); } - QrSegment::new(&QrSegmentMode_ECI, 0, bb) + QrSegment::new(QrSegmentMode::Eci, 0, bb) } - pub fn new(mode: &'static QrSegmentMode, numchars: usize, data: Vec) -> QrSegment { + pub fn new(mode: QrSegmentMode, numchars: usize, data: Vec) -> QrSegment { QrSegment { mode: mode, numchars: numchars, @@ -904,7 +904,7 @@ impl QrSegment { } - pub fn mode(&self) -> &QrSegmentMode { + pub fn mode(&self) -> QrSegmentMode { self.mode } @@ -956,26 +956,46 @@ static QrSegment_ALPHANUMERIC_CHARSET: [char; 45] = ['0','1','2','3','4','5','6' /*---- QrSegmentMode functionality ----*/ -pub struct QrSegmentMode { - - // An unsigned 4-bit integer value (range 0 to 15) - // representing the mode indicator bits for this mode object. - modebits: u8, - - numbitscharcount: [u8; 3], - +#[derive(Clone, Copy)] +pub enum QrSegmentMode { + Numeric, + Alphanumeric, + Byte, + Kanji, + Eci, } impl QrSegmentMode { + // Returns an unsigned 4-bit integer value (range 0 to 15) + // representing the mode indicator bits for this mode object. + fn mode_bits(&self) -> u32 { + match *self { + QrSegmentMode::Numeric => 0x1, + QrSegmentMode::Alphanumeric => 0x2, + QrSegmentMode::Byte => 0x4, + QrSegmentMode::Kanji => 0x8, + QrSegmentMode::Eci => 0x7, + } + } + + pub fn num_char_count_bits(&self, ver: u8) -> u8 { + let array: [u8; 3] = match *self { + QrSegmentMode::Numeric => [10, 12, 14], + QrSegmentMode::Alphanumeric => [ 9, 11, 13], + QrSegmentMode::Byte => [ 8, 16, 16], + QrSegmentMode::Kanji => [ 8, 10, 12], + QrSegmentMode::Eci => [ 0, 0, 0], + }; + if 1 <= ver && ver <= 9 { - self.numbitscharcount[0] + array[0] } else if 10 <= ver && ver <= 26 { - self.numbitscharcount[1] + array[1] } else if 27 <= ver && ver <= 40 { - self.numbitscharcount[2] + array[2] } else { panic!("Version number out of range"); } @@ -984,13 +1004,6 @@ impl QrSegmentMode { } -pub static QrSegmentMode_NUMERIC : QrSegmentMode = QrSegmentMode { modebits: 0x1, numbitscharcount: [10, 12, 14] }; -pub static QrSegmentMode_ALPHANUMERIC: QrSegmentMode = QrSegmentMode { modebits: 0x2, numbitscharcount: [ 9, 11, 13] }; -pub static QrSegmentMode_BYTE : QrSegmentMode = QrSegmentMode { modebits: 0x4, numbitscharcount: [ 8, 16, 16] }; -pub static QrSegmentMode_KANJI : QrSegmentMode = QrSegmentMode { modebits: 0x8, numbitscharcount: [ 8, 10, 12] }; -pub static QrSegmentMode_ECI : QrSegmentMode = QrSegmentMode { modebits: 0x7, numbitscharcount: [ 0, 0, 0] }; - - /*---- Bit buffer functionality ----*/