Vin result port and passes

This commit is contained in:
Henry Schimke
2022-09-10 11:41:18 -05:00
parent cf14fb6742
commit 6a059c5a4a
4 changed files with 365 additions and 249 deletions

View File

@@ -23,7 +23,9 @@
use regex::Regex;
use crate::{RXingResult, BarcodeFormat, exceptions::Exceptions};
use crate::{
client::result::VINParsedRXingResult, exceptions::Exceptions, BarcodeFormat, RXingResult,
};
use super::ParsedClientResult;
@@ -33,81 +35,110 @@ use super::ParsedClientResult;
* @author Sean Owen
*/
pub fn parse(result: &RXingResult) -> Option<ParsedClientResult> {
if result.getBarcodeFormat() != &BarcodeFormat::CODE_39 {
return None;
}
let ioq_matcher = Regex::new(IOQ).unwrap();
let az09_matcher = Regex::new(AZ09).unwrap();
let rawText = result.getText();
ioq_matcher.replace_all(result.getText(), "").trim();
// rawText = IOQ.matcher(rawText).replaceAll("").trim();
if let None = az09_matcher.find(rawText){
return None;
}
// if !AZ09.matcher(rawText).matches() {
// return null;
// }
let check_cs = checkChecksum(rawText);
if !check_cs {
return None;
}
let wmi = &rawText[..3];
try {
if result.getBarcodeFormat() != &BarcodeFormat::CODE_39 {
return None;
}
let ioq_matcher = Regex::new(IOQ).unwrap();
let az09_matcher = Regex::new(AZ09).unwrap();
let rawText_res = result.getText().trim();
let rawText = ioq_matcher.replace_all(rawText_res, "").to_string();
// rawText = IOQ.matcher(rawText).replaceAll("").trim();
if let None = az09_matcher.find(&rawText) {
return None;
}
// if !AZ09.matcher(rawText).matches() {
// return null;
// }
let check_cs = checkChecksum(&rawText).unwrap_or(false);
if !check_cs {
return None;
}
let wmi = &rawText[..3];
// try {
// if (!checkChecksum(rawText)) {
// return null;
// }
// String wmi = rawText.substring(0, 3);
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;
}
let country_code = countryCode(wmi).unwrap_or("");
let model_year = modelYear(rawText.chars().nth(9).unwrap_or('_'));
if model_year.is_err() {
return None;
}
Some(ParsedClientResult::VINResult(VINParsedRXingResult::new(
rawText.to_owned(),
wmi.to_owned(),
rawText[3..9].to_owned(),
rawText[9..17].to_owned(),
country_code.to_owned(),
rawText[3..8].to_owned(),
model_year.unwrap(),
rawText.chars().nth(10).unwrap(),
rawText[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 : &'static str = "[IOQ]";
const AZ09 :&'static str = "[A-Z0-9]{17}";
const IOQ: &'static str = "[IOQ]";
const AZ09: &'static str = "[A-Z0-9]{17}";
fn checkChecksum( vin: &str) -> Result<bool,Exceptions> {
fn checkChecksum(vin: &str) -> Result<bool, Exceptions> {
let mut sum = 0;
for i in 0..vin.len() {
// for (int i = 0; i < vin.length(); i++) {
sum += vinPositionWeight(i + 1)? * vinCharValue(vin.chars().nth(i).unwrap())?;
// for (int i = 0; i < vin.length(); i++) {
sum += vinPositionWeight(i + 1)? as u32 * vinCharValue(vin.chars().nth(i).unwrap())?;
}
let checkToChar = vin.chars().nth(8).unwrap();
let expectedCheckChar = checkChar((sum % 11) as u8)?;
Ok( checkToChar == expectedCheckChar)
}
fn vinCharValue( c:char)->Result<u32,Exceptions> {
if c >= 'A' && c <= 'I' {
return Ok((c as u8 as u32 - 'A' as u8 as u32) + 1);
Ok(checkToChar == expectedCheckChar)
}
fn vinCharValue(c: char) -> Result<u32, Exceptions> {
match c {
'A'..='I' => Ok((c as u8 as u32 - 'A' as u8 as u32) + 1),
'J'..='R' => Ok((c as u8 as u32 - 'J' as u8 as u32) + 1),
'S'..='Z' => Ok((c as u8 as u32 - 'S' as u8 as u32) + 2),
'0'..='9' => Ok(c as u8 as u32 - '0' as u8 as u32),
_ => Err(Exceptions::IllegalArgumentException(
"vin char out of range".to_owned(),
)),
}
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 vinPositionWeight( position:usize) -> Result<usize, Exceptions>{
// 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 vinPositionWeight(position: usize) -> Result<usize, Exceptions> {
match position {
1..=7 => Ok(9-position),
8 => Ok(10),
9 => Ok(0),
10..=17 => Ok(19-position),
_ => Err(Exceptions::IllegalArgumentException("vin position weight out of bounds".to_owned())),
1..=7 => Ok(9 - position),
8 => Ok(10),
9 => Ok(0),
10..=17 => Ok(19 - position),
_ => Err(Exceptions::IllegalArgumentException(
"vin position weight out of bounds".to_owned(),
)),
}
// if position >= 1 && position <= 7 {
// return 9 - position;
@@ -122,62 +153,83 @@ pub fn parse(result: &RXingResult) -> Option<ParsedClientResult> {
// return 19 - position;
// }
// throw new IllegalArgumentException();
}
}
fn checkChar( remainder:u8) -> Result<char,Exceptions> {
if remainder < 10 {
return Ok( ('0' as u8 + remainder) as char );
fn checkChar(remainder: u8) -> Result<char, Exceptions> {
match remainder {
0..=9 => Ok(('0' as u8 + remainder) as char),
10 => Ok('X'),
_ => Err(Exceptions::IllegalArgumentException(
"remainder too high".to_owned(),
)),
}
if remainder == 10 {
return Ok('X');
}
Err(Exceptions::IllegalArgumentException("remainder too high".to_owned()))
}
fn modelYear( c:char) -> Result<u32,Exceptions> {
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();
}
// 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 countryCode( wmi : &str) -> Option<&'static str> {
fn modelYear(c: char) -> Result<u32, Exceptions> {
match c {
'E'..='H' => Ok((c as u8 as u32 - 'E' as u8 as u32) + 1984),
'J'..='N' => Ok((c as u8 as u32 - 'J' as u8 as u32) + 1988),
'P' => Ok(1993),
'R'..='T' => Ok((c as u8 as u32 - 'R' as u8 as u32) + 1994),
'V'..='Y' => Ok((c as u8 as u32 - 'V' as u8 as u32) + 1997),
'1'..='9' => Ok((c as u8 as u32 - '1' as u8 as u32) + 2001),
'A'..='D' => Ok((c as u8 as u32 - 'A' as u8 as u32) + 2010),
_ => Err(Exceptions::IllegalArgumentException(String::from(
"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 countryCode(wmi: &str) -> Option<&'static str> {
let c1 = wmi.chars().nth(0).unwrap();
let c2 = wmi.chars().nth(1).unwrap();
match c1 {
'1' | '4'| '5' => Some("US"),
'2' => Some("CA"),
'3' if c2 >= 'A' && c2 <= 'W' => Some("MX"),
'9' if ((c2 >= 'A' && c2 <= 'E') || (c2 >= '3' && c2 <= '9')) => Some("BR"),
'J' if (c2 >= 'A' && c2 <= 'T') => Some("JP"),
'K' if (c2 >= 'L' && c2 <= 'R') => Some("KO"),
'L' => Some("CN"),
'M' if (c2 >= 'A' && c2 <= 'E') => Some("IN"),
'S' if (c2 >= 'A' && c2 <= 'M') => Some("UK"),
'S' if (c2 >= 'N' && c2 <= 'T') => Some("DE"),
'V' if (c2 >= 'F' && c2 <= 'R') => Some("FR"),
'V' if (c2 >= 'S' && c2 <= 'W') => Some("ES"),
'W' => Some("DE"),
'X' if (c2 == '0' || (c2 >= '3' && c2 <= '9')) => Some("RU"),
'Z' if (c2 >= 'A' && c2 <= 'R') => Some("IT"),
_ => None
'1' | '4' | '5' => Some("US"),
'2' => Some("CA"),
'3' if c2 >= 'A' && c2 <= 'W' => Some("MX"),
'9' if ((c2 >= 'A' && c2 <= 'E') || (c2 >= '3' && c2 <= '9')) => Some("BR"),
'J' if (c2 >= 'A' && c2 <= 'T') => Some("JP"),
'K' if (c2 >= 'L' && c2 <= 'R') => Some("KO"),
'L' => Some("CN"),
'M' if (c2 >= 'A' && c2 <= 'E') => Some("IN"),
'S' if (c2 >= 'A' && c2 <= 'M') => Some("UK"),
'S' if (c2 >= 'N' && c2 <= 'T') => Some("DE"),
'V' if (c2 >= 'F' && c2 <= 'R') => Some("FR"),
'V' if (c2 >= 'S' && c2 <= 'W') => Some("ES"),
'W' => Some("DE"),
'X' if (c2 == '0' || (c2 >= '3' && c2 <= '9')) => Some("RU"),
'Z' if (c2 >= 'A' && c2 <= 'R') => Some("IT"),
_ => None,
}
}
}