diff --git a/src/client/result/ExpandedProductParsedResult.java b/src/client/result/ExpandedProductParsedResult.java deleted file mode 100644 index 3b6b30a..0000000 --- a/src/client/result/ExpandedProductParsedResult.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (C) 2010 ZXing authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * These authors would like to acknowledge the Spanish Ministry of Industry, - * Tourism and Trade, for the support in the project TSI020301-2008-2 - * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled - * Mobile Dynamic Environments", led by Treelogic - * ( http://www.treelogic.com/ ): - * - * http://www.piramidepse.com/ - */ - -package com.google.zxing.client.result; - -import java.util.Map; -import java.util.Objects; - -/** - * Represents a parsed result that encodes extended product information as encoded - * by the RSS format, like weight, price, dates, etc. - * - * @author Antonio Manuel Benjumea Conde, Servinform, S.A. - * @author Agustín Delgado, Servinform, S.A. - */ -public final class ExpandedProductParsedRXingResult extends ParsedRXingResult { - - public static final String KILOGRAM = "KG"; - public static final String POUND = "LB"; - - private final String rawText; - private final String productID; - private final String sscc; - private final String lotNumber; - private final String productionDate; - private final String packagingDate; - private final String bestBeforeDate; - private final String expirationDate; - private final String weight; - private final String weightType; - private final String weightIncrement; - private final String price; - private final String priceIncrement; - private final String priceCurrency; - // For AIS that not exist in this object - private final Map uncommonAIs; - - public ExpandedProductParsedRXingResult(String rawText, - String productID, - String sscc, - String lotNumber, - String productionDate, - String packagingDate, - String bestBeforeDate, - String expirationDate, - String weight, - String weightType, - String weightIncrement, - String price, - String priceIncrement, - String priceCurrency, - Map uncommonAIs) { - super(ParsedRXingResultType.PRODUCT); - this.rawText = rawText; - this.productID = productID; - this.sscc = sscc; - this.lotNumber = lotNumber; - this.productionDate = productionDate; - this.packagingDate = packagingDate; - this.bestBeforeDate = bestBeforeDate; - this.expirationDate = expirationDate; - this.weight = weight; - this.weightType = weightType; - this.weightIncrement = weightIncrement; - this.price = price; - this.priceIncrement = priceIncrement; - this.priceCurrency = priceCurrency; - this.uncommonAIs = uncommonAIs; - } - - @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; - } - - public String getRawText() { - return rawText; - } - - public String getProductID() { - return productID; - } - - public String getSscc() { - return sscc; - } - - public String getLotNumber() { - return lotNumber; - } - - public String getProductionDate() { - return productionDate; - } - - public String getPackagingDate() { - return packagingDate; - } - - public String getBestBeforeDate() { - return bestBeforeDate; - } - - public String getExpirationDate() { - return expirationDate; - } - - public String getWeight() { - return weight; - } - - public String getWeightType() { - return weightType; - } - - public String getWeightIncrement() { - return weightIncrement; - } - - public String getPrice() { - return price; - } - - public String getPriceIncrement() { - return priceIncrement; - } - - public String getPriceCurrency() { - return priceCurrency; - } - - public Map getUncommonAIs() { - return uncommonAIs; - } - - @Override - public String getDisplayRXingResult() { - return String.valueOf(rawText); - } -} diff --git a/src/client/result/ExpandedProductParsedResult.rs b/src/client/result/ExpandedProductParsedResult.rs new file mode 100644 index 0000000..941208d --- /dev/null +++ b/src/client/result/ExpandedProductParsedResult.rs @@ -0,0 +1,212 @@ +/* + * Copyright (C) 2010 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * These authors would like to acknowledge the Spanish Ministry of Industry, + * Tourism and Trade, for the support in the project TSI020301-2008-2 + * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled + * Mobile Dynamic Environments", led by Treelogic + * ( http://www.treelogic.com/ ): + * + * http://www.piramidepse.com/ + */ + +// package com.google.zxing.client.result; + +// import java.util.Map; +// import java.util.Objects; + +use std::{collections::HashMap, hash::Hash}; + +use super::{ParsedRXingResult, ParsedRXingResultType}; + +pub const KILOGRAM: &'static str = "KG"; +pub const POUND: &'static str = "LB"; + +/** + * Represents a parsed result that encodes extended product information as encoded + * by the RSS format, like weight, price, dates, etc. + * + * @author Antonio Manuel Benjumea Conde, Servinform, S.A. + * @author Agustín Delgado, Servinform, S.A. + */ +#[derive(PartialEq, Eq)] +pub struct ExpandedProductParsedRXingResult { + rawText: String, + productID: String, + sscc: String, + lotNumber: String, + productionDate: String, + packagingDate: String, + bestBeforeDate: String, + expirationDate: String, + weight: String, + weightType: String, + weightIncrement: String, + price: String, + priceIncrement: String, + priceCurrency: String, + // For AIS that not exist in this object + uncommonAIs: HashMap, +} +impl ParsedRXingResult for ExpandedProductParsedRXingResult { + fn getType(&self) -> super::ParsedRXingResultType { + ParsedRXingResultType::PRODUCT + } + + fn getDisplayRXingResult(&self) -> String { + self.rawText.clone() + } +} + +impl ExpandedProductParsedRXingResult { + pub fn new( + rawText: String, + productID: String, + sscc: String, + lotNumber: String, + productionDate: String, + packagingDate: String, + bestBeforeDate: String, + expirationDate: String, + weight: String, + weightType: String, + weightIncrement: String, + price: String, + priceIncrement: String, + priceCurrency: String, + uncommonAIs: HashMap, + ) -> Self { + Self { + rawText, + productID, + sscc, + lotNumber, + productionDate, + packagingDate, + bestBeforeDate, + expirationDate, + weight, + weightType, + weightIncrement, + price, + priceIncrement, + priceCurrency, + uncommonAIs, + } + } + + // @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 + } + + pub fn getProductID(&self) -> &str { + &self.productID + } + + pub fn getSscc(&self) -> &str { + &self.sscc + } + + pub fn getLotNumber(&self) -> &str { + &self.lotNumber + } + + pub fn getProductionDate(&self) -> &str { + &self.productionDate + } + + pub fn getPackagingDate(&self) -> &str { + &self.packagingDate + } + + pub fn getBestBeforeDate(&self) -> &str { + &self.bestBeforeDate + } + + pub fn getExpirationDate(&self) -> &str { + &self.expirationDate + } + + pub fn getWeight(&self) -> &str { + &self.weight + } + + pub fn getWeightType(&self) -> &str { + &self.weightType + } + + pub fn getWeightIncrement(&self) -> &str { + &self.weightIncrement + } + + pub fn getPrice(&self) -> &str { + &self.price + } + + pub fn getPriceIncrement(&self) -> &str { + &self.priceIncrement + } + + pub fn getPriceCurrency(&self) -> &str { + &self.priceCurrency + } + + pub fn getUncommonAIs(&self) -> &HashMap { + &self.uncommonAIs + } +} diff --git a/src/client/result/ExpandedProductParsedResultTestCase.java b/src/client/result/ExpandedProductParsedResultTestCase.java deleted file mode 100644 index dbe9f9c..0000000 --- a/src/client/result/ExpandedProductParsedResultTestCase.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2010 ZXing authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * These authors would like to acknowledge the Spanish Ministry of Industry, - * Tourism and Trade, for the support in the project TSI020301-2008-2 - * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled - * Mobile Dynamic Environments", led by Treelogic - * ( http://www.treelogic.com/ ): - * - * 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. - */ -public final class ExpandedProductParsedRXingResultTestCase extends Assert { - - @Test - public void testRSSExpanded() { - Map uncommonAIs = new HashMap<>(); - uncommonAIs.put("123", "544654"); - RXingResult result = - new RXingResult("(01)66546(13)001205(3932)4455(3102)6544(123)544654", null, null, BarcodeFormat.RSS_EXPANDED); - ExpandedProductParsedRXingResult o = new ExpandedProductRXingResultParser().parse(result); - assertNotNull(o); - assertEquals("66546", o.getProductID()); - assertNull(o.getSscc()); - assertNull(o.getLotNumber()); - assertNull(o.getProductionDate()); - assertEquals("001205", o.getPackagingDate()); - assertNull(o.getBestBeforeDate()); - assertNull(o.getExpirationDate()); - assertEquals("6544", o.getWeight()); - assertEquals("KG", o.getWeightType()); - assertEquals("2", o.getWeightIncrement()); - assertEquals("5", o.getPrice()); - assertEquals("2", o.getPriceIncrement()); - assertEquals("445", o.getPriceCurrency()); - assertEquals(uncommonAIs, o.getUncommonAIs()); - } -} diff --git a/src/client/result/ExpandedProductParsedResultTestCase.rs b/src/client/result/ExpandedProductParsedResultTestCase.rs new file mode 100644 index 0000000..c08278f --- /dev/null +++ b/src/client/result/ExpandedProductParsedResultTestCase.rs @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2010 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * These authors would like to acknowledge the Spanish Ministry of Industry, + * Tourism and Trade, for the support in the project TSI020301-2008-2 + * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled + * Mobile Dynamic Environments", led by Treelogic + * ( http://www.treelogic.com/ ): + * + * 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. +// */ +// public final class ExpandedProductParsedRXingResultTestCase extends Assert { + +use std::collections::HashMap; + +use crate::{ + client::result::{ParsedClientResult, ProductParsedResult}, + RXingResult, BarcodeFormat, +}; + +use super::ExpandedProductResultParser; + +#[test] +fn testRSSExpanded() { + let mut uncommonAIs = HashMap::new(); + uncommonAIs.insert("123", "544654"); + let result = RXingResult::new( + "(01)66546(13)001205(3932)4455(3102)6544(123)544654", + Vec::new(), + Vec::new(), + BarcodeFormat::RSS_EXPANDED, + ); + let o = ExpandedProductResultParser::parse(&result); + if let Some(res) = o { + if let ParsedClientResult::ExpandedProductResult(epr_res) = res { + assert_eq!("66546", epr_res.getProductID()); + assert!(epr_res.getSscc().is_empty()); + assert!(epr_res.getLotNumber().is_empty()); + assert!(epr_res.getProductionDate().is_empty()); + assert_eq!("001205", epr_res.getPackagingDate()); + assert!(epr_res.getBestBeforeDate().is_empty()); + assert!(epr_res.getExpirationDate().is_empty()); + assert_eq!("6544", epr_res.getWeight()); + assert_eq!("KG", epr_res.getWeightType()); + assert_eq!("2", epr_res.getWeightIncrement()); + assert_eq!("5", epr_res.getPrice()); + assert_eq!("2", epr_res.getPriceIncrement()); + assert_eq!("445", epr_res.getPriceCurrency()); + assert_eq!(uncommonAIs.len(), epr_res.getUncommonAIs().len()); + for (k, v) in uncommonAIs { + if epr_res.getUncommonAIs().contains_key(k) { + let ev = epr_res.getUncommonAIs().get(k).unwrap(); + assert_eq!(v, ev); + } else { + panic!("key not found {}", k) + } + } + // assert_eq!(&uncommonAIs, epr_res.getUncommonAIs()); + } else { + panic!("Should have gotten a expanded product"); + } + } else { + panic!("Should have found a result"); + } +} +// } diff --git a/src/client/result/ExpandedProductResultParser.java b/src/client/result/ExpandedProductResultParser.java deleted file mode 100644 index 7ddd101..0000000 --- a/src/client/result/ExpandedProductResultParser.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (C) 2010 ZXing authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * These authors would like to acknowledge the Spanish Ministry of Industry, - * Tourism and Trade, for the support in the project TSI020301-2008-2 - * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled - * Mobile Dynamic Environments", led by Treelogic - * ( http://www.treelogic.com/ ): - * - * http://www.piramidepse.com/ - */ - -package com.google.zxing.client.result; - -import java.util.HashMap; -import java.util.Map; - -import com.google.zxing.BarcodeFormat; -import com.google.zxing.RXingResult; - -/** - * Parses strings of digits that represent a RSS Extended code. - * - * @author Antonio Manuel Benjumea Conde, Servinform, S.A. - * @author Agustín Delgado, Servinform, S.A. - */ -public final class ExpandedProductRXingResultParser extends RXingResultParser { - - @Override - public ExpandedProductParsedRXingResult parse(RXingResult result) { - BarcodeFormat format = result.getBarcodeFormat(); - if (format != BarcodeFormat.RSS_EXPANDED) { - // ExtendedProductParsedRXingResult NOT created. Not a RSS Expanded barcode - return null; - } - String rawText = getMassagedText(result); - - String productID = null; - String sscc = null; - String lotNumber = null; - String productionDate = null; - String packagingDate = null; - String bestBeforeDate = null; - String expirationDate = null; - String weight = null; - String weightType = null; - String weightIncrement = null; - String price = null; - String priceIncrement = null; - String priceCurrency = null; - Map uncommonAIs = new HashMap<>(); - - int i = 0; - - while (i < rawText.length()) { - String ai = findAIvalue(i, rawText); - if (ai == null) { - // Error. Code doesn't match with RSS expanded pattern - // ExtendedProductParsedRXingResult NOT created. Not match with RSS Expanded pattern - return null; - } - i += ai.length() + 2; - String value = findValue(i, rawText); - i += value.length(); - - switch (ai) { - case "00": - sscc = value; - break; - case "01": - productID = value; - break; - case "10": - lotNumber = value; - break; - case "11": - productionDate = value; - break; - case "13": - packagingDate = value; - break; - case "15": - bestBeforeDate = value; - break; - case "17": - expirationDate = value; - break; - case "3100": - case "3101": - case "3102": - case "3103": - case "3104": - case "3105": - case "3106": - case "3107": - case "3108": - case "3109": - weight = value; - weightType = ExpandedProductParsedRXingResult.KILOGRAM; - weightIncrement = ai.substring(3); - break; - case "3200": - case "3201": - case "3202": - case "3203": - case "3204": - case "3205": - case "3206": - case "3207": - case "3208": - case "3209": - weight = value; - weightType = ExpandedProductParsedRXingResult.POUND; - weightIncrement = ai.substring(3); - break; - case "3920": - case "3921": - case "3922": - case "3923": - price = value; - priceIncrement = ai.substring(3); - break; - case "3930": - case "3931": - case "3932": - case "3933": - if (value.length() < 4) { - // The value must have more of 3 symbols (3 for currency and - // 1 at least for the price) - // ExtendedProductParsedRXingResult NOT created. Not match with RSS Expanded pattern - return null; - } - price = value.substring(3); - priceCurrency = value.substring(0, 3); - priceIncrement = ai.substring(3); - break; - default: - // No match with common AIs - uncommonAIs.put(ai, value); - break; - } - } - - return new ExpandedProductParsedRXingResult(rawText, - productID, - sscc, - lotNumber, - productionDate, - packagingDate, - bestBeforeDate, - expirationDate, - weight, - weightType, - weightIncrement, - price, - priceIncrement, - priceCurrency, - uncommonAIs); - } - - private static String findAIvalue(int i, String rawText) { - char c = rawText.charAt(i); - // First character must be a open parenthesis.If not, ERROR - if (c != '(') { - return null; - } - - CharSequence rawTextAux = rawText.substring(i + 1); - - StringBuilder buf = new StringBuilder(); - for (int index = 0; index < rawTextAux.length(); index++) { - char currentChar = rawTextAux.charAt(index); - if (currentChar == ')') { - return buf.toString(); - } - if (currentChar < '0' || currentChar > '9') { - return null; - } - buf.append(currentChar); - } - return buf.toString(); - } - - private static String findValue(int i, String rawText) { - StringBuilder buf = new StringBuilder(); - String rawTextAux = rawText.substring(i); - - for (int index = 0; index < rawTextAux.length(); index++) { - char c = rawTextAux.charAt(index); - if (c == '(') { - // We look for a new AI. If it doesn't exist (ERROR), we continue - // with the iteration - if (findAIvalue(index, rawTextAux) != null) { - break; - } - buf.append('('); - } else { - buf.append(c); - } - } - return buf.toString(); - } -} diff --git a/src/client/result/ExpandedProductResultParser.rs b/src/client/result/ExpandedProductResultParser.rs new file mode 100644 index 0000000..ee0ca5b --- /dev/null +++ b/src/client/result/ExpandedProductResultParser.rs @@ -0,0 +1,288 @@ +/* + * Copyright (C) 2010 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * These authors would like to acknowledge the Spanish Ministry of Industry, + * Tourism and Trade, for the support in the project TSI020301-2008-2 + * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled + * Mobile Dynamic Environments", led by Treelogic + * ( http://www.treelogic.com/ ): + * + * http://www.piramidepse.com/ + */ + +// package com.google.zxing.client.result; + +// import java.util.HashMap; +// import java.util.Map; + +// import com.google.zxing.BarcodeFormat; +// import com.google.zxing.RXingResult; + +use std::collections::HashMap; + +use crate::BarcodeFormat; + +use super::{ + ExpandedProductParsedRXingResult, ExpandedProductParsedResult, ParsedClientResult, ResultParser, +}; + +/** + * Parses strings of digits that represent a RSS Extended code. + * + * @author Antonio Manuel Benjumea Conde, Servinform, S.A. + * @author Agustín Delgado, Servinform, S.A. + */ +pub fn parse(result: &crate::RXingResult) -> Option { + let barcode_format = result.getBarcodeFormat(); + if barcode_format != &BarcodeFormat::RSS_EXPANDED { + // ExtendedProductParsedRXingResult NOT created. Not a RSS Expanded barcode + return None; + } + let rawText = ResultParser::getMassagedText(result); + + let mut productID: String = "".to_owned(); // = null; + let mut sscc: String = "".to_owned(); + let mut lotNumber: String = "".to_owned(); + let mut productionDate: String = "".to_owned(); + let mut packagingDate: String = "".to_owned(); + let mut bestBeforeDate: String = "".to_owned(); + let mut expirationDate: String = "".to_owned(); + let mut weight: String = "".to_owned(); + let mut weightType: String = "".to_owned(); + let mut weightIncrement: String = "".to_owned(); + let mut price: String = "".to_owned(); + let mut priceIncrement: String = "".to_owned(); + let mut priceCurrency: String = "".to_owned(); + let mut uncommonAIs = HashMap::new(); + + let mut i = 0; + + while i < rawText.len() { + let ai = findAIvalue(i, &rawText)?; + // if ai == null { + // Error. Code doesn't match with RSS expanded pattern + // ExtendedProductParsedRXingResult NOT created. Not match with RSS Expanded pattern + // return None; + // } + i += ai.len() + 2; + let value = findValue(i, &rawText); + i += value.len(); + match ai.as_str() { + "00" => sscc = value, + "01" => productID = value, + "10" => lotNumber = value, + "10" => lotNumber = value, + "11" => productionDate = value, + "13" => packagingDate = value, + "15" => bestBeforeDate = value, + "17" => expirationDate = value, + "3100" | "3101" | "3102" | "3103" | "3104" | "3105" | "3106" | "3107" | "3108" + | "3109" => { + weight = value; + weightType = ExpandedProductParsedResult::KILOGRAM.into(); + weightIncrement = ai[3..].to_owned() + } + "3200" | "3201" | "3202" | "3203" | "3204" | "3205" | "3206" | "3207" | "3208" + | "3209" => { + weight = value; + weightType = ExpandedProductParsedResult::POUND.into(); + weightIncrement = ai[3..].to_owned(); + } + "3920" | "3921" | "3922" | "3923" => { + price = value; + priceIncrement = ai[3..].to_owned(); + } + "3930" | "3931" | "3932" | "3933" => { + if value.len() < 4 { + // The value must have more of 3 symbols (3 for currency and + // 1 at least for the price) + // ExtendedProductParsedRXingResult NOT created. Not match with RSS Expanded pattern + return None; + } + price = value[3..].to_owned(); + priceCurrency = value[0..3].to_owned(); + priceIncrement = ai[3..].to_owned(); + } + _ => { + // No match with common AIs + uncommonAIs.insert(ai, value); + } + }; + + // switch (ai) { + // case "00": + // sscc = value; + // break; + // case "01": + // productID = value; + // break; + // case "10": + // lotNumber = value; + // break; + // case "11": + // productionDate = value; + // break; + // case "13": + // packagingDate = value; + // break; + // case "15": + // bestBeforeDate = value; + // break; + // case "17": + // expirationDate = value; + // break; + // case "3100": + // case "3101": + // case "3102": + // case "3103": + // case "3104": + // case "3105": + // case "3106": + // case "3107": + // case "3108": + // case "3109": + // weight = value; + // weightType = ExpandedProductParsedRXingResult.KILOGRAM; + // weightIncrement = ai.substring(3); + // break; + // case "3200": + // case "3201": + // case "3202": + // case "3203": + // case "3204": + // case "3205": + // case "3206": + // case "3207": + // case "3208": + // case "3209": + // weight = value; + // weightType = ExpandedProductParsedRXingResult.POUND; + // weightIncrement = ai.substring(3); + // break; + // case "3920": + // case "3921": + // case "3922": + // case "3923": + // price = value; + // priceIncrement = ai.substring(3); + // break; + // case "3930": + // case "3931": + // case "3932": + // case "3933": + // if (value.length() < 4) { + // // The value must have more of 3 symbols (3 for currency and + // // 1 at least for the price) + // // ExtendedProductParsedRXingResult NOT created. Not match with RSS Expanded pattern + // return null; + // } + // price = value.substring(3); + // priceCurrency = value.substring(0, 3); + // priceIncrement = ai.substring(3); + // break; + // default: + // // No match with common AIs + // uncommonAIs.put(ai, value); + // break; + // } + } + + Some(ParsedClientResult::ExpandedProductResult( + ExpandedProductParsedRXingResult::new( + rawText, + productID, + sscc, + lotNumber, + productionDate, + packagingDate, + bestBeforeDate, + expirationDate, + weight, + weightType, + weightIncrement, + price, + priceIncrement, + priceCurrency, + uncommonAIs, + ), + )) + + // return new ExpandedProductParsedRXingResult(rawText, + // productID, + // sscc, + // lotNumber, + // productionDate, + // packagingDate, + // bestBeforeDate, + // expirationDate, + // weight, + // weightType, + // weightIncrement, + // price, + // priceIncrement, + // priceCurrency, + // uncommonAIs); +} + +fn findAIvalue(i: usize, rawText: &str) -> Option { + let c = rawText.chars().nth(i)?; + // First character must be a open parenthesis.If not, ERROR + if c != '(' { + return None; + } + + let rawTextAux = &rawText[i + 1..]; + + let mut buf = String::new(); + for index in 0..rawTextAux.len() { + // for (int index = 0; index < rawTextAux.length(); index++) { + let currentChar = rawTextAux.chars().nth(index)?; + if currentChar == ')' { + return Some(buf); + } + if currentChar < '0' || currentChar > '9' { + return None; + } + buf.push(currentChar); + } + + Some(buf) +} + +fn findValue(i: usize, rawText: &str) -> String { + 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(); + if c == '(' { + // We look for a new AI. If it doesn't exist (ERROR), we continue + // with the iteration + if let Some(_) = findAIvalue(index, rawTextAux) { + break; + } + // if findAIvalue(index, rawTextAux) != null { + // break; + // } + buf.push('('); + } else { + buf.push(c); + } + } + buf +} diff --git a/src/client/result/mod.rs b/src/client/result/mod.rs index 527ab8d..9a82ca9 100644 --- a/src/client/result/mod.rs +++ b/src/client/result/mod.rs @@ -33,6 +33,8 @@ mod VCardResultParser; mod BizcardResultParser; mod CalendarParsedResult; mod VEventResultParser; +mod ExpandedProductParsedResult; +mod ExpandedProductResultParser; use std::fmt; @@ -56,6 +58,7 @@ pub use VINParsedResult::*; pub use AddressBookParsedResult::*; pub use CalendarParsedResult::*; pub use CalendarParsedResult::*; +pub use ExpandedProductParsedResult::*; #[cfg(test)] mod TelParsedResultTestCase; @@ -79,6 +82,8 @@ mod VINParsedResultTestCase; mod AddressBookParsedResultTestCase; #[cfg(test)] mod CalendarParsedResultTestCase; +#[cfg(test)] +mod ExpandedProductParsedResultTestCase; pub enum ParsedClientResult { TextResult(TextParsedRXingResult), @@ -93,6 +98,7 @@ pub enum ParsedClientResult { VINResult(VINParsedRXingResult), AddressBookResult(AddressBookParsedRXingResult), CalendarEventResult(CalendarParsedRXingResult), + ExpandedProductResult(ExpandedProductParsedRXingResult), } impl ParsedRXingResult for ParsedClientResult { @@ -110,6 +116,7 @@ impl ParsedRXingResult for ParsedClientResult { ParsedClientResult::VINResult(a) => a.getType(), ParsedClientResult::AddressBookResult(a) => a.getType(), ParsedClientResult::CalendarEventResult(a) => a.getType(), + ParsedClientResult::ExpandedProductResult(a) => a.getType(), } } @@ -127,6 +134,7 @@ impl ParsedRXingResult for ParsedClientResult { ParsedClientResult::VINResult(a) => a.getDisplayRXingResult(), ParsedClientResult::AddressBookResult(a) => a.getDisplayRXingResult(), ParsedClientResult::CalendarEventResult(a) => a.getDisplayRXingResult(), + ParsedClientResult::ExpandedProductResult(a) => a.getDisplayRXingResult(), } } }