diff --git a/src/aztec/DecoderTest.rs b/src/aztec/DecoderTest.rs index ee52b58..c7deae2 100644 --- a/src/aztec/DecoderTest.rs +++ b/src/aztec/DecoderTest.rs @@ -32,7 +32,7 @@ use crate::{ RXingResultPoint, }; -use super::{decoder, AztecDetectorResult::AztecDetectorRXingResult}; +use super::{aztec_detector_result::AztecDetectorRXingResult, decoder}; /** * Tests {@link Decoder}. diff --git a/src/aztec/DetectorTest.rs b/src/aztec/DetectorTest.rs index 3271a9a..5c9cc50 100644 --- a/src/aztec/DetectorTest.rs +++ b/src/aztec/DetectorTest.rs @@ -185,7 +185,7 @@ fn test_error_in_parameter_locator(data: &str) { // Zooms a bit matrix so that each bit is factor x factor fn make_larger(input: &BitMatrix, factor: u32) -> BitMatrix { let width = input.getWidth(); - let mut output = BitMatrix::with_single_dimension(width * factor); + let mut output = BitMatrix::with_single_dimension(width * factor).expect("new"); for inputY in 0..width { // for (int inputY = 0; inputY < width; inputY++) { for inputX in 0..width { @@ -216,7 +216,7 @@ fn get_rotations(matrix0: &BitMatrix) -> Vec { // Rotates a square BitMatrix to the right by 90 degrees fn rotate_right(input: &BitMatrix) -> BitMatrix { let width = input.getWidth(); - let mut result = BitMatrix::with_single_dimension(width); + let mut result = BitMatrix::with_single_dimension(width).expect("new"); for x in 0..width { // for (int x = 0; x < width; x++) { for y in 0..width { @@ -233,7 +233,7 @@ fn rotate_right(input: &BitMatrix) -> BitMatrix { // matrix to the right, and then flipping it left-to-right fn transpose(input: &BitMatrix) -> BitMatrix { let width = input.getWidth(); - let mut result = BitMatrix::with_single_dimension(width); + let mut result = BitMatrix::with_single_dimension(width).expect("new"); for x in 0..width { // for (int x = 0; x < width; x++) { for y in 0..width { @@ -248,7 +248,7 @@ fn transpose(input: &BitMatrix) -> BitMatrix { fn clone(input: &BitMatrix) -> BitMatrix { let width = input.getWidth(); - let mut result = BitMatrix::with_single_dimension(width); + let mut result = BitMatrix::with_single_dimension(width).expect("new"); for x in 0..width { // for (int x = 0; x < width; x++) { for y in 0..width { diff --git a/src/aztec/EncoderTest.rs b/src/aztec/EncoderTest.rs index c5891b2..af45797 100644 --- a/src/aztec/EncoderTest.rs +++ b/src/aztec/EncoderTest.rs @@ -20,10 +20,10 @@ use encoding::EncodingRef; use crate::{ aztec::{ + aztec_detector_result::AztecDetectorRXingResult, decoder, encoder::HighLevelEncoder, shared_test_methods::{stripSpace, toBitArray, toBooleanArray}, - AztecDetectorResult::AztecDetectorRXingResult, }, BarcodeFormat, EncodeHintType, EncodeHintValue, RXingResultPoint, }; @@ -810,7 +810,7 @@ fn testModeMessageComplex(compact: bool, layers: u32, words: u32, expected: &str fn testStuffBits(wordSize: usize, bits: &str, expected: &str) { let indata = toBitArray(bits); - let stuffed = aztec_encoder::stuffBits(&indata, wordSize); + let stuffed = aztec_encoder::stuffBits(&indata, wordSize).unwrap(); assert_eq!( stripSpace(expected), stripSpace(&stuffed.to_string()), diff --git a/src/aztec/AztecDetectorResult.rs b/src/aztec/aztec_detector_result.rs similarity index 96% rename from src/aztec/AztecDetectorResult.rs rename to src/aztec/aztec_detector_result.rs index 7275aee..8579347 100644 --- a/src/aztec/AztecDetectorResult.rs +++ b/src/aztec/aztec_detector_result.rs @@ -33,7 +33,7 @@ use crate::{ */ pub struct AztecDetectorRXingResult { bits: BitMatrix, - points: Vec, + points: [RXingResultPoint; 4], compact: bool, nbDatablocks: u32, nbLayers: u32, @@ -59,7 +59,7 @@ impl AztecDetectorRXingResult { ) -> Self { Self { bits, - points: points.to_vec(), + points, compact, nbDatablocks, nbLayers, diff --git a/src/aztec/aztec_reader.rs b/src/aztec/aztec_reader.rs index cfa8986..043b208 100644 --- a/src/aztec/aztec_reader.rs +++ b/src/aztec/aztec_reader.rs @@ -130,8 +130,4 @@ impl Reader for AztecReader { Ok(result) } - - fn reset(&mut self) { - // do nothing - } } diff --git a/src/aztec/aztec_writer.rs b/src/aztec/aztec_writer.rs index 7b3e9a0..0994120 100644 --- a/src/aztec/aztec_writer.rs +++ b/src/aztec/aztec_writer.rs @@ -53,36 +53,25 @@ impl Writer for AztecWriter { let mut charset = None; // Do not add any ECI code by default let mut ecc_percent = aztec_encoder::DEFAULT_EC_PERCENT; let mut layers = aztec_encoder::DEFAULT_AZTEC_LAYERS; - if hints.contains_key(&EncodeHintType::CHARACTER_SET) { - if let EncodeHintValue::CharacterSet(cset_name) = hints - .get(&EncodeHintType::CHARACTER_SET) - .expect("already knonw presence") - { - if cset_name != "iso-8859-1" { - charset = Some(encoding::label::encoding_from_whatwg_label(cset_name).unwrap()); - } - // dbg!(cset_name); - // dbg!(encoding::label::encoding_from_whatwg_label(cset_name).unwrap().name(), encoding::label::encoding_from_whatwg_label(cset_name).unwrap().whatwg_name()); + if let Some(EncodeHintValue::CharacterSet(cset_name)) = + hints.get(&EncodeHintType::CHARACTER_SET) + { + if cset_name.to_lowercase() != "iso-8859-1" { + charset = Some( + encoding::label::encoding_from_whatwg_label(cset_name) + .ok_or(Exceptions::IllegalArgumentException(None))?, + ); } - // charset = Charset.forName(hints.get(EncodeHintType.CHARACTER_SET).toString()); } - if hints.contains_key(&EncodeHintType::ERROR_CORRECTION) { - if let EncodeHintValue::ErrorCorrection(ecc_level) = hints - .get(&EncodeHintType::ERROR_CORRECTION) - .expect("key exists") - { - ecc_percent = ecc_level.parse().expect("should convert to int"); - } - // eccPercent = Integer.parseInt(hints.get(EncodeHintType::ERROR_CORRECTION).toString()); + if let Some(EncodeHintValue::ErrorCorrection(ecc_level)) = + hints.get(&EncodeHintType::ERROR_CORRECTION) + { + ecc_percent = ecc_level.parse().unwrap_or(23); } - if hints.contains_key(&EncodeHintType::AZTEC_LAYERS) { - if let EncodeHintValue::AztecLayers(az_layers) = hints - .get(&EncodeHintType::AZTEC_LAYERS) - .expect("key exists") - { - layers = *az_layers; - } - // layers = Integer.parseInt(hints.get(EncodeHintType.AZTEC_LAYERS).toString()); + if let Some(EncodeHintValue::AztecLayers(az_layers)) = + hints.get(&EncodeHintType::AZTEC_LAYERS) + { + layers = *az_layers; } encode( contents, @@ -121,9 +110,7 @@ fn encode( fn renderRXingResult(code: &AztecCode, width: u32, height: u32) -> Result { let input = code.getMatrix(); - // if input == null { - // throw new IllegalStateException(); - // } + let input_width = input.getWidth(); let input_height = input.getHeight(); let output_width = width.max(input_width); @@ -152,13 +139,5 @@ fn renderRXingResult(code: &AztecCode, width: u32, height: u32) -> ResultThe main class which implements Aztec Code decoding -- as opposed to locating and extracting @@ -164,7 +164,7 @@ fn get_encoded_data(corrected_bits: &[bool]) -> Result { result.push_str( &encdr .decode(&decoded_bytes, encoding::DecoderTrap::Strict) - .unwrap(), + .map_err(|a| Exceptions::IllegalStateException(Some(a.to_string())))?, ); decoded_bytes.clear(); @@ -210,8 +210,17 @@ fn get_encoded_data(corrected_bits: &[bool]) -> Result { // That's including when that mode is a shift. // Our test case dlusbs.png for issue #642 exercises that. latch_table = shift_table; // Latch the current mode, so as to return to Upper after U/S B/S - shift_table = getTable(str.chars().nth(5).unwrap()); - if str.chars().nth(6).unwrap() == 'L' { + shift_table = getTable( + str.chars() + .nth(5) + .ok_or(Exceptions::IndexOutOfBoundsException(None))?, + ); + if str + .chars() + .nth(6) + .ok_or(Exceptions::IndexOutOfBoundsException(None))? + == 'L' + { latch_table = shift_table; } } else { diff --git a/src/aztec/detector.rs b/src/aztec/detector.rs index 7820487..007ea5d 100644 --- a/src/aztec/detector.rs +++ b/src/aztec/detector.rs @@ -26,7 +26,7 @@ use crate::{ RXingResultPoint, ResultPoint, }; -use super::AztecDetectorResult::AztecDetectorRXingResult; +use super::aztec_detector_result::AztecDetectorRXingResult; const EXPECTED_CORNER_BITS: [u32; 4] = [ 0xee0, // 07340 XXX .XX X.. ... @@ -731,11 +731,11 @@ impl<'a> Detector<'_> { } fn distance_points(a: &Point, b: &Point) -> f32 { - MathUtils::distance_int(a.get_x(), a.get_y(), b.get_x(), b.get_y()) + MathUtils::distance(a.get_x(), a.get_y(), b.get_x(), b.get_y()) } fn distance(a: &RXingResultPoint, b: &RXingResultPoint) -> f32 { - MathUtils::distance_float(a.getX(), a.getY(), b.getX(), b.getY()) + MathUtils::distance(a.getX(), a.getY(), b.getX(), b.getY()) } fn get_dimension(&self) -> u32 { diff --git a/src/aztec/encoder/aztec_encoder.rs b/src/aztec/encoder/aztec_encoder.rs index e5d7fe6..e63d5ba 100644 --- a/src/aztec/encoder/aztec_encoder.rs +++ b/src/aztec/encoder/aztec_encoder.rs @@ -185,7 +185,7 @@ pub fn encode_bytes_with_charset( total_bits_in_layer_var = total_bits_in_layer(layers, compact); word_size = WORD_SIZE[layers as usize]; let usable_bits_in_layers = total_bits_in_layer_var - (total_bits_in_layer_var % word_size); - stuffed_bits = stuffBits(&bits, word_size as usize); + stuffed_bits = stuffBits(&bits, word_size as usize)?; if stuffed_bits.getSize() as u32 + ecc_bits > usable_bits_in_layers { return Err(Exceptions::IllegalArgumentException(Some( "Data to large for user specified layer".to_owned(), @@ -222,7 +222,7 @@ pub fn encode_bytes_with_charset( // wordSize has changed if stuffed_bits.getSize() == 0 || word_size != WORD_SIZE[layers as usize] { word_size = WORD_SIZE[layers as usize]; - stuffed_bits = stuffBits(&bits, word_size as usize); + stuffed_bits = stuffBits(&bits, word_size as usize)?; } let usable_bits_in_layers = total_bits_in_layer_var - (total_bits_in_layer_var % word_size); @@ -267,7 +267,7 @@ pub fn encode_bytes_with_charset( alignmentMap[origCenter + i] = center + newOffset + 1; } } - let mut matrix = BitMatrix::with_single_dimension(matrixSize); + let mut matrix = BitMatrix::with_single_dimension(matrixSize)?; // dbg!(matrix.to_string()); @@ -307,13 +307,9 @@ pub fn encode_bytes_with_charset( rowOffset += rowSize * 8; } - // dbg!(matrix.to_string()); - // draw mode message drawModeMessage(&mut matrix, compact, matrixSize, modeMessage); - // dbg!(matrix.to_string()); - // draw alignment marks if compact { drawBullsEye(&mut matrix, matrixSize / 2, 5); @@ -385,20 +381,12 @@ pub fn generateModeMessage( ) -> Result { let mut mode_message = BitArray::new(); if compact { - mode_message - .appendBits(layers - 1, 2) - .expect("should append"); - mode_message - .appendBits(messageSizeInWords - 1, 6) - .expect("should append"); + mode_message.appendBits(layers - 1, 2)?; + mode_message.appendBits(messageSizeInWords - 1, 6)?; mode_message = generateCheckWords(&mode_message, 28, 4)?; } else { - mode_message - .appendBits(layers - 1, 5) - .expect("should append"); - mode_message - .appendBits(messageSizeInWords - 1, 11) - .expect("should append"); + mode_message.appendBits(layers - 1, 5)?; + mode_message.appendBits(messageSizeInWords - 1, 11)?; mode_message = generateCheckWords(&mode_message, 40, 4)?; } Ok(mode_message) @@ -407,7 +395,7 @@ pub fn generateModeMessage( fn drawModeMessage(matrix: &mut BitMatrix, compact: bool, matrixSize: u32, modeMessage: BitArray) { let center = matrixSize / 2; if compact { - for i in 0..7usize { + for i in 0..7_usize { // for (int i = 0; i < 7; i++) { let offset = (center as usize - 3 + i) as u32; if modeMessage.get(i) { @@ -424,7 +412,7 @@ fn drawModeMessage(matrix: &mut BitMatrix, compact: bool, matrixSize: u32, modeM } } } else { - for i in 0..10usize { + for i in 0..10_usize { // for (int i = 0; i < 10; i++) { let offset = (center as usize - 5 + i + i / 5) as u32; if modeMessage.get(i) { @@ -450,13 +438,13 @@ fn generateCheckWords( ) -> Result { // bitArray is guaranteed to be a multiple of the wordSize, so no padding needed let message_size_in_words = bitArray.getSize() / wordSize; - let mut rs = ReedSolomonEncoder::new(getGF(wordSize)?); + let mut rs = ReedSolomonEncoder::new(getGF(wordSize)?)?; let total_words = totalBits / wordSize; let mut message_words = bitsToWords(bitArray, wordSize, total_words); rs.encode(&mut message_words, total_words - message_size_in_words)?; let start_pad = totalBits % wordSize; let mut message_bits = BitArray::new(); - message_bits.appendBits(0, start_pad).expect("must append"); + message_bits.appendBits(0, start_pad)?; for message_word in message_words { // for (int messageWord : messageWords) { message_bits.appendBits(message_word as u32, wordSize)? @@ -498,23 +486,9 @@ fn getGF(wordSize: usize) -> Result { "Unsupported word size {wordSize}" )))), } - // switch (wordSize) { - // case 4: - // return GenericGF.AZTEC_PARAM; - // case 6: - // return GenericGF.AZTEC_DATA_6; - // case 8: - // return GenericGF.AZTEC_DATA_8; - // case 10: - // return GenericGF.AZTEC_DATA_10; - // case 12: - // return GenericGF.AZTEC_DATA_12; - // default: - // throw new IllegalArgumentException("Unsupported word size " + wordSize); - // } } -pub fn stuffBits(bits: &BitArray, word_size: usize) -> BitArray { +pub fn stuffBits(bits: &BitArray, word_size: usize) -> Result { let mut out = BitArray::new(); let n = bits.getSize() as isize; @@ -530,21 +504,20 @@ pub fn stuffBits(bits: &BitArray, word_size: usize) -> BitArray { } } if (word & mask) == mask { - out.appendBits(word & mask, word_size).unwrap(); + out.appendBits(word & mask, word_size)?; i -= 1; } else if (word & mask) == 0 { - out.appendBits(word | 1, word_size).unwrap(); + out.appendBits(word | 1, word_size)?; i -= 1; } else { - out.appendBits(word, word_size).unwrap(); + out.appendBits(word, word_size)?; } i += word_size as isize; } - out + Ok(out) } fn total_bits_in_layer(layers: u32, compact: bool) -> u32 { ((if compact { 88 } else { 112 }) + 16 * layers) * layers - // return ((compact ? 88 : 112) + 16 * layers) * layers; } diff --git a/src/aztec/encoder/binary_shift_token.rs b/src/aztec/encoder/binary_shift_token.rs index 4160aa6..a8b8333 100644 --- a/src/aztec/encoder/binary_shift_token.rs +++ b/src/aztec/encoder/binary_shift_token.rs @@ -16,7 +16,7 @@ use std::fmt; -use crate::common::BitArray; +use crate::{common::BitArray, Exceptions}; #[derive(Debug, PartialEq, Eq, Clone)] pub struct BinaryShiftToken { @@ -32,28 +32,27 @@ impl BinaryShiftToken { } } - pub fn appendTo(&self, bit_array: &mut BitArray, text: &[u8]) { + pub fn appendTo(&self, bit_array: &mut BitArray, text: &[u8]) -> Result<(), Exceptions> { let bsbc = self.binary_shift_byte_count as usize; for i in 0..bsbc { // for (int i = 0; i < bsbc; i++) { if i == 0 || (i == 31 && bsbc <= 62) { // We need a header before the first character, and before // character 31 when the total byte code is <= 62 - bit_array.appendBits(31, 5).unwrap(); // BINARY_SHIFT + bit_array.appendBits(31, 5)?; // BINARY_SHIFT if bsbc > 62 { - bit_array.appendBits(bsbc as u32 - 31, 16).unwrap(); + bit_array.appendBits(bsbc as u32 - 31, 16)?; } else if i == 0 { // 1 <= binaryShiftByteCode <= 62 - bit_array.appendBits(bsbc.min(31) as u32, 5).unwrap(); + bit_array.appendBits(bsbc.min(31) as u32, 5)?; } else { // 32 <= binaryShiftCount <= 62 and i == 31 - bit_array.appendBits(bsbc as u32 - 31, 5).unwrap(); + bit_array.appendBits(bsbc as u32 - 31, 5)?; } } - bit_array - .appendBits(text[self.binary_shift_start as usize + i].into(), 8) - .expect("should never fail to append"); + bit_array.appendBits(text[self.binary_shift_start as usize + i].into(), 8)?; } + Ok(()) } // @Override diff --git a/src/aztec/encoder/high_level_encoder.rs b/src/aztec/encoder/high_level_encoder.rs index 0c1b562..feaf12c 100644 --- a/src/aztec/encoder/high_level_encoder.rs +++ b/src/aztec/encoder/high_level_encoder.rs @@ -324,7 +324,7 @@ impl HighLevelEncoder { // Convert it to a bit array, and return. // dbg!(min_state.clone().toBitArray(&self.text).to_string()); - Ok(min_state.toBitArray(&self.text)) + min_state.toBitArray(&self.text) } // We update a set of states for a new character by updating each state diff --git a/src/aztec/encoder/simple_token.rs b/src/aztec/encoder/simple_token.rs index 97b1fde..3846a02 100644 --- a/src/aztec/encoder/simple_token.rs +++ b/src/aztec/encoder/simple_token.rs @@ -16,7 +16,7 @@ use std::fmt; -use crate::common::BitArray; +use crate::{common::BitArray, Exceptions}; #[derive(Debug, PartialEq, Eq, Clone)] pub struct SimpleToken { @@ -33,10 +33,8 @@ impl SimpleToken { } } - pub fn appendTo(&self, bit_array: &mut BitArray, _text: &[u8]) { - bit_array - .appendBits(self.value as u32, self.bit_count as usize) - .expect("append should never fail"); + pub fn appendTo(&self, bit_array: &mut BitArray, _text: &[u8]) -> Result<(), Exceptions> { + bit_array.appendBits(self.value as u32, self.bit_count as usize) } // @Override diff --git a/src/aztec/encoder/state.rs b/src/aztec/encoder/state.rs index ecd3780..de84926 100644 --- a/src/aztec/encoder/state.rs +++ b/src/aztec/encoder/state.rs @@ -85,9 +85,11 @@ impl State { ))); // throw new IllegalArgumentException("ECI code must be between 0 and 999999"); } else { - let eci_digits = encoding::all::ISO_8859_1 + let Ok(eci_digits) = encoding::all::ISO_8859_1 .encode(&format!("{eci}"), encoding::EncoderTrap::Strict) - .unwrap(); + else { + return Err(Exceptions::IllegalArgumentException(None)) + }; // let eciDigits = Integer.toString(eci).getBytes(StandardCharsets.ISO_8859_1); token.add(eci_digits.len() as i32, 3); // 1-6: number of ECI digits for eci_digit in &eci_digits { @@ -205,7 +207,7 @@ impl State { new_mode_bit_count <= other.bit_count } - pub fn toBitArray(self, text: &[u8]) -> BitArray { + pub fn toBitArray(self, text: &[u8]) -> Result { let mut symbols = Vec::new(); let tok = self.endBinaryShift(text.len() as u32).token; for tkn in tok.into_iter() { @@ -223,22 +225,22 @@ impl State { for symbol in symbols.into_iter().rev() { // for i in (0..symbols.len()).rev() { // for (int i = symbols.size() - 1; i >= 0; i--) { - symbol.appendTo(&mut bit_array, text); + symbol.appendTo(&mut bit_array, text)?; } - bit_array + Ok(bit_array) } + #[inline(always)] fn calculate_binary_shift_cost(binary_shift_byte_count: u32) -> u32 { if binary_shift_byte_count > 62 { - return 21; // B/S with extended length + 21 // B/S with extended length + } else if binary_shift_byte_count > 31 { + 20 // two B/S + } else if binary_shift_byte_count > 0 { + 10 // one B/S + } else { + 0 } - if binary_shift_byte_count > 31 { - return 20; // two B/S - } - if binary_shift_byte_count > 0 { - return 10; // one B/S - } - 0 } } diff --git a/src/aztec/encoder/token.rs b/src/aztec/encoder/token.rs index 131f91e..e798774 100644 --- a/src/aztec/encoder/token.rs +++ b/src/aztec/encoder/token.rs @@ -14,7 +14,7 @@ * limitations under the License. */ -use crate::common::BitArray; +use crate::{common::BitArray, Exceptions}; use super::{BinaryShiftToken, SimpleToken}; @@ -26,12 +26,14 @@ pub enum TokenType { } impl TokenType { - pub fn appendTo(&self, bit_array: &mut BitArray, text: &[u8]) { + pub fn appendTo(&self, bit_array: &mut BitArray, text: &[u8]) -> Result<(), Exceptions> { // let token = &self.tokens[self.current_pointer]; match self { TokenType::Simple(a) => a.appendTo(bit_array, text), TokenType::BinaryShift(a) => a.appendTo(bit_array, text), - TokenType::Empty => panic!("cannot appendTo on Empty final item"), + TokenType::Empty => Err(Exceptions::IllegalStateException(Some(String::from( + "cannot appendTo on Empty final item", + )))), } } } @@ -95,27 +97,6 @@ impl IntoIterator for Token { } } -// pub enum Token{ -// Simple(Rc), -// BinaryShift(), -// Empty, -// } - -// pub trait TokenTrait { -// fn getPrevious(&self)->&Token; - -// fn add(&self, value: i32, bitCount: u32) -> Token{ -// Token::Simple(Rc::new(SimpleToken::new(self, value, bitCount))) -// } - -// fn addBinaryShift(&self, start: i32, byteCount: u32) -> &Token; //{ -// // //int bitCount = (byteCount * 8) + (byteCount <= 31 ? 10 : byteCount <= 62 ? 20 : 21); -// // return new BinaryShiftToken(this, start, byteCount); -// // } - -// fn appendTo(&self, bitArray: BitArray, text: &[u8]); -// } - impl Default for Token { fn default() -> Self { Self::new() diff --git a/src/aztec/mod.rs b/src/aztec/mod.rs index 418da72..f355ef1 100644 --- a/src/aztec/mod.rs +++ b/src/aztec/mod.rs @@ -1,4 +1,4 @@ -mod AztecDetectorResult; +mod aztec_detector_result; mod aztec_reader; mod aztec_writer; pub mod decoder; diff --git a/src/binary_bitmap.rs b/src/binary_bitmap.rs index d59b421..2a737dc 100644 --- a/src/binary_bitmap.rs +++ b/src/binary_bitmap.rs @@ -78,6 +78,8 @@ impl BinaryBitmap { * may not apply sharpening. Therefore, a row from this matrix may not be identical to one * fetched using getBlackRow(), so don't mix and match between them. * + * Panics if the binarizer cannot be created. + * * @return The 2D array of bits for the image (true means black). * @throws NotFoundException if image can't be binarized to make a matrix */ @@ -99,6 +101,8 @@ impl BinaryBitmap { * may not apply sharpening. Therefore, a row from this matrix may not be identical to one * fetched using getBlackRow(), so don't mix and match between them. * + * Panics if the binarizer cannot be created. + * * @return The 2D array of bits for the image (true means black). * @throws NotFoundException if image can't be binarized to make a matrix */ @@ -125,6 +129,8 @@ impl BinaryBitmap { * Returns a new object with cropped image data. Implementations may keep a reference to the * original data rather than a copy. Only callable if isCropSupported() is true. * + * Panics if the binarizer cannot be created. + * * @param left The left coordinate, which must be in [0,getWidth()) * @param top The top coordinate, which must be in [0,getHeight()) * @param width The width of the rectangle to crop. @@ -140,10 +146,6 @@ impl BinaryBitmap { self.binarizer .createBinarizer(newSource.expect("new lum source expected")), ); - // Self { - // binarizer: self.binarizer.clone(), - // matrix: Some(self.getBlackMatrix().crop(top, left, height, width)), - // } } /** @@ -157,6 +159,8 @@ impl BinaryBitmap { * Returns a new object with rotated image data by 90 degrees counterclockwise. * Only callable if {@link #isRotateSupported()} is true. * + * Panics if the binarizer cannot be created. + * * @return A rotated version of this object. */ pub fn rotateCounterClockwise(&mut self) -> BinaryBitmap { @@ -165,19 +169,14 @@ impl BinaryBitmap { self.binarizer .createBinarizer(newSource.expect("new lum source expected")), ); - // let mut new_matrix = self.getBlackMatrix().clone(); - // new_matrix.rotate90(); - - // Self { - // binarizer: self.binarizer.clone(), - // matrix: Some(new_matrix), - // } } /** * Returns a new object with rotated image data by 45 degrees counterclockwise. * Only callable if {@link #isRotateSupported()} is true. * + * Panics if the binarizer cannot be created. + * * @return A rotated version of this object. */ pub fn rotateCounterClockwise45(&self) -> BinaryBitmap { diff --git a/src/buffered_image_luminance_source.rs b/src/buffered_image_luminance_source.rs index fcc9181..15851c3 100644 --- a/src/buffered_image_luminance_source.rs +++ b/src/buffered_image_luminance_source.rs @@ -54,46 +54,6 @@ impl BufferedImageLuminanceSource { width: usize, height: usize, ) -> Self { - // if image.getType() == BufferedImage.TYPE_BYTE_GRAY { - // this.image = image; - // } else { - // int sourceWidth = image.getWidth(); - // int sourceHeight = image.getHeight(); - // if (left + width > sourceWidth || top + height > sourceHeight) { - // throw new IllegalArgumentException("Crop rectangle does not fit within image data."); - // } - - // this.image = new BufferedImage(sourceWidth, sourceHeight, BufferedImage.TYPE_BYTE_GRAY); - - // WritableRaster raster = this.image.getRaster(); - // int[] buffer = new int[width]; - // for (int y = top; y < top + height; y++) { - // image.getRGB(left, y, width, 1, buffer, 0, sourceWidth); - // for (int x = 0; x < width; x++) { - // int pixel = buffer[x]; - - // // The color of fully-transparent pixels is irrelevant. They are often, technically, fully-transparent - // // black (0 alpha, and then 0 RGB). They are often used, of course as the "white" area in a - // // barcode image. Force any such pixel to be white: - // if ((pixel & 0xFF000000) == 0) { - // // white, so we know its luminance is 255 - // buffer[x] = 0xFF; - // } else { - // // .299R + 0.587G + 0.114B (YUV/YIQ for PAL and NTSC), - // // (306*R) >> 10 is approximately equal to R*0.299, and so on. - // // 0x200 >> 10 is 0.5, it implements rounding. - // buffer[x] = - // (306 * ((pixel >> 16) & 0xFF) + - // 601 * ((pixel >> 8) & 0xFF) + - // 117 * (pixel & 0xFF) + - // 0x200) >> 10; - // } - // } - // raster.setPixels(left, y, width, 1, buffer); - // } - - // } - let img = image.to_rgba8(); let mut raster: ImageBuffer<_, Vec<_>> = ImageBuffer::new(image.width(), image.height()); @@ -116,29 +76,6 @@ impl BufferedImageLuminanceSource { } } - // for pixel in img.pixels() { - // // The color of fully-transparent pixels is irrelevant. They are often, technically, fully-transparent - // // black (0 alpha, and then 0 RGB). They are often used, of course as the "white" area in a - // // barcode image. Force any such pixel to be white: - // let [red,green,blue,alpha] = pixel.0; - // if (alpha & 0xFF) == 0 { - // // white, so we know its luminance is 255 - // raster.push(0xFF); - // // buffer[x] = 0xFF; - // } else { - // // .299R + 0.587G + 0.114B (YUV/YIQ for PAL and NTSC), - // // (306*R) >> 10 is approximately equal to R*0.299, and so on. - // // 0x200 >> 10 is 0.5, it implements rounding. - // raster.push(( - // (306 * ((red as u32 >> 16) & 0xFF) + - // 601 * ((green as u32 >> 8) & 0xFF) + - // 117 * (blue as u32 & 0xFF) + - // 0x200) >> 10) as u8); - // } - // } - - // let ib:ImageBuffer, Vec> = ImageBuffer::from_raw(image.width() , image.height(), raster).unwrap(); - Self { image: Rc::new(DynamicImage::from(raster)), width, @@ -146,14 +83,6 @@ impl BufferedImageLuminanceSource { left, top, } - - // Self { - // image: DynamicImage::from(image.to_luma8()), - // width: width, - // height: height, - // left: left, - // top: top, - // } } } @@ -161,20 +90,19 @@ impl LuminanceSource for BufferedImageLuminanceSource { fn getRow(&self, y: usize) -> Vec { let width = self.getWidth(); // - self.left as usize; - let pixels: Vec = self - .image - .as_luma8() - .unwrap() - .rows() - .nth(y + self.top as usize) - .unwrap() - .skip(self.left as usize) - .take(width) - .map(|&p| p.0[0]) - .collect(); - - // The underlying raster of image consists of bytes with the luminance values - // row[..width].clone_from_slice(&pixels[..]); + let pixels: Vec = || -> Option> { + Some( + self.image + .as_luma8()? + .rows() + .nth(y + self.top as usize)? + .skip(self.left as usize) + .take(width) + .map(|&p| p.0[0]) + .collect(), + ) + }() + .unwrap_or_default(); pixels } @@ -221,7 +149,6 @@ impl LuminanceSource for BufferedImageLuminanceSource { } fn invert(&mut self) { - // self.image.borrow_mut().invert(); let mut img = (*self.image).clone(); img.invert(); self.image = Rc::new(img); @@ -238,18 +165,7 @@ impl LuminanceSource for BufferedImageLuminanceSource { width: usize, height: usize, ) -> Result, crate::exceptions::Exceptions> { - // Ok(Box::new(BufferedImageLuminanceSource::with_details( - // self.image - // .crop_imm(left as u32, top as u32, width as u32, height as u32), - // self.left + left as u32, - // self.top + top as u32, - // width, - // height, - // ))) Ok(Box::new(Self { - // image: self - // .image - // .crop_imm(left as u32, top as u32, width as u32, height as u32), image: self.image.clone(), width, height, @@ -265,9 +181,6 @@ impl LuminanceSource for BufferedImageLuminanceSource { fn rotateCounterClockwise( &self, ) -> Result, crate::exceptions::Exceptions> { - // Ok(Box::new(BufferedImageLuminanceSource::new( - // self.image.rotate270(), - // ))) let img = self.image.rotate270(); Ok(Box::new(Self { width: img.width() as usize, @@ -290,7 +203,6 @@ impl LuminanceSource for BufferedImageLuminanceSource { let new_img = DynamicImage::from(img); - // Ok(Box::new(BufferedImageLuminanceSource::new(new_img))) Ok(Box::new(Self { width: new_img.width() as usize, height: new_img.height() as usize, diff --git a/src/client/result/AddressBookAUResultParser.rs b/src/client/result/AddressBookAUResultParser.rs index 42fd40d..242c868 100644 --- a/src/client/result/AddressBookAUResultParser.rs +++ b/src/client/result/AddressBookAUResultParser.rs @@ -50,17 +50,10 @@ pub fn parse(result: &RXingResult) -> Option { let note = ResultParser::matchSinglePrefixedField("MEMORY:", &rawText, '\r', false) .unwrap_or_default(); let address = ResultParser::matchSinglePrefixedField("ADD:", &rawText, '\r', true); - let addresses = if address.is_none() { - Vec::new() - } else { - vec![address?] - }; + let addresses = address.map_or_else(Vec::new, |add| vec![add]); + if let Ok(new_data) = AddressBookParsedRXingResult::with_details( - if let Some(nm) = ResultParser::maybeWrap(name) { - nm - } else { - Vec::new() - }, + ResultParser::maybeWrap(name).unwrap_or_default(), Vec::new(), pronunciation.unwrap_or_default(), phoneNumbers, @@ -90,10 +83,12 @@ fn matchMultipleValuePrefix(prefix: &str, rawText: &str) -> Vec { // for (int i = 1; i <= 3; i++) { let value = ResultParser::matchSinglePrefixedField(&format!("{prefix}{i}:"), rawText, '\r', true); - if value.is_none() { + + if let Some(value) = value { + values.push(value) + } else { break; } - values.push(value.unwrap()); } values diff --git a/src/client/result/AddressBookDoCoMoResultParser.rs b/src/client/result/AddressBookDoCoMoResultParser.rs index 639dc18..1ed4732 100644 --- a/src/client/result/AddressBookDoCoMoResultParser.rs +++ b/src/client/result/AddressBookDoCoMoResultParser.rs @@ -43,35 +43,32 @@ pub fn parse(result: &RXingResult) -> Option { if !rawText.starts_with("MECARD:") { return None; } - let rawName = ResultParser::match_do_co_mo_prefixed_field("N:", &rawText)?; + let rawName = ResultParser::match_docomo_prefixed_field("N:", &rawText)?; let name = parseName(&rawName[0]); - let pronunciation = - ResultParser::match_single_do_co_mo_prefixed_field("SOUND:", &rawText, true) - .unwrap_or_default(); - let phoneNumbers = - ResultParser::match_do_co_mo_prefixed_field("TEL:", &rawText).unwrap_or_default(); - let emails = - ResultParser::match_do_co_mo_prefixed_field("EMAIL:", &rawText).unwrap_or_default(); - let note = ResultParser::match_single_do_co_mo_prefixed_field("NOTE:", &rawText, false) + let pronunciation = ResultParser::match_single_docomo_prefixed_field("SOUND:", &rawText, true) .unwrap_or_default(); - let addresses = - ResultParser::match_do_co_mo_prefixed_field("ADR:", &rawText).unwrap_or_default(); - let mut birthday = ResultParser::match_single_do_co_mo_prefixed_field("BDAY:", &rawText, true) + let phoneNumbers = + ResultParser::match_docomo_prefixed_field("TEL:", &rawText).unwrap_or_default(); + let emails = ResultParser::match_docomo_prefixed_field("EMAIL:", &rawText).unwrap_or_default(); + let note = ResultParser::match_single_docomo_prefixed_field("NOTE:", &rawText, false) + .unwrap_or_default(); + let addresses = ResultParser::match_docomo_prefixed_field("ADR:", &rawText).unwrap_or_default(); + let mut birthday = ResultParser::match_single_docomo_prefixed_field("BDAY:", &rawText, true) .unwrap_or_default(); if !ResultParser::isStringOfDigits(&birthday, 8) { // No reason to throw out the whole card because the birthday is formatted wrong. birthday = String::default(); } - let urls = ResultParser::match_do_co_mo_prefixed_field("URL:", &rawText).unwrap_or_default(); + let urls = ResultParser::match_docomo_prefixed_field("URL:", &rawText).unwrap_or_default(); // Although ORG may not be strictly legal in MECARD, it does exist in VCARD and we might as well // honor it when found in the wild. - let org = ResultParser::match_single_do_co_mo_prefixed_field("ORG:", &rawText, true) + let org = ResultParser::match_single_docomo_prefixed_field("ORG:", &rawText, true) .unwrap_or_default(); if let Ok(new_adb) = AddressBookParsedRXingResult::with_details( - ResultParser::maybeWrap(Some(name))?, + ResultParser::maybeWrap(Some(name)).unwrap_or_default(), Vec::new(), pronunciation, phoneNumbers, @@ -100,12 +97,4 @@ fn parseName(name: &str) -> String { } else { name.to_owned() } - // let comma = name.indexOf(','); - // if (comma >= 0) { - // // Format may be last,first; switch it around - // return name.substring(comma + 1) + ' ' + name.substring(0, comma); - // } - // return name; } - -// } diff --git a/src/client/result/BizcardResultParser.rs b/src/client/result/BizcardResultParser.rs index 83fac40..da34a52 100644 --- a/src/client/result/BizcardResultParser.rs +++ b/src/client/result/BizcardResultParser.rs @@ -41,36 +41,36 @@ pub fn parse(result: &RXingResult) -> Option { return None; } - let firstName = ResultParser::match_single_do_co_mo_prefixed_field("N:", &rawText, true) - .unwrap_or_default(); - let lastName = ResultParser::match_single_do_co_mo_prefixed_field("X:", &rawText, true) - .unwrap_or_default(); + let firstName = + ResultParser::match_single_docomo_prefixed_field("N:", &rawText, true).unwrap_or_default(); + let lastName = + ResultParser::match_single_docomo_prefixed_field("X:", &rawText, true).unwrap_or_default(); let fullName = buildName(&firstName, &lastName); - let title = ResultParser::match_single_do_co_mo_prefixed_field("T:", &rawText, true) - .unwrap_or_default(); - let org = ResultParser::match_single_do_co_mo_prefixed_field("C:", &rawText, true) - .unwrap_or_default(); - let addresses = ResultParser::match_do_co_mo_prefixed_field("A:", &rawText); - let phoneNumber1 = ResultParser::match_single_do_co_mo_prefixed_field("B:", &rawText, true) - .unwrap_or_default(); - let phoneNumber2 = ResultParser::match_single_do_co_mo_prefixed_field("M:", &rawText, true) - .unwrap_or_default(); - let phoneNumber3 = ResultParser::match_single_do_co_mo_prefixed_field("F:", &rawText, true) - .unwrap_or_default(); - let email = ResultParser::match_single_do_co_mo_prefixed_field("E:", &rawText, true) - .unwrap_or_default(); + let title = + ResultParser::match_single_docomo_prefixed_field("T:", &rawText, true).unwrap_or_default(); + let org = + ResultParser::match_single_docomo_prefixed_field("C:", &rawText, true).unwrap_or_default(); + let addresses = ResultParser::match_docomo_prefixed_field("A:", &rawText); + let phoneNumber1 = + ResultParser::match_single_docomo_prefixed_field("B:", &rawText, true).unwrap_or_default(); + let phoneNumber2 = + ResultParser::match_single_docomo_prefixed_field("M:", &rawText, true).unwrap_or_default(); + let phoneNumber3 = + ResultParser::match_single_docomo_prefixed_field("F:", &rawText, true).unwrap_or_default(); + let email = + ResultParser::match_single_docomo_prefixed_field("E:", &rawText, true).unwrap_or_default(); if let Ok(adb) = AddressBookParsedRXingResult::with_details( - ResultParser::maybeWrap(Some(fullName))?, + ResultParser::maybeWrap(Some(fullName)).unwrap_or_default(), Vec::new(), String::default(), buildPhoneNumbers(phoneNumber1, phoneNumber2, phoneNumber3), Vec::new(), - ResultParser::maybeWrap(Some(email))?, + ResultParser::maybeWrap(Some(email)).unwrap_or_default(), Vec::new(), String::default(), String::default(), - addresses?, + addresses.unwrap_or_default(), Vec::new(), org, String::default(), @@ -82,23 +82,6 @@ pub fn parse(result: &RXingResult) -> Option { } else { None } - - // return new AddressBookParsedRXingResult(maybeWrap(fullName), - // null, - // null, - // buildPhoneNumbers(phoneNumber1, phoneNumber2, phoneNumber3), - // null, - // maybeWrap(email), - // null, - // null, - // null, - // addresses, - // null, - // org, - // null, - // title, - // null, - // null); } fn buildPhoneNumbers(number1: String, number2: String, number3: String) -> Vec { diff --git a/src/client/result/BookmarkDoCoMoResultParser.rs b/src/client/result/BookmarkDoCoMoResultParser.rs index 3ad6d3e..d5b98f4 100644 --- a/src/client/result/BookmarkDoCoMoResultParser.rs +++ b/src/client/result/BookmarkDoCoMoResultParser.rs @@ -30,20 +30,16 @@ pub fn parse(result: &RXingResult) -> Option { if !rawText.starts_with("MEBKM:") { return None; } - let title = ResultParser::match_single_do_co_mo_prefixed_field("TITLE:", rawText, true); - let rawUri = ResultParser::match_do_co_mo_prefixed_field("URL:", rawText); - rawUri.as_ref()?; - let uri = rawUri?[0].clone(); - if URIResultParser::is_basically_valid_uri(&uri) { + let title = ResultParser::match_single_docomo_prefixed_field("TITLE:", rawText, true); + let rawUri = ResultParser::match_docomo_prefixed_field("URL:", rawText)?; + + let uri = &rawUri[0]; + if URIResultParser::is_basically_valid_uri(uri) { Some(ParsedClientResult::URIResult(URIParsedRXingResult::new( - uri, + uri.to_string(), title.unwrap_or_default(), ))) } else { None } - - // return URIRXingResultParser.isBasicallyValidURI(uri) ? new URIParsedRXingResult(uri, title) : null; } - -// } diff --git a/src/client/result/CalendarParsedResult.rs b/src/client/result/CalendarParsedResult.rs index 16c50ba..5363b52 100644 --- a/src/client/result/CalendarParsedResult.rs +++ b/src/client/result/CalendarParsedResult.rs @@ -112,7 +112,7 @@ impl CalendarParsedRXingResult { ) -> Result { let start = Self::parseDate(startString.clone())?; let end = if endString.is_empty() { - let durationMS = Self::parseDurationMS(&durationString); + let durationMS = Self::parseDurationMS(&durationString)?; if durationMS < 0i64 { -1i64 } else { @@ -165,7 +165,6 @@ impl CalendarParsedRXingResult { * @throws ParseException if not able to parse as a date */ fn parseDate(when: String) -> Result { - // let date_time_regex = Regex::new(DATE_TIME).unwrap(); if !DATE_TIME.is_match(&when) { return Err(Exceptions::ParseException(Some(when))); } @@ -178,37 +177,23 @@ impl CalendarParsedRXingResult { // http://code.google.com/p/android/issues/detail?id=8330 return match Utc.datetime_from_str(&format!("{}T000000Z", &when,), date_format_string) { Ok(dtm) => Ok(dtm.timestamp()), - Err(e) => panic!("{}", e), - // Err(e) => Err(Exceptions::ParseException(format!( - // "couldn't parse string: {}", - // e - // ))), + Err(e) => Err(Exceptions::ParseException(Some(e.to_string()))), }; - // let dtm = DateTime::parse_from_str(&when, date_format_string).unwrap(); - // let dtm = dtm.with_timezone(&Utc); - - // // format.setTimeZone(TimeZone.getTimeZone("GMT")); - // // return format.parse(when).getTime(); - // return Ok(dtm.timestamp()); } // The when string can be local time, or UTC if it ends with a Z - if when.len() == 16 && when.chars().nth(15).unwrap() == 'Z' { + if when.len() == 16 + && when + .chars() + .nth(15) + .ok_or(Exceptions::IndexOutOfBoundsException(None))? + == 'Z' + { return match Utc.datetime_from_str(&when, "%Y%m%dT%H%M%SZ") { Ok(dtm) => Ok(dtm.with_timezone(&Utc).timestamp()), Err(e) => Err(Exceptions::ParseException(Some(format!( "couldn't parse string: {e}" )))), }; - // let dtm = DateTime::parse_from_str(&when, "%Y%m%dT%H%M%S").unwrap().with_timezone(&Utc); - // //let milliseconds = Self::parseDateTimeString(&when[0..15]); - // // Calendar calendar = new GregorianCalendar(); - // // // Account for time zone difference - // // milliseconds += calendar.get(Calendar.ZONE_OFFSET); - // // // Might need to correct for daylight savings time, but use target time since - // // // now might be in DST but not then, or vice versa - // // calendar.setTime(new Date(milliseconds)); - // // return milliseconds + calendar.get(Calendar.DST_OFFSET); - // return Ok(dtm.timestamp()); } // Try once more, with weird tz formatting if when.len() > 16 { @@ -258,9 +243,9 @@ impl CalendarParsedRXingResult { } } - fn parseDurationMS(durationString: &str) -> i64 { + fn parseDurationMS(durationString: &str) -> Result { if durationString.is_empty() { - return -1; + return Ok(-1); } // let regex = Regex::new(RFC2445_DURATION).unwrap(); if let Some(m) = RFC2445_DURATION.captures(durationString) { @@ -270,13 +255,16 @@ impl CalendarParsedRXingResult { // for (int i = 0; i < RFC2445_DURATION_FIELD_UNITS.length; i++) { let fieldValue = m.get(i + 1); if let Some(parseable) = fieldValue { - let z = parseable.as_str().parse::().unwrap(); + let z = parseable + .as_str() + .parse::() + .map_err(|e| Exceptions::ParseException(Some(e.to_string())))?; durationMS += unit * z; } } - durationMS + Ok(durationMS) } else { - -1 + Ok(-1) } // if (!m.matches()) { // return -1L; diff --git a/src/client/result/EmailAddressResultParser.rs b/src/client/result/EmailAddressResultParser.rs index 1c46bd9..7329a8e 100644 --- a/src/client/result/EmailAddressResultParser.rs +++ b/src/client/result/EmailAddressResultParser.rs @@ -41,8 +41,6 @@ use super::{ * @author Sean Owen */ pub fn parse(result: &RXingResult) -> Option { - // let comma_regex = Regex::new(",").unwrap(); - // private static final Pattern COMMA = Pattern.compile(","); let rawText = ResultParser::getMassagedText(result); if rawText.starts_with("mailto:") || rawText.starts_with("MAILTO:") { // If it starts with mailto:, assume it is definitely trying to be an email address @@ -55,11 +53,7 @@ pub fn parse(result: &RXingResult) -> Option { // hostEmail = hostEmail.substring(0, queryStart); // } // try { - let tmp = if let Ok(res) = ResultParser::urlDecode(hostEmail) { - res - } else { - return None; - }; + let tmp = ResultParser::urlDecode(hostEmail).ok()?; hostEmail = tmp.as_str(); // } catch (IllegalArgumentException iae) { // return null; diff --git a/src/client/result/EmailDoCoMoResultParser.rs b/src/client/result/EmailDoCoMoResultParser.rs index a7e4e62..335f02d 100644 --- a/src/client/result/EmailDoCoMoResultParser.rs +++ b/src/client/result/EmailDoCoMoResultParser.rs @@ -43,16 +43,16 @@ pub fn parse(result: &RXingResult) -> Option { if !rawText.starts_with("MATMSG:") { return None; } - let tos = ResultParser::match_do_co_mo_prefixed_field("TO:", &rawText)?; + let tos = ResultParser::match_docomo_prefixed_field("TO:", &rawText)?; for to in &tos { if !isBasicallyValidEmailAddress(to, &ATEXT_ALPHANUMERIC) { return None; } } - let subject = ResultParser::match_single_do_co_mo_prefixed_field("SUB:", &rawText, false) + let subject = ResultParser::match_single_docomo_prefixed_field("SUB:", &rawText, false) .unwrap_or_default(); - let body = ResultParser::match_single_do_co_mo_prefixed_field("BODY:", &rawText, false) + let body = ResultParser::match_single_docomo_prefixed_field("BODY:", &rawText, false) .unwrap_or_default(); Some(ParsedClientResult::EmailResult( EmailAddressParsedRXingResult::with_details(tos, Vec::new(), Vec::new(), subject, body), diff --git a/src/client/result/ExpandedProductParsedResult.rs b/src/client/result/ExpandedProductParsedResult.rs index 2ab37e4..f7ff148 100644 --- a/src/client/result/ExpandedProductParsedResult.rs +++ b/src/client/result/ExpandedProductParsedResult.rs @@ -110,47 +110,6 @@ impl ExpandedProductParsedRXingResult { } } - // @Override - // public boolean equals(Object o) { - // if (!(o instanceof ExpandedProductParsedRXingResult)) { - // return false; - // } - - // ExpandedProductParsedRXingResult other = (ExpandedProductParsedRXingResult) o; - - // return Objects.equals(productID, other.productID) - // && Objects.equals(sscc, other.sscc) - // && Objects.equals(lotNumber, other.lotNumber) - // && Objects.equals(productionDate, other.productionDate) - // && Objects.equals(bestBeforeDate, other.bestBeforeDate) - // && Objects.equals(expirationDate, other.expirationDate) - // && Objects.equals(weight, other.weight) - // && Objects.equals(weightType, other.weightType) - // && Objects.equals(weightIncrement, other.weightIncrement) - // && Objects.equals(price, other.price) - // && Objects.equals(priceIncrement, other.priceIncrement) - // && Objects.equals(priceCurrency, other.priceCurrency) - // && Objects.equals(uncommonAIs, other.uncommonAIs); - // } - - // @Override - // public int hashCode() { - // int hash = Objects.hashCode(productID); - // hash ^= Objects.hashCode(sscc); - // hash ^= Objects.hashCode(lotNumber); - // hash ^= Objects.hashCode(productionDate); - // hash ^= Objects.hashCode(bestBeforeDate); - // hash ^= Objects.hashCode(expirationDate); - // hash ^= Objects.hashCode(weight); - // hash ^= Objects.hashCode(weightType); - // hash ^= Objects.hashCode(weightIncrement); - // hash ^= Objects.hashCode(price); - // hash ^= Objects.hashCode(priceIncrement); - // hash ^= Objects.hashCode(priceCurrency); - // hash ^= Objects.hashCode(uncommonAIs); - // return hash; - // } - pub fn getRawText(&self) -> &str { &self.rawText } diff --git a/src/client/result/ExpandedProductParsedResultTestCase.rs b/src/client/result/ExpandedProductParsedResultTestCase.rs index 9f34096..f661462 100644 --- a/src/client/result/ExpandedProductParsedResultTestCase.rs +++ b/src/client/result/ExpandedProductParsedResultTestCase.rs @@ -24,16 +24,6 @@ * http://www.piramidepse.com/ */ -// package com.google.zxing.client.result; - -// import com.google.zxing.BarcodeFormat; -// import com.google.zxing.RXingResult; -// import org.junit.Assert; -// import org.junit.Test; - -// import java.util.HashMap; -// import java.util.Map; - // /** // * @author Antonio Manuel Benjumea Conde, Servinform, S.A. // * @author Agustín Delgado, Servinform, S.A. diff --git a/src/client/result/ExpandedProductResultParser.rs b/src/client/result/ExpandedProductResultParser.rs index 8549006..63eb29c 100644 --- a/src/client/result/ExpandedProductResultParser.rs +++ b/src/client/result/ExpandedProductResultParser.rs @@ -77,7 +77,7 @@ pub fn parse(result: &crate::RXingResult) -> Option { // return None; // } i += ai.len() + 2; - let value = findValue(i, &rawText); + let value = findValue(i, &rawText)?; i += value.len(); match ai.as_str() { "00" => sscc = value, @@ -260,13 +260,13 @@ fn findAIvalue(i: usize, rawText: &str) -> Option { Some(buf) } -fn findValue(i: usize, rawText: &str) -> String { +fn findValue(i: usize, rawText: &str) -> Option { let mut buf = String::new(); let rawTextAux = &rawText[i..]; for index in 0..rawTextAux.len() { // for (int index = 0; index < rawTextAux.length(); index++) { - let c = rawTextAux.chars().nth(index).unwrap(); + let c = rawTextAux.chars().nth(index)?; if c == '(' { // We look for a new AI. If it doesn't exist (ERROR), we continue // with the iteration @@ -281,5 +281,5 @@ fn findValue(i: usize, rawText: &str) -> String { buf.push(c); } } - buf + Some(buf) } diff --git a/src/client/result/GeoResultParser.rs b/src/client/result/GeoResultParser.rs index 1cee854..4e6ee07 100644 --- a/src/client/result/GeoResultParser.rs +++ b/src/client/result/GeoResultParser.rs @@ -50,31 +50,41 @@ pub fn parse(theRXingResult: &crate::RXingResult) -> Option() { - if !(-90.0..=90.0).contains(&laf64) { - return None; - } - laf64 - } else { - return None; - } - } else { + let latitude = captures.get(1)?.as_str().parse::().ok()?; + if !(-90.0..=90.0).contains(&latitude) { return None; - }; + } - let longitude = if let Some(lo) = captures.get(2) { - if let Ok(lof64) = lo.as_str().parse::() { - if !(-180.0..=180.0).contains(&lof64) { - return None; - } - lof64 - } else { - return None; - } - } else { + // let latitude = if let Some(la) = captures.get(1) { + // if let Ok(laf64) = la.as_str().parse::() { + // if !(-90.0..=90.0).contains(&laf64) { + // return None; + // } + // laf64 + // } else { + // return None; + // } + // } else { + // return None; + // }; + + let longitude = captures.get(2)?.as_str().parse::().ok()?; + if !(-180.0..=180.0).contains(&longitude) { return None; - }; + } + + // let longitude = if let Some(lo) = captures.get(2) { + // if let Ok(lof64) = lo.as_str().parse::() { + // if !(-180.0..=180.0).contains(&lof64) { + // return None; + // } + // lof64 + // } else { + // return None; + // } + // } else { + // return None; + // }; let altitude = if let Some(al) = captures.get(3) { if let Ok(alf64) = al.as_str().parse::() { @@ -88,28 +98,6 @@ pub fn parse(theRXingResult: &crate::RXingResult) -> Option 90.0 || latitude < -90.0) { - // // return null; - // // } - // // longitude = Double.parseDouble(matcher.group(2)); - // // if (longitude > 180.0 || longitude < -180.0) { - // // return null; - // // } - // // if (matcher.group(3) == null) { - // // altitude = 0.0; - // // } else { - // // altitude = Double.parseDouble(matcher.group(3)); - // // if (altitude < 0.0) { - // // return null; - // // } - // // } - // } catch (NumberFormatException ignored) { - // return null; - // } Some(ParsedClientResult::GeoResult(GeoParsedRXingResult::new( latitude, longitude, @@ -119,10 +107,4 @@ pub fn parse(theRXingResult: &crate::RXingResult) -> Option Option { { return None; } + let rawText = ResultParser::getMassagedText(result); if !ResultParser::isStringOfDigits(&rawText, rawText.len()) { return None; @@ -50,7 +51,7 @@ pub fn parse(result: &RXingResult) -> Option { // Expand UPC-E for purposes of searching if format == &BarcodeFormat::UPC_E && rawText.len() == 8 { // unimplemented!("UPCEReader is required to parse this"); - crate::oned::convertUPCEtoUPCA(&rawText) + crate::oned::convertUPCEtoUPCA(&rawText)? } else { rawText.clone() }; diff --git a/src/client/result/ResultParser.rs b/src/client/result/ResultParser.rs index a816e9a..26880da 100644 --- a/src/client/result/ResultParser.rs +++ b/src/client/result/ResultParser.rs @@ -102,11 +102,14 @@ const BYTE_ORDER_MARK: &str = "\u{feff}"; //private static final String BYTE_ORD // const EMPTY_STR_ARRAY: &'static str = ""; pub fn getMassagedText(result: &RXingResult) -> String { - let mut text = result.getText().clone(); - if text.starts_with(BYTE_ORDER_MARK) { - text = text[1..].to_owned(); - } - text + result + .getText() + .trim_start_matches(BYTE_ORDER_MARK) + .to_owned() + // if text.starts_with(BYTE_ORDER_MARK) { + // text = &text[1..]; + // } + // text.to_owned() } pub fn parse_result_with_parsers( @@ -181,19 +184,18 @@ pub fn maybe_append_string(value: &str, result: &mut String) { } pub fn maybe_append_multiple(value: &[String], result: &mut String) { - if !value.is_empty() { - for s in value { - // for (String s : value) { - if !s.is_empty() { - if !result.is_empty() { - result.push('\n'); - } - result.push_str(s); + for s in value { + // for (String s : value) { + if !s.is_empty() { + if !result.is_empty() { + result.push('\n'); } + result.push_str(s); } } } +#[inline(always)] pub fn maybeWrap(value: Option) -> Option> { if value.is_none() { None @@ -207,14 +209,12 @@ pub fn unescapeBackslash(escaped: &str) -> String { if backslash.is_none() { return escaped.to_owned(); } - let max = escaped.len(); - let mut unescaped = String::with_capacity(max - 1); + let max = escaped.chars().count(); let backslash = backslash.unwrap_or(0); - unescaped.push_str(&escaped[0..backslash]); + let mut unescaped = escaped.chars().take(backslash).collect::(); + unescaped.reserve(max - 1); let mut nextIsEscaped = false; - for i in backslash..max { - // for (int i = backslash; i < max; i++) { - let c = escaped.chars().nth(i).unwrap(); + for c in escaped.chars().skip(backslash) { if nextIsEscaped || c != '\\' { unescaped.push(c); nextIsEscaped = false; @@ -239,6 +239,7 @@ pub fn parseHexDigit(c: char) -> i32 { -1 } +#[inline(always)] pub fn isStringOfDigits(value: &str, length: usize) -> bool { !value.is_empty() && length > 0 && length == value.len() && DIGITS.is_match(value) } @@ -249,10 +250,10 @@ pub fn isSubstringOfDigits(value: &str, offset: usize, length: usize) -> bool { } let max = offset + length; - let sub_seq = &value[offset..max]; + let sub_seq: String = value.chars().skip(offset).take(length).collect(); //&value[offset..max]; - let is_a_match = if let Some(mtch) = DIGITS.find(sub_seq) { - mtch.start() == 0 && mtch.end() == sub_seq.len() + let is_a_match = if let Some(mtch) = DIGITS.find(&sub_seq) { + mtch.start() == 0 && mtch.end() == sub_seq.chars().count() } else { false }; @@ -266,16 +267,11 @@ pub fn parseNameValuePairs(uri: &str) -> Option> { let mut result = HashMap::with_capacity(3); let paramStart = paramStart.unwrap_or(0); - let sub_str = &uri[paramStart + 1..]; + let sub_str = &uri[paramStart + 1..]; // This is likely ok because we're looking for a specific single byte charaacter let list = sub_str.split(AMPERSAND); for keyValue in list { appendKeyValue(keyValue, &mut result); } - - // for keyValue in Self::AMPERSAND.split(uri[paramStart + 1..]) { - // // for (String keyValue : AMPERSAND.split(uri.substring(paramStart + 1))) { - // Self::appendKeyValue(keyValue, &mut result); - // } Some(result) } @@ -304,9 +300,9 @@ pub fn urlDecode(encoded: &str) -> Result { if let Ok(decoded) = decode(encoded) { Ok(decoded.to_string()) } else { - Err(Exceptions::IllegalStateException(Some( - "UnsupportedEncodingException".to_owned(), - ))) + Err(Exceptions::IllegalStateException(Some(String::from( + "UnsupportedEncodingException", + )))) } } @@ -329,7 +325,7 @@ pub fn matchPrefixedField( // if (i < 0) { // break; // } - i += prefix.len(); // Skip past this prefix we found to start + i += prefix.chars().count(); // Skip past this prefix we found to start let start = i; // Found the start of a match here let mut more = true; while more { @@ -337,7 +333,7 @@ pub fn matchPrefixedField( i += next_index; } else { // No terminating end character? uh, done. Set i such that loop terminates and break - i = rawText.len(); + i = rawText.chars().count(); more = false; continue; } @@ -411,11 +407,11 @@ pub fn matchSinglePrefixedField( // return matches == null ? null : matches[0]; } -pub fn match_do_co_mo_prefixed_field(prefix: &str, raw_text: &str) -> Option> { +pub fn match_docomo_prefixed_field(prefix: &str, raw_text: &str) -> Option> { matchPrefixedField(prefix, raw_text, ';', true) } -pub fn match_single_do_co_mo_prefixed_field( +pub fn match_single_docomo_prefixed_field( prefix: &str, raw_text: &str, trim: bool, @@ -426,7 +422,9 @@ pub fn match_single_do_co_mo_prefixed_field( #[cfg(test)] mod tests { use crate::{ - client::result::{ParsedClientResult, TextParsedRXingResult}, + client::result::{ + OtherParsedResult, ParsedClientResult, ParsedRXingResult, TextParsedRXingResult, + }, RXingResult, }; @@ -449,4 +447,32 @@ mod tests { .unwrap(); assert_eq!(p_res.to_string(), "parsed with parser"); } + + #[test] + fn test_other_parser() { + let result: RXingResult = RXingResult::new( + "text", + vec![12, 23, 54, 23], + Vec::new(), + crate::BarcodeFormat::EAN_13, + ); + let p_res = parse_result_with_parser(&result, |v| { + Some(ParsedClientResult::Other(OtherParsedResult::new(Box::new( + v.getRawBytes().clone(), + )))) + }) + .unwrap(); + + assert_eq!(p_res.getDisplayRXingResult(), "Any { .. }"); + + if let ParsedClientResult::Other(opr) = p_res { + if let Some(d) = opr.get_data().downcast_ref::>() { + assert_eq!(d, result.getRawBytes()); + } else { + panic!("did not get vec"); + } + } else { + panic!("did not get ParsedClientResult::Other"); + } + } } diff --git a/src/client/result/SMSMMSResultParser.rs b/src/client/result/SMSMMSResultParser.rs index c07e544..b796ccf 100644 --- a/src/client/result/SMSMMSResultParser.rs +++ b/src/client/result/SMSMMSResultParser.rs @@ -14,15 +14,6 @@ * limitations under the License. */ -// package com.google.zxing.client.result; - -// import com.google.zxing.RXingResult; - -// import java.util.ArrayList; -// import java.util.Collection; -// import java.util.List; -// import java.util.Map; - /** *

Parses an "sms:" URI result, which specifies a number to SMS. * See RFC 5724 on this.

@@ -38,7 +29,6 @@ * * @author Sean Owen */ -// public final class SMSMMSRXingResultParser extends RXingResultParser { use crate::RXingResult; use super::{ParsedClientResult, ResultParser, SMSParsedRXingResult}; @@ -121,21 +111,13 @@ fn add_number_via(numbers: &mut Vec, vias: &mut Vec, number_part return; } if let Some(number_end) = number_part.find(';') { - // if numberEnd < 0 { numbers.push(number_part[..number_end].to_string()); let maybe_via = &number_part[number_end + 1..]; - let via = if let Some(stripped) = maybe_via.strip_prefix("via=") { - stripped - } else { - "" - }; + let via = maybe_via.strip_prefix("via=").unwrap_or_default(); if !via.is_empty() { vias.push(via.to_owned()); } } else { numbers.push(number_part.to_owned()); - //vias.push(String::default()); } } - -// } diff --git a/src/client/result/SMSTOMMSTOResultParser.rs b/src/client/result/SMSTOMMSTOResultParser.rs index 22187f0..9895735 100644 --- a/src/client/result/SMSTOMMSTOResultParser.rs +++ b/src/client/result/SMSTOMMSTOResultParser.rs @@ -49,11 +49,7 @@ pub fn parse(result: &RXingResult) -> Option { body = &number[body_start + 1..]; number = &number[..body_start]; } - // let bodyStart = number.indexOf(':'); - // if (bodyStart >= 0) { - // body = number.substring(bodyStart + 1); - // number = number.substring(0, bodyStart); - // } + Some(ParsedClientResult::SMSResult( SMSParsedRXingResult::with_singles( number.to_owned(), @@ -62,5 +58,4 @@ pub fn parse(result: &RXingResult) -> Option { body.to_owned(), ), )) - // return new SMSParsedRXingResult(number, null, null, body); } diff --git a/src/client/result/SMTPResultParser.rs b/src/client/result/SMTPResultParser.rs index c70f841..f6e4844 100644 --- a/src/client/result/SMTPResultParser.rs +++ b/src/client/result/SMTPResultParser.rs @@ -44,16 +44,7 @@ pub fn parse(result: &RXingResult) -> Option { subject = &subject[..new_colon]; } } - // let colon = emailAddress.indexOf(':'); - // if (colon >= 0) { - // subject = emailAddress.substring(colon + 1); - // emailAddress = emailAddress.substring(0, colon); - // colon = subject.indexOf(':'); - // if (colon >= 0) { - // body = subject.substring(colon + 1); - // subject = subject.substring(0, colon); - // } - // } + Some(ParsedClientResult::EmailResult( EmailAddressParsedRXingResult::with_details( vec![emailAddress.to_owned()], @@ -63,9 +54,4 @@ pub fn parse(result: &RXingResult) -> Option { body.to_owned(), ), )) - // return new EmailAddressParsedRXingResult(new String[] {emailAddress}, - // null, - // null, - // subject, - // body); } diff --git a/src/client/result/URIParsedResult.rs b/src/client/result/URIParsedResult.rs index f1b3b2b..5f8cb47 100644 --- a/src/client/result/URIParsedResult.rs +++ b/src/client/result/URIParsedResult.rs @@ -92,7 +92,7 @@ impl URIParsedRXingResult { let nextSlash = if let Some(pos) = uri[start..].find('/') { pos + start } else { - uri.len() + uri.chars().count() }; // let nextSlash = uri.indexOf('/', start); // if (nextSlash < 0) { diff --git a/src/client/result/URIResultParser.rs b/src/client/result/URIResultParser.rs index 135cb1e..f55eab7 100644 --- a/src/client/result/URIResultParser.rs +++ b/src/client/result/URIResultParser.rs @@ -39,18 +39,16 @@ static ALLOWED_URI_CHARS: Lazy = Lazy::new(|| { }); static USER_IN_HOST: Lazy = Lazy::new(|| Regex::new(":/*([^/@]+)@[^/]+").expect("Regex patterns should always copile")); + +/// See http://www.ietf.org/rfc/rfc2396.txt static URL_WITH_PROTOCOL_PATTERN: Lazy = Lazy::new(|| Regex::new("[a-zA-Z][a-zA-Z0-9+-.]+:").unwrap()); + +/// (host name elements; allow up to say 6 domain elements), (maybe port), (query, path or nothing) static URL_WITHOUT_PROTOCOL_PATTERN: Lazy = Lazy::new(|| Regex::new("([a-zA-Z0-9\\-]+\\.){1,6}[a-zA-Z]{2,}(:\\d{1,5})?(/|\\?|$)").unwrap()); const ALLOWED_URI_CHARS_PATTERN: &str = "[-._~:/?#\\[\\]@!$&'()*+,;=%A-Za-z0-9]+"; -// const USER_IN_HOST: &'static str = ":/*([^/@]+)@[^/]+"; -/// See http://www.ietf.org/rfc/rfc2396.txt -// const URL_WITH_PROTOCOL_PATTERN: &'static str = "[a-zA-Z][a-zA-Z0-9+-.]+:"; -/// (host name elements; allow up to say 6 domain elements), (maybe port), (query, path or nothing) -// const URL_WITHOUT_PROTOCOL_PATTERN: &'static str = -// "([a-zA-Z0-9\\-]+\\.){1,6}[a-zA-Z]{2,}(:\\d{1,5})?(/|\\?|$)"; pub fn parse(result: &RXingResult) -> Option { let raw_text = ResultParser::getMassagedText(result); diff --git a/src/client/result/VCardResultParser.rs b/src/client/result/VCardResultParser.rs index 781b29f..d21617b 100644 --- a/src/client/result/VCardResultParser.rs +++ b/src/client/result/VCardResultParser.rs @@ -14,20 +14,6 @@ * limitations under the License. */ -// package com.google.zxing.client.result; - -// import com.google.zxing.RXingResult; - -// import java.io.ByteArrayOutputStream; -// import java.io.UnsupportedEncodingException; -// import java.net.URI; -// import java.nio.charset.StandardCharsets; -// import java.util.ArrayList; -// import java.util.Collection; -// import java.util.List; -// import java.util.regex.Matcher; -// import java.util.regex.Pattern; - use std::convert::TryFrom; use regex::Regex; diff --git a/src/client/result/VINParsedResultTestCase.rs b/src/client/result/VINParsedResultTestCase.rs index d0fe914..da6c1eb 100644 --- a/src/client/result/VINParsedResultTestCase.rs +++ b/src/client/result/VINParsedResultTestCase.rs @@ -14,13 +14,6 @@ * limitations under the License. */ -// package com.google.zxing.client.result; - -// import com.google.zxing.BarcodeFormat; -// import com.google.zxing.RXingResult; -// import org.junit.Assert; -// import org.junit.Test; - /** * Tests {@link VINParsedRXingResult}. */ diff --git a/src/client/result/VINResultParser.rs b/src/client/result/VINResultParser.rs index 60d0735..f35493d 100644 --- a/src/client/result/VINResultParser.rs +++ b/src/client/result/VINResultParser.rs @@ -14,13 +14,6 @@ * limitations under the License. */ -// package com.google.zxing.client.result; - -// import com.google.zxing.BarcodeFormat; -// import com.google.zxing.RXingResult; - -// import java.util.regex.Pattern; - use regex::Regex; use crate::{ @@ -46,26 +39,18 @@ pub fn parse(result: &RXingResult) -> Option { let raw_text_res = result.getText().trim(); let raw_text = IOQ_MATCHER.replace_all(raw_text_res, "").to_string(); - // rawText = IOQ.matcher(rawText).replaceAll("").trim(); + AZ09_MATCHER.find(&raw_text)?; - // if !AZ09.matcher(rawText).matches() { - // return null; - // } + let check_cs = check_checksum(&raw_text).unwrap_or(false); if !check_cs { return None; } let wmi = &raw_text[..3]; - // try { - // if (!checkChecksum(rawText)) { - // return null; - // } - // String wmi = rawText.substring(0, 3); + let country_code = country_code(wmi).unwrap_or(""); - let model_year = model_year(raw_text.chars().nth(9).unwrap_or('_')); - if model_year.is_err() { - return None; - } + let model_year = model_year(raw_text.chars().nth(9).unwrap_or('_')).ok(); + Some(ParsedClientResult::VINResult(VINParsedRXingResult::new( raw_text.to_owned(), wmi.to_owned(), @@ -73,22 +58,10 @@ pub fn parse(result: &RXingResult) -> Option { raw_text[9..17].to_owned(), country_code.to_owned(), raw_text[3..8].to_owned(), - model_year.unwrap(), - raw_text.chars().nth(10).unwrap(), + model_year?, + raw_text.chars().nth(10)?, raw_text[11..].to_owned(), ))) - // return new VINParsedRXingResult(rawText, - // wmi, - // rawText.substring(3, 9), - // rawText.substring(9, 17), - // countryCode(wmi), - // rawText.substring(3, 8), - // modelYear(rawText.charAt(9)), - // rawText.charAt(10), - // rawText.substring(11)); - // } catch (IllegalArgumentException iae) { - // return null; - // } } const IOQ: &str = "[IOQ]"; @@ -97,10 +70,17 @@ const AZ09: &str = "[A-Z0-9]{17}"; fn check_checksum(vin: &str) -> Result { let mut sum = 0; for i in 0..vin.len() { - // for (int i = 0; i < vin.length(); i++) { - sum += vin_position_weight(i + 1)? as u32 * vin_char_value(vin.chars().nth(i).unwrap())?; + sum += vin_position_weight(i + 1)? as u32 + * vin_char_value( + vin.chars() + .nth(i) + .ok_or(Exceptions::IllegalArgumentException(None))?, + )?; } - let check_to_char = vin.chars().nth(8).unwrap(); + let check_to_char = vin + .chars() + .nth(8) + .ok_or(Exceptions::IllegalArgumentException(None))?; let expected_check_char = check_char((sum % 11) as u8)?; Ok(check_to_char == expected_check_char) } @@ -115,21 +95,6 @@ fn vin_char_value(c: char) -> Result { "vin char out of range".to_owned(), ))), } - // if c >= 'A' && c <= 'I' { - // return Ok((c as u8 as u32 - 'A' as u8 as u32) + 1); - // } - // if c >= 'J' && c <= 'R' { - // return Ok((c as u8 as u32 - 'J' as u8 as u32) + 1); - // } - // if c >= 'S' && c <= 'Z' { - // return Ok((c as u8 as u32 - 'S' as u8 as u32) + 2); - // } - // if c >= '0' && c <= '9' { - // return Ok(c as u8 as u32 - '0' as u8 as u32); - // } - // Err(Exceptions::IllegalArgumentException( - // "vin char out of range".to_owned(), - // )) } fn vin_position_weight(position: usize) -> Result { @@ -142,19 +107,6 @@ fn vin_position_weight(position: usize) -> Result { "vin position weight out of bounds".to_owned(), ))), } - // if position >= 1 && position <= 7 { - // return 9 - position; - // } - // if position == 8 { - // return 10; - // } - // if position == 9 { - // return 0; - // } - // if position >= 10 && position <= 17 { - // return 19 - position; - // } - // throw new IllegalArgumentException(); } fn check_char(remainder: u8) -> Result { @@ -165,15 +117,6 @@ fn check_char(remainder: u8) -> Result { "remainder too high".to_owned(), ))), } - // if remainder < 10 { - // return Ok(('0' as u8 + remainder) as char); - // } - // if remainder == 10 { - // return Ok('X'); - // } - // Err(Exceptions::IllegalArgumentException( - // "remainder too high".to_owned(), - // )) } fn model_year(c: char) -> Result { @@ -189,33 +132,11 @@ fn model_year(c: char) -> Result { "model year argument out of range", )))), } - // if c >= 'E' && c <= 'H' { - // return (c - 'E') + 1984; - // } - // if c >= 'J' && c <= 'N' { - // return (c - 'J') + 1988; - // } - // if c == 'P' { - // return 1993; - // } - // if c >= 'R' && c <= 'T' { - // return (c - 'R') + 1994; - // } - // if c >= 'V' && c <= 'Y' { - // return (c - 'V') + 1997; - // } - // if c >= '1' && c <= '9' { - // return (c - '1') + 2001; - // } - // if c >= 'A' && c <= 'D' { - // return (c - 'A') + 2010; - // } - // throw new IllegalArgumentException(); } fn country_code(wmi: &str) -> Option<&'static str> { - let c1 = wmi.chars().next().unwrap(); - let c2 = wmi.chars().nth(1).unwrap(); + let c1 = wmi.chars().next()?; + let c2 = wmi.chars().nth(1)?; match c1 { '1' | '4' | '5' => Some("US"), '2' => Some("CA"), diff --git a/src/client/result/WifiResultParser.rs b/src/client/result/WifiResultParser.rs index 44eaaf5..726041d 100644 --- a/src/client/result/WifiResultParser.rs +++ b/src/client/result/WifiResultParser.rs @@ -14,15 +14,10 @@ * limitations under the License. */ -// package com.google.zxing.client.result; - -// import com.google.zxing.RXingResult; - use crate::client::result::{ParsedClientResult, WifiParsedRXingResult}; use super::ResultParser; -// @SuppressWarnings("checkstyle:lineLength") /** *

Parses a WIFI configuration string. Strings will be of the form:

* @@ -40,9 +35,6 @@ use super::ResultParser; * @author Sean Owen * @author Steffen Kieß */ -// pub struct WifiRXingResultParser {} - -// impl RXingResultParser for WifiRXingResultParser { pub fn parse(theRXingResult: &crate::RXingResult) -> Option { const WIFI_TEST: &str = "WIFI:"; @@ -53,35 +45,29 @@ pub fn parse(theRXingResult: &crate::RXingResult) -> Option