mirror of
https://github.com/starovoid/rxing.git
synced 2026-07-26 04:12:34 +00:00
Cleanup of many components of the code.
Many unwraps, expects, and panics removed or handled. More rustification of the codebase. Squashed commit of the following: commit 80c6483cf8c819496a7b781f9e3a149d1f18d5fe Author: Henry <henry@azule.info> Date: Fri Feb 10 20:36:57 2023 -0600 add other parsed result option commit 412d92ae585e7bf194697f5282dbc045e448bace Author: Henry <henry@azule.info> Date: Fri Feb 10 19:06:34 2023 -0600 fix some panics commit 9108d3e931aadec00fc0bf346ebc52d24e5d8146 Author: Henry <henry@azule.info> Date: Fri Feb 10 18:56:30 2023 -0600 clippy --fix commit 8cd89d314323f54f342f15fc73297b62d418ac79 Author: Henry <henry@azule.info> Date: Fri Feb 10 18:55:45 2023 -0600 some more cleanup in aztec commit fb7f9242e273b85a4bb212f22a185a0dcbfafc36 Author: Henry <henry@azule.info> Date: Fri Feb 10 18:19:54 2023 -0600 cleanup root commit 4fb7c0639830869149332b29be789e891eade3e7 Author: Henry Schimke <henry@azule.info> Date: Fri Feb 10 16:50:15 2023 -0600 format commit 3ac271af657b25fbe5ee39cbdf8859e5aa38ea41 Author: Henry Schimke <henry@azule.info> Date: Fri Feb 10 16:43:14 2023 -0600 clippy --fix commit 0c5b4c1477159db93a9da9645039f51cd1a7c574 Author: Henry Schimke <henry@azule.info> Date: Fri Feb 10 16:04:31 2023 -0600 qrcode cleanup complete commit 70c1d107cc672e45d46567c650c46fece7e7da9c Author: Henry Schimke <henry@azule.info> Date: Fri Feb 10 13:28:25 2023 -0600 clippy --fix commit e13263d0f1f2a13dbb59b6e60d8b871a32babc92 Author: Henry Schimke <henry@azule.info> Date: Fri Feb 10 13:27:44 2023 -0600 qrcode detector cleanup commit f7f2855099e469fe1091868c6099196705d0ae83 Author: Henry Schimke <henry@azule.info> Date: Fri Feb 10 11:48:13 2023 -0600 qrcode decoder commit bdbaaba597b3479639c2ed3726465a69e3004471 Author: Henry Schimke <henry@azule.info> Date: Fri Feb 10 11:13:18 2023 -0600 clippy --fix commit fd6dbcaeb1f45dc91ae98f0e7c58aad48d67df78 Author: Henry Schimke <henry@azule.info> Date: Fri Feb 10 11:12:28 2023 -0600 pdf417 cleanup complete commit 7bbd47604c2639a5eb61bdb5533e71be3bce95a1 Author: Henry Schimke <henry@azule.info> Date: Fri Feb 10 10:39:28 2023 -0600 clippy --fix commit 8f4962b7bb5f133524fe4d3d4948e5672a88c545 Author: Henry Schimke <henry@azule.info> Date: Fri Feb 10 10:39:00 2023 -0600 cleanup on pdf417 hie commit 254c8243953776d3c8704dd81529aadd05d5a94e Author: Henry <henry@azule.info> Date: Fri Feb 10 02:51:21 2023 +0000 partway through pdf417 hle commit d4a5b00fde8c0282b0c6e4175a21c1e111b11533 Author: Henry <henry@azule.info> Date: Wed Feb 8 21:35:25 2023 +0000 clippy --fix commit 2bd4a8e218aa963a88997b50bc5a198f9a88205e Author: Henry <henry@azule.info> Date: Wed Feb 8 21:31:55 2023 +0000 pdf417 decode and detect cleanup commit 05130ac54a72c2303045d64507bf6185aa74e531 Author: Henry Schimke <henry@azule.info> Date: Tue Feb 7 08:06:25 2023 -0600 at decodeTextCompaction in decoded_bit_straem_parser commit 924c023a7d2339dfffa6ef0c4a805fb192576796 Author: Henry Schimke <henry@azule.info> Date: Mon Feb 6 18:22:02 2023 -0600 clippy --fix commit 5cfb81a885c22b4b5ec937a79be31d0815def211 Author: Henry Schimke <henry@azule.info> Date: Mon Feb 6 18:20:22 2023 -0600 oned cleanup commit 0649b64854baf56a8e3314728d4f6cf4063db8b2 Author: Henry Schimke <henry@azule.info> Date: Mon Feb 6 11:47:28 2023 -0600 rss cleanup commit 2d3127898fc11f7e65d590e983cda799b798b646 Author: Henry Schimke <henry@azule.info> Date: Mon Feb 6 10:19:56 2023 -0600 multi cleanup commit 7e8b43a159083a2096123e6204d4d1d359c59981 Author: Henry <henry@azule.info> Date: Sun Feb 5 21:41:59 2023 -0600 cargo fmt commit df8285e8da07b4bffd48ca6e596de3f010eb8d9e Author: Henry <henry@azule.info> Date: Sun Feb 5 21:41:29 2023 -0600 maxicode cleanup commit a51f923a14016eb416ca202b2194258808dde3e7 Author: Henry <henry@azule.info> Date: Sun Feb 5 21:27:57 2023 -0600 cargo fmt commit 332d7eef4a25318611025a3fcb0b70c604d917be Author: Henry <henry@azule.info> Date: Sun Feb 5 21:27:48 2023 -0600 cleanup datamatrix commit eb2311c476a9c9993f271ab6cf9fd359aedca26f Author: Henry <henry@azule.info> Date: Sun Feb 5 21:27:26 2023 -0600 cargo clippy --fix commit 2abaa4c51d287f619d4c7a438f85ba2a30f159cf Author: Henry <henry@azule.info> Date: Sun Feb 5 19:13:02 2023 -0600 finish cleanup in parsers commit 716aa2fbf728716cff36657a5fd80e7bca5276b7 Author: Henry Schimke <henry@azule.info> Date: Sun Feb 5 17:44:56 2023 -0600 cleanup continues commit 7d843788a49fa9cc82c4616d226c0f882e73612b Author: Henry Schimke <henry@azule.info> Date: Sun Feb 5 15:15:09 2023 -0600 common cleanup commit fd251866c68f22d450dd428c93d7a3620bf1be27 Author: Henry Schimke <henry@azule.info> Date: Sun Feb 5 10:24:54 2023 -0600 cleanup reedsolomon commit 132e27ed1468f5c1ce998516ff5a00687217c3e6 Author: Henry Schimke <henry@azule.info> Date: Sun Feb 5 09:52:04 2023 -0600 make MathUtils more generic commit d8352b7fff4cb4f9ecc8e8a969710d26ef410e8b Author: Henry Schimke <henry@azule.info> Date: Sun Feb 5 09:29:33 2023 -0600 cleanup some string handling in ResultParser There may still be some edge cases where multi-byte characters break the parser
This commit is contained in:
@@ -50,17 +50,10 @@ pub fn parse(result: &RXingResult) -> Option<ParsedClientResult> {
|
||||
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<String> {
|
||||
// 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
|
||||
|
||||
@@ -43,35 +43,32 @@ pub fn parse(result: &RXingResult) -> Option<ParsedClientResult> {
|
||||
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;
|
||||
}
|
||||
|
||||
// }
|
||||
|
||||
@@ -41,36 +41,36 @@ pub fn parse(result: &RXingResult) -> Option<ParsedClientResult> {
|
||||
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<ParsedClientResult> {
|
||||
} 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<String> {
|
||||
|
||||
@@ -30,20 +30,16 @@ pub fn parse(result: &RXingResult) -> Option<ParsedClientResult> {
|
||||
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;
|
||||
}
|
||||
|
||||
// }
|
||||
|
||||
@@ -112,7 +112,7 @@ impl CalendarParsedRXingResult {
|
||||
) -> Result<Self, Exceptions> {
|
||||
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<i64, Exceptions> {
|
||||
// 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<i64, Exceptions> {
|
||||
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::<i64>().unwrap();
|
||||
let z = parseable
|
||||
.as_str()
|
||||
.parse::<i64>()
|
||||
.map_err(|e| Exceptions::ParseException(Some(e.to_string())))?;
|
||||
durationMS += unit * z;
|
||||
}
|
||||
}
|
||||
durationMS
|
||||
Ok(durationMS)
|
||||
} else {
|
||||
-1
|
||||
Ok(-1)
|
||||
}
|
||||
// if (!m.matches()) {
|
||||
// return -1L;
|
||||
|
||||
@@ -41,8 +41,6 @@ use super::{
|
||||
* @author Sean Owen
|
||||
*/
|
||||
pub fn parse(result: &RXingResult) -> Option<ParsedClientResult> {
|
||||
// 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<ParsedClientResult> {
|
||||
// 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;
|
||||
|
||||
@@ -43,16 +43,16 @@ pub fn parse(result: &RXingResult) -> Option<ParsedClientResult> {
|
||||
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),
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -77,7 +77,7 @@ pub fn parse(result: &crate::RXingResult) -> Option<super::ParsedClientResult> {
|
||||
// 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<String> {
|
||||
Some(buf)
|
||||
}
|
||||
|
||||
fn findValue(i: usize, rawText: &str) -> String {
|
||||
fn findValue(i: usize, rawText: &str) -> Option<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();
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -50,31 +50,41 @@ pub fn parse(theRXingResult: &crate::RXingResult) -> Option<super::ParsedClientR
|
||||
""
|
||||
};
|
||||
|
||||
let latitude = if let Some(la) = captures.get(1) {
|
||||
if let Ok(laf64) = la.as_str().parse::<f64>() {
|
||||
if !(-90.0..=90.0).contains(&laf64) {
|
||||
return None;
|
||||
}
|
||||
laf64
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
} else {
|
||||
let latitude = captures.get(1)?.as_str().parse::<f64>().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::<f64>() {
|
||||
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::<f64>() {
|
||||
// if !(-90.0..=90.0).contains(&laf64) {
|
||||
// return None;
|
||||
// }
|
||||
// laf64
|
||||
// } else {
|
||||
// return None;
|
||||
// }
|
||||
// } else {
|
||||
// return None;
|
||||
// };
|
||||
|
||||
let longitude = captures.get(2)?.as_str().parse::<f64>().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::<f64>() {
|
||||
// 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::<f64>() {
|
||||
@@ -88,28 +98,6 @@ pub fn parse(theRXingResult: &crate::RXingResult) -> Option<super::ParsedClientR
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
// let longitude;
|
||||
// let altitude;
|
||||
// try {
|
||||
// // latitude = Double.parseDouble(matcher.group(1));
|
||||
// // if (latitude > 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<super::ParsedClientR
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
||||
// Matcher matcher = GEO_URL_PATTERN.matcher(rawText);
|
||||
// if (!matcher.matches()) {
|
||||
// return null;
|
||||
// }
|
||||
}
|
||||
// }
|
||||
|
||||
@@ -36,4 +36,5 @@ pub enum ParsedRXingResultType {
|
||||
WIFI,
|
||||
ISBN,
|
||||
VIN,
|
||||
OTHER,
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ pub fn parse(result: &RXingResult) -> Option<ParsedClientResult> {
|
||||
{
|
||||
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<ParsedClientResult> {
|
||||
// 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()
|
||||
};
|
||||
|
||||
@@ -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<String>) -> Option<Vec<String>> {
|
||||
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::<String>();
|
||||
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<HashMap<String, String>> {
|
||||
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<String, Exceptions> {
|
||||
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<Vec<String>> {
|
||||
pub fn match_docomo_prefixed_field(prefix: &str, raw_text: &str) -> Option<Vec<String>> {
|
||||
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::<Vec<u8>>() {
|
||||
assert_eq!(d, result.getRawBytes());
|
||||
} else {
|
||||
panic!("did not get vec<u8>");
|
||||
}
|
||||
} else {
|
||||
panic!("did not get ParsedClientResult::Other");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
* <p>Parses an "sms:" URI result, which specifies a number to SMS.
|
||||
* See <a href="http://tools.ietf.org/html/rfc5724"> RFC 5724</a> on this.</p>
|
||||
@@ -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<String>, vias: &mut Vec<String>, 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());
|
||||
}
|
||||
}
|
||||
|
||||
// }
|
||||
|
||||
@@ -49,11 +49,7 @@ pub fn parse(result: &RXingResult) -> Option<ParsedClientResult> {
|
||||
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<ParsedClientResult> {
|
||||
body.to_owned(),
|
||||
),
|
||||
))
|
||||
// return new SMSParsedRXingResult(number, null, null, body);
|
||||
}
|
||||
|
||||
@@ -44,16 +44,7 @@ pub fn parse(result: &RXingResult) -> Option<ParsedClientResult> {
|
||||
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<ParsedClientResult> {
|
||||
body.to_owned(),
|
||||
),
|
||||
))
|
||||
// return new EmailAddressParsedRXingResult(new String[] {emailAddress},
|
||||
// null,
|
||||
// null,
|
||||
// subject,
|
||||
// body);
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -39,18 +39,16 @@ static ALLOWED_URI_CHARS: Lazy<Regex> = Lazy::new(|| {
|
||||
});
|
||||
static USER_IN_HOST: Lazy<Regex> =
|
||||
Lazy::new(|| Regex::new(":/*([^/@]+)@[^/]+").expect("Regex patterns should always copile"));
|
||||
|
||||
/// See http://www.ietf.org/rfc/rfc2396.txt
|
||||
static URL_WITH_PROTOCOL_PATTERN: Lazy<Regex> =
|
||||
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<Regex> =
|
||||
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<ParsedClientResult> {
|
||||
let raw_text = ResultParser::getMassagedText(result);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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}.
|
||||
*/
|
||||
|
||||
@@ -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<ParsedClientResult> {
|
||||
|
||||
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<ParsedClientResult> {
|
||||
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<bool, Exceptions> {
|
||||
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<u32, Exceptions> {
|
||||
"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<usize, Exceptions> {
|
||||
@@ -142,19 +107,6 @@ fn vin_position_weight(position: usize) -> Result<usize, Exceptions> {
|
||||
"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<char, Exceptions> {
|
||||
@@ -165,15 +117,6 @@ fn check_char(remainder: u8) -> Result<char, Exceptions> {
|
||||
"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<u32, Exceptions> {
|
||||
@@ -189,33 +132,11 @@ fn model_year(c: char) -> Result<u32, Exceptions> {
|
||||
"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"),
|
||||
|
||||
@@ -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")
|
||||
/**
|
||||
* <p>Parses a WIFI configuration string. Strings will be of the form:</p>
|
||||
*
|
||||
@@ -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<super::ParsedClientResult> {
|
||||
const WIFI_TEST: &str = "WIFI:";
|
||||
|
||||
@@ -53,35 +45,29 @@ pub fn parse(theRXingResult: &crate::RXingResult) -> Option<super::ParsedClientR
|
||||
let rawText = rawText_unstripped[WIFI_TEST.len()..].to_owned();
|
||||
let ssid =
|
||||
ResultParser::matchSinglePrefixedField("S:", &rawText, ';', false).unwrap_or_default();
|
||||
|
||||
if ssid.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let pass =
|
||||
ResultParser::matchSinglePrefixedField("P:", &rawText, ';', false).unwrap_or_default();
|
||||
let n_type =
|
||||
if let Some(nt) = ResultParser::matchSinglePrefixedField("T:", &rawText, ';', false) {
|
||||
nt
|
||||
} else {
|
||||
String::from("nopass")
|
||||
};
|
||||
|
||||
let n_type = ResultParser::matchSinglePrefixedField("T:", &rawText, ';', false)
|
||||
.unwrap_or(String::from("nopass"));
|
||||
|
||||
// Unfortunately, in the past, H: was not just used for boolean 'hidden', but 'phase 2 method'.
|
||||
// To try to retain backwards compatibility, we set one or the other based on whether the string
|
||||
// is 'true' or 'false':
|
||||
let mut hidden = false;
|
||||
let mut phase2Method = ResultParser::matchSinglePrefixedField("PH2:", &rawText, ';', false);
|
||||
let _hValue = if let Some(hv) =
|
||||
ResultParser::matchSinglePrefixedField("H:", &rawText, ';', false)
|
||||
{
|
||||
if let Some(hv) = ResultParser::matchSinglePrefixedField("H:", &rawText, ';', false) {
|
||||
// If PH2 was specified separately, or if the value is clearly boolean, interpret it as 'hidden'
|
||||
if phase2Method.is_some() || "true" == hv.to_lowercase() || "false" == hv.to_lowercase() {
|
||||
hidden = hv.parse().unwrap(); //Boolean.parseBoolean(hValue);
|
||||
hidden = hv.parse().ok()?;
|
||||
} else {
|
||||
phase2Method = Some(hv.clone());
|
||||
phase2Method = Some(hv);
|
||||
}
|
||||
hv
|
||||
} else {
|
||||
String::default()
|
||||
};
|
||||
|
||||
let identity =
|
||||
|
||||
@@ -60,6 +60,9 @@ pub use SMSParsedResult::*;
|
||||
pub use URIParsedResult::*;
|
||||
pub use VINParsedResult::*;
|
||||
|
||||
mod other_parsed_result;
|
||||
pub use other_parsed_result::*;
|
||||
|
||||
#[cfg(test)]
|
||||
mod AddressBookParsedResultTestCase;
|
||||
#[cfg(test)]
|
||||
@@ -102,6 +105,7 @@ pub enum ParsedClientResult {
|
||||
AddressBookResult(AddressBookParsedRXingResult),
|
||||
CalendarEventResult(CalendarParsedRXingResult),
|
||||
ExpandedProductResult(ExpandedProductParsedRXingResult),
|
||||
Other(OtherParsedResult),
|
||||
}
|
||||
|
||||
impl ParsedRXingResult for ParsedClientResult {
|
||||
@@ -120,6 +124,7 @@ impl ParsedRXingResult for ParsedClientResult {
|
||||
ParsedClientResult::AddressBookResult(a) => a.getType(),
|
||||
ParsedClientResult::CalendarEventResult(a) => a.getType(),
|
||||
ParsedClientResult::ExpandedProductResult(a) => a.getType(),
|
||||
ParsedClientResult::Other(a) => a.getType(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,6 +143,7 @@ impl ParsedRXingResult for ParsedClientResult {
|
||||
ParsedClientResult::AddressBookResult(a) => a.getDisplayRXingResult(),
|
||||
ParsedClientResult::CalendarEventResult(a) => a.getDisplayRXingResult(),
|
||||
ParsedClientResult::ExpandedProductResult(a) => a.getDisplayRXingResult(),
|
||||
ParsedClientResult::Other(a) => a.getDisplayRXingResult(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
37
src/client/result/other_parsed_result.rs
Normal file
37
src/client/result/other_parsed_result.rs
Normal file
@@ -0,0 +1,37 @@
|
||||
use std::any::Any;
|
||||
|
||||
use super::ParsedRXingResult;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct OtherParsedResult {
|
||||
data: Box<dyn Any>,
|
||||
}
|
||||
|
||||
impl ParsedRXingResult for OtherParsedResult {
|
||||
fn getType(&self) -> super::ParsedRXingResultType {
|
||||
super::ParsedRXingResultType::OTHER
|
||||
}
|
||||
|
||||
fn getDisplayRXingResult(&self) -> String {
|
||||
format!("{:?}", self.data)
|
||||
}
|
||||
}
|
||||
|
||||
impl OtherParsedResult {
|
||||
pub fn new(data: Box<dyn Any>) -> Self {
|
||||
Self { data }
|
||||
}
|
||||
|
||||
pub fn get_data(&self) -> &Box<dyn Any> {
|
||||
&self.data
|
||||
}
|
||||
}
|
||||
|
||||
/// This always returns false, any cannot be equal
|
||||
impl PartialEq for OtherParsedResult {
|
||||
fn eq(&self, _other: &Self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for OtherParsedResult {}
|
||||
Reference in New Issue
Block a user