still working through addresses

This commit is contained in:
Henry Schimke
2022-09-10 14:55:32 -05:00
parent a71138590f
commit 582dd75c02
11 changed files with 896 additions and 633 deletions

View File

@@ -1,89 +0,0 @@
/*
* Copyright 2008 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.
*/
package com.google.zxing.client.result;
import com.google.zxing.RXingResult;
import java.util.ArrayList;
import java.util.List;
/**
* Implements KDDI AU's address book format. See
* <a href="http://www.au.kddi.com/ezfactory/tec/two_dimensions/index.html">
* http://www.au.kddi.com/ezfactory/tec/two_dimensions/index.html</a>.
* (Thanks to Yuzo for translating!)
*
* @author Sean Owen
*/
public final class AddressBookAURXingResultParser extends RXingResultParser {
@Override
public AddressBookParsedRXingResult parse(RXingResult result) {
String rawText = getMassagedText(result);
// MEMORY is mandatory; seems like a decent indicator, as does end-of-record separator CR/LF
if (!rawText.contains("MEMORY") || !rawText.contains("\r\n")) {
return null;
}
// NAME1 and NAME2 have specific uses, namely written name and pronunciation, respectively.
// Therefore we treat them specially instead of as an array of names.
String name = matchSinglePrefixedField("NAME1:", rawText, '\r', true);
String pronunciation = matchSinglePrefixedField("NAME2:", rawText, '\r', true);
String[] phoneNumbers = matchMultipleValuePrefix("TEL", rawText);
String[] emails = matchMultipleValuePrefix("MAIL", rawText);
String note = matchSinglePrefixedField("MEMORY:", rawText, '\r', false);
String address = matchSinglePrefixedField("ADD:", rawText, '\r', true);
String[] addresses = address == null ? null : new String[] {address};
return new AddressBookParsedRXingResult(maybeWrap(name),
null,
pronunciation,
phoneNumbers,
null,
emails,
null,
null,
note,
addresses,
null,
null,
null,
null,
null,
null);
}
private static String[] matchMultipleValuePrefix(String prefix, String rawText) {
List<String> values = null;
// For now, always 3, and always trim
for (int i = 1; i <= 3; i++) {
String value = matchSinglePrefixedField(prefix + i + ':', rawText, '\r', true);
if (value == null) {
break;
}
if (values == null) {
values = new ArrayList<>(3); // lazy init
}
values.add(value);
}
if (values == null) {
return null;
}
return values.toArray(EMPTY_STR_ARRAY);
}
}

View File

@@ -0,0 +1,99 @@
/*
* Copyright 2008 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.
*/
// package com.google.zxing.client.result;
// import com.google.zxing.RXingResult;
// import java.util.ArrayList;
// import java.util.List;
use crate::RXingResult;
use super::{AddressBookParsedRXingResult, ParsedClientResult, ResultParser};
/**
* Implements KDDI AU's address book format. See
* <a href="http://www.au.kddi.com/ezfactory/tec/two_dimensions/index.html">
* http://www.au.kddi.com/ezfactory/tec/two_dimensions/index.html</a>.
* (Thanks to Yuzo for translating!)
*
* @author Sean Owen
*/
pub fn parse(result: &RXingResult) -> Option<ParsedClientResult> {
let rawText = ResultParser::getMassagedText(result);
// MEMORY is mandatory; seems like a decent indicator, as does end-of-record separator CR/LF
if !rawText.contains("MEMORY") || !rawText.contains("\r\n") {
return None;
}
// NAME1 and NAME2 have specific uses, namely written name and pronunciation, respectively.
// Therefore we treat them specially instead of as an array of names.
let name = ResultParser::matchSinglePrefixedField("NAME1:", &rawText, '\r', true);
let pronunciation = ResultParser::matchSinglePrefixedField("NAME2:", &rawText, '\r', true);
let phoneNumbers = matchMultipleValuePrefix("TEL", &rawText);
let emails = matchMultipleValuePrefix("MAIL", &rawText);
let note = ResultParser::matchSinglePrefixedField("MEMORY:", &rawText, '\r', false)?;
let address = ResultParser::matchSinglePrefixedField("ADD:", &rawText, '\r', true);
let addresses = if address.is_none() {
Vec::new()
} else {
vec![address?]
};
if let Ok(new_data) = AddressBookParsedRXingResult::with_details(
ResultParser::maybeWrap(name)?,
Vec::new(),
"".to_owned(),
phoneNumbers,
Vec::new(),
Vec::new(),
Vec::new(),
"".to_owned(),
note,
addresses,
Vec::new(),
"".to_owned(),
"".to_owned(),
"".to_owned(),
Vec::new(),
Vec::new(),
) {
Some(ParsedClientResult::AddressBookResult(new_data))
} else {
None
}
}
fn matchMultipleValuePrefix(prefix: &str, rawText: &str) -> Vec<String> {
let mut values = Vec::new();
// For now, always 3, and always trim
for i in 1..=3 {
// for (int i = 1; i <= 3; i++) {
let value = ResultParser::matchSinglePrefixedField(
&format!("{}{}:", prefix, i),
rawText,
'\r',
true,
);
if value.is_none() {
break;
}
values.push(value.unwrap());
}
values
}

View File

@@ -1,92 +0,0 @@
/*
* Copyright 2007 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.
*/
package com.google.zxing.client.result;
import com.google.zxing.RXingResult;
/**
* Implements the "MECARD" address book entry format.
*
* Supported keys: N, SOUND, TEL, EMAIL, NOTE, ADR, BDAY, URL, plus ORG
* Unsupported keys: TEL-AV, NICKNAME
*
* Except for TEL, multiple values for keys are also not supported;
* the first one found takes precedence.
*
* Our understanding of the MECARD format is based on this document:
*
* http://www.mobicode.org.tw/files/OMIA%20Mobile%20Bar%20Code%20Standard%20v3.2.1.doc
*
* @author Sean Owen
*/
public final class AddressBookDoCoMoRXingResultParser extends AbstractDoCoMoRXingResultParser {
@Override
public AddressBookParsedRXingResult parse(RXingResult result) {
String rawText = getMassagedText(result);
if (!rawText.startsWith("MECARD:")) {
return null;
}
String[] rawName = matchDoCoMoPrefixedField("N:", rawText);
if (rawName == null) {
return null;
}
String name = parseName(rawName[0]);
String pronunciation = matchSingleDoCoMoPrefixedField("SOUND:", rawText, true);
String[] phoneNumbers = matchDoCoMoPrefixedField("TEL:", rawText);
String[] emails = matchDoCoMoPrefixedField("EMAIL:", rawText);
String note = matchSingleDoCoMoPrefixedField("NOTE:", rawText, false);
String[] addresses = matchDoCoMoPrefixedField("ADR:", rawText);
String birthday = matchSingleDoCoMoPrefixedField("BDAY:", rawText, true);
if (!isStringOfDigits(birthday, 8)) {
// No reason to throw out the whole card because the birthday is formatted wrong.
birthday = null;
}
String[] urls = matchDoCoMoPrefixedField("URL:", rawText);
// 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.
String org = matchSingleDoCoMoPrefixedField("ORG:", rawText, true);
return new AddressBookParsedRXingResult(maybeWrap(name),
null,
pronunciation,
phoneNumbers,
null,
emails,
null,
null,
note,
addresses,
null,
org,
birthday,
null,
urls,
null);
}
private static String parseName(String name) {
int 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;
}
}

View File

@@ -0,0 +1,111 @@
/*
* Copyright 2007 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.
*/
// package com.google.zxing.client.result;
// import com.google.zxing.RXingResult;
use crate::RXingResult;
use super::{AddressBookParsedRXingResult, ParsedClientResult, ResultParser};
/**
* Implements the "MECARD" address book entry format.
*
* Supported keys: N, SOUND, TEL, EMAIL, NOTE, ADR, BDAY, URL, plus ORG
* Unsupported keys: TEL-AV, NICKNAME
*
* Except for TEL, multiple values for keys are also not supported;
* the first one found takes precedence.
*
* Our understanding of the MECARD format is based on this document:
*
* http://www.mobicode.org.tw/files/OMIA%20Mobile%20Bar%20Code%20Standard%20v3.2.1.doc
*
* @author Sean Owen
*/
// public final class AddressBookDoCoMoRXingResultParser extends AbstractDoCoMoRXingResultParser {
pub fn parse(result: &RXingResult) -> Option<ParsedClientResult> {
let rawText = ResultParser::getMassagedText(result);
if !rawText.starts_with("MECARD:") {
return None;
}
let rawName = ResultParser::match_do_co_mo_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)
.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)
.unwrap_or_default();
if !ResultParser::isStringOfDigits(&birthday, 8) {
// No reason to throw out the whole card because the birthday is formatted wrong.
birthday = "".to_owned();
}
let urls = ResultParser::match_do_co_mo_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)
.unwrap_or_default();
if let Ok(new_adb) = AddressBookParsedRXingResult::with_details(
ResultParser::maybeWrap(Some(name))?,
Vec::new(),
pronunciation,
phoneNumbers,
Vec::new(),
emails,
Vec::new(),
"".to_owned(),
note,
addresses,
Vec::new(),
org,
birthday,
"".to_owned(),
urls,
Vec::new(),
) {
Some(ParsedClientResult::AddressBookResult(new_adb))
} else {
None
}
}
fn parseName(name: &str) -> String {
if let Some(comma) = name.find(',') {
format!("{} {}", &name[comma + 1..], &name[0..comma])
} 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;
}
// }

View File

@@ -1,220 +0,0 @@
/*
* Copyright 2007 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.
*/
package com.google.zxing.client.result;
/**
* Represents a parsed result that encodes contact information, like that in an address book
* entry.
*
* @author Sean Owen
*/
public final class AddressBookParsedRXingResult extends ParsedRXingResult {
private final String[] names;
private final String[] nicknames;
private final String pronunciation;
private final String[] phoneNumbers;
private final String[] phoneTypes;
private final String[] emails;
private final String[] emailTypes;
private final String instantMessenger;
private final String note;
private final String[] addresses;
private final String[] addressTypes;
private final String org;
private final String birthday;
private final String title;
private final String[] urls;
private final String[] geo;
public AddressBookParsedRXingResult(String[] names,
String[] phoneNumbers,
String[] phoneTypes,
String[] emails,
String[] emailTypes,
String[] addresses,
String[] addressTypes) {
this(names,
null,
null,
phoneNumbers,
phoneTypes,
emails,
emailTypes,
null,
null,
addresses,
addressTypes,
null,
null,
null,
null,
null);
}
public AddressBookParsedRXingResult(String[] names,
String[] nicknames,
String pronunciation,
String[] phoneNumbers,
String[] phoneTypes,
String[] emails,
String[] emailTypes,
String instantMessenger,
String note,
String[] addresses,
String[] addressTypes,
String org,
String birthday,
String title,
String[] urls,
String[] geo) {
super(ParsedRXingResultType.ADDRESSBOOK);
if (phoneNumbers != null && phoneTypes != null && phoneNumbers.length != phoneTypes.length) {
throw new IllegalArgumentException("Phone numbers and types lengths differ");
}
if (emails != null && emailTypes != null && emails.length != emailTypes.length) {
throw new IllegalArgumentException("Emails and types lengths differ");
}
if (addresses != null && addressTypes != null && addresses.length != addressTypes.length) {
throw new IllegalArgumentException("Addresses and types lengths differ");
}
this.names = names;
this.nicknames = nicknames;
this.pronunciation = pronunciation;
this.phoneNumbers = phoneNumbers;
this.phoneTypes = phoneTypes;
this.emails = emails;
this.emailTypes = emailTypes;
this.instantMessenger = instantMessenger;
this.note = note;
this.addresses = addresses;
this.addressTypes = addressTypes;
this.org = org;
this.birthday = birthday;
this.title = title;
this.urls = urls;
this.geo = geo;
}
public String[] getNames() {
return names;
}
public String[] getNicknames() {
return nicknames;
}
/**
* In Japanese, the name is written in kanji, which can have multiple readings. Therefore a hint
* is often provided, called furigana, which spells the name phonetically.
*
* @return The pronunciation of the getNames() field, often in hiragana or katakana.
*/
public String getPronunciation() {
return pronunciation;
}
public String[] getPhoneNumbers() {
return phoneNumbers;
}
/**
* @return optional descriptions of the type of each phone number. It could be like "HOME", but,
* there is no guaranteed or standard format.
*/
public String[] getPhoneTypes() {
return phoneTypes;
}
public String[] getEmails() {
return emails;
}
/**
* @return optional descriptions of the type of each e-mail. It could be like "WORK", but,
* there is no guaranteed or standard format.
*/
public String[] getEmailTypes() {
return emailTypes;
}
public String getInstantMessenger() {
return instantMessenger;
}
public String getNote() {
return note;
}
public String[] getAddresses() {
return addresses;
}
/**
* @return optional descriptions of the type of each e-mail. It could be like "WORK", but,
* there is no guaranteed or standard format.
*/
public String[] getAddressTypes() {
return addressTypes;
}
public String getTitle() {
return title;
}
public String getOrg() {
return org;
}
public String[] getURLs() {
return urls;
}
/**
* @return birthday formatted as yyyyMMdd (e.g. 19780917)
*/
public String getBirthday() {
return birthday;
}
/**
* @return a location as a latitude/longitude pair
*/
public String[] getGeo() {
return geo;
}
@Override
public String getDisplayRXingResult() {
StringBuilder result = new StringBuilder(100);
maybeAppend(names, result);
maybeAppend(nicknames, result);
maybeAppend(pronunciation, result);
maybeAppend(title, result);
maybeAppend(org, result);
maybeAppend(addresses, result);
maybeAppend(phoneNumbers, result);
maybeAppend(emails, result);
maybeAppend(instantMessenger, result);
maybeAppend(urls, result);
maybeAppend(birthday, result);
maybeAppend(geo, result);
maybeAppend(note, result);
return result.toString();
}
}

View File

@@ -0,0 +1,242 @@
/*
* Copyright 2007 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.
*/
// package com.google.zxing.client.result;
use crate::exceptions::Exceptions;
use super::{ParsedRXingResult, ParsedRXingResultType, ResultParser};
/**
* Represents a parsed result that encodes contact information, like that in an address book
* entry.
*
* @author Sean Owen
*/
pub struct AddressBookParsedRXingResult {
names: Vec<String>,
nicknames: Vec<String>,
pronunciation: String,
phone_numbers: Vec<String>,
phone_types: Vec<String>,
emails: Vec<String>,
email_types: Vec<String>,
instant_messenger: String,
note: String,
addresses: Vec<String>,
address_types: Vec<String>,
org: String,
birthday: String,
title: String,
urls: Vec<String>,
geo: Vec<String>,
}
impl ParsedRXingResult for AddressBookParsedRXingResult {
fn getType(&self) -> super::ParsedRXingResultType {
ParsedRXingResultType::ADDRESSBOOK
}
fn getDisplayRXingResult(&self) -> String {
let mut result = String::with_capacity(100);
ResultParser::maybe_append_multiple(&self.names, &mut result);
ResultParser::maybe_append_multiple(&self.nicknames, &mut result);
ResultParser::maybe_append_string(&self.pronunciation, &mut result);
ResultParser::maybe_append_string(&self.title, &mut result);
ResultParser::maybe_append_string(&self.org, &mut result);
ResultParser::maybe_append_multiple(&self.addresses, &mut result);
ResultParser::maybe_append_multiple(&self.phone_numbers, &mut result);
ResultParser::maybe_append_multiple(&self.emails, &mut result);
ResultParser::maybe_append_string(&self.instant_messenger, &mut result);
ResultParser::maybe_append_multiple(&self.urls, &mut result);
ResultParser::maybe_append_string(&self.birthday, &mut result);
ResultParser::maybe_append_multiple(&self.geo, &mut result);
ResultParser::maybe_append_string(&self.note, &mut result);
result
}
}
impl AddressBookParsedRXingResult {
pub fn new(
names: Vec<String>,
phone_numbers: Vec<String>,
phone_types: Vec<String>,
emails: Vec<String>,
email_types: Vec<String>,
addresses: Vec<String>,
address_types: Vec<String>,
) -> Result<Self, Exceptions> {
Self::with_details(
names,
Vec::new(),
"".to_owned(),
phone_numbers,
phone_types,
emails,
email_types,
"".to_owned(),
"".to_owned(),
addresses,
address_types,
"".to_owned(),
"".to_owned(),
"".to_owned(),
Vec::new(),
Vec::new(),
)
}
pub fn with_details(
names: Vec<String>,
nicknames: Vec<String>,
pronunciation: String,
phone_numbers: Vec<String>,
phone_types: Vec<String>,
emails: Vec<String>,
email_types: Vec<String>,
instant_messenger: String,
note: String,
addresses: Vec<String>,
address_types: Vec<String>,
org: String,
birthday: String,
title: String,
urls: Vec<String>,
geo: Vec<String>,
) -> Result<Self, Exceptions> {
if phone_numbers.len() != phone_types.len() {
return Err(Exceptions::IllegalArgumentException(
"Phone numbers and types lengths differ".to_owned(),
));
}
if emails.len() != email_types.len() {
return Err(Exceptions::IllegalArgumentException(
"Emails and types lengths differ".to_owned(),
));
}
if addresses.len() != address_types.len() {
return Err(Exceptions::IllegalArgumentException(
"Addresses and types lengths differ".to_owned(),
));
}
Ok(Self {
names,
nicknames,
pronunciation,
phone_numbers,
phone_types,
emails,
email_types,
instant_messenger,
note,
addresses,
address_types,
org,
birthday,
title,
urls,
geo,
})
}
pub fn getNames(&self) -> &Vec<String> {
&self.names
}
pub fn getNicknames(&self) -> &Vec<String> {
&self.nicknames
}
/**
* In Japanese, the name is written in kanji, which can have multiple readings. Therefore a hint
* is often provided, called furigana, which spells the name phonetically.
*
* @return The pronunciation of the getNames() field, often in hiragana or katakana.
*/
pub fn getPronunciation(&self) -> &str {
&self.pronunciation
}
pub fn getPhoneNumbers(&self) -> &Vec<String> {
&self.phone_numbers
}
/**
* @return optional descriptions of the type of each phone number. It could be like "HOME", but,
* there is no guaranteed or standard format.
*/
pub fn getPhoneTypes(&self) -> &Vec<String> {
&self.phone_types
}
pub fn getEmails(&self) -> &Vec<String> {
&self.emails
}
/**
* @return optional descriptions of the type of each e-mail. It could be like "WORK", but,
* there is no guaranteed or standard format.
*/
pub fn getEmailTypes(&self) -> &Vec<String> {
&self.email_types
}
pub fn getInstantMessenger(&self) -> &str {
&self.instant_messenger
}
pub fn getNote(&self) -> &str {
&self.note
}
pub fn getAddresses(&self) -> &Vec<String> {
&self.addresses
}
/**
* @return optional descriptions of the type of each e-mail. It could be like "WORK", but,
* there is no guaranteed or standard format.
*/
pub fn getAddressTypes(&self) -> &Vec<String> {
&self.address_types
}
pub fn getTitle(&self) -> &str {
&self.title
}
pub fn getOrg(&self) -> &str {
&self.org
}
pub fn getURLs(&self) -> &Vec<String> {
&self.urls
}
/**
* @return birthday formatted as yyyyMMdd (e.g. 19780917)
*/
pub fn getBirthday(&self) -> &str {
&self.birthday
}
/**
* @return a location as a latitude/longitude pair
*/
pub fn getGeo(&self) -> &Vec<String> {
&self.geo
}
}

View File

@@ -1,169 +0,0 @@
/*
* Copyright 2007 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.
*/
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 AddressBookParsedRXingResult}.
*
* @author Sean Owen
*/
public final class AddressBookParsedRXingResultTestCase extends Assert {
@Test
public void testAddressBookDocomo() {
doTest("MECARD:N:Sean Owen;;", null, new String[] {"Sean Owen"},
null, null, null, null, null, null, null, null, null);
doTest("MECARD:NOTE:ZXing Team;N:Sean Owen;URL:google.com;EMAIL:srowen@example.org;;",
null, new String[] {"Sean Owen"}, null, null, new String[] {"srowen@example.org"}, null, null, null,
new String[] {"google.com"}, null, "ZXing Team");
}
@Test
public void testAddressBookAU() {
doTest("MEMORY:foo\r\nNAME1:Sean\r\nTEL1:+12125551212\r\n",
null, new String[] {"Sean"}, null, null, null, new String[] {"+12125551212"}, null, null, null, null, "foo");
}
@Test
public void testVCard() {
doTest("BEGIN:VCARD\r\nADR;HOME:123 Main St\r\nVERSION:2.1\r\nN:Owen;Sean\r\nEND:VCARD",
null, new String[] {"Sean Owen"}, null, new String[] {"123 Main St"},
null, null, null, null, null, null, null);
}
@Test
public void testVCardFullN() {
doTest("BEGIN:VCARD\r\nVERSION:2.1\r\nN:Owen;Sean;T;Mr.;Esq.\r\nEND:VCARD",
null, new String[] {"Mr. Sean T Owen Esq."}, null, null, null, null, null, null, null, null, null);
}
@Test
public void testVCardFullN2() {
doTest("BEGIN:VCARD\r\nVERSION:2.1\r\nN:Owen;Sean;;;\r\nEND:VCARD",
null, new String[] {"Sean Owen"}, null, null, null, null, null, null, null, null, null);
}
@Test
public void testVCardFullN3() {
doTest("BEGIN:VCARD\r\nVERSION:2.1\r\nN:;Sean;;;\r\nEND:VCARD",
null, new String[] {"Sean"}, null, null, null, null, null, null, null, null, null);
}
@Test
public void testVCardCaseInsensitive() {
doTest("begin:vcard\r\nadr;HOME:123 Main St\r\nVersion:2.1\r\nn:Owen;Sean\r\nEND:VCARD",
null, new String[] {"Sean Owen"}, null, new String[] {"123 Main St"},
null, null, null, null, null, null, null);
}
@Test
public void testEscapedVCard() {
doTest("BEGIN:VCARD\r\nADR;HOME:123\\;\\\\ Main\\, St\\nHome\r\nVERSION:2.1\r\nN:Owen;Sean\r\nEND:VCARD",
null, new String[] {"Sean Owen"}, null, new String[] {"123;\\ Main, St\nHome"},
null, null, null, null, null, null, null);
}
@Test
public void testBizcard() {
doTest("BIZCARD:N:Sean;X:Owen;C:Google;A:123 Main St;M:+12125551212;E:srowen@example.org;",
null, new String[] {"Sean Owen"}, null, new String[] {"123 Main St"}, new String[] {"srowen@example.org"},
new String[] {"+12125551212"}, null, "Google", null, null, null);
}
@Test
public void testSeveralAddresses() {
doTest("MECARD:N:Foo Bar;ORG:Company;TEL:5555555555;EMAIL:foo.bar@xyz.com;ADR:City, 10001;" +
"ADR:City, 10001;NOTE:This is the memo.;;",
null, new String[] {"Foo Bar"}, null, new String[] {"City, 10001", "City, 10001"},
new String[] {"foo.bar@xyz.com"},
new String[] {"5555555555" }, null, "Company", null, null, "This is the memo.");
}
@Test
public void testQuotedPrintable() {
doTest("BEGIN:VCARD\r\nADR;HOME;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:;;" +
"=38=38=20=4C=79=6E=62=72=6F=6F=6B=0D=0A=43=\r\n" +
"=4F=20=36=39=39=\r\n" +
"=39=39;;;\r\nEND:VCARD",
null, null, null, new String[] {"88 Lynbrook\r\nCO 69999"},
null, null, null, null, null, null, null);
}
@Test
public void testVCardEscape() {
doTest("BEGIN:VCARD\r\nNOTE:foo\\nbar\r\nEND:VCARD",
null, null, null, null, null, null, null, null, null, null, "foo\nbar");
doTest("BEGIN:VCARD\r\nNOTE:foo\\;bar\r\nEND:VCARD",
null, null, null, null, null, null, null, null, null, null, "foo;bar");
doTest("BEGIN:VCARD\r\nNOTE:foo\\\\bar\r\nEND:VCARD",
null, null, null, null, null, null, null, null, null, null, "foo\\bar");
doTest("BEGIN:VCARD\r\nNOTE:foo\\,bar\r\nEND:VCARD",
null, null, null, null, null, null, null, null, null, null, "foo,bar");
}
@Test
public void testVCardValueURI() {
doTest("BEGIN:VCARD\r\nTEL;VALUE=uri:tel:+1-555-555-1212\r\nEND:VCARD",
null, null, null, null, null, new String[] { "+1-555-555-1212" }, new String[] { null },
null, null, null, null);
doTest("BEGIN:VCARD\r\nN;VALUE=text:Owen;Sean\r\nEND:VCARD",
null, new String[] {"Sean Owen"}, null, null, null, null, null, null, null, null, null);
}
@Test
public void testVCardTypes() {
doTest("BEGIN:VCARD\r\nTEL;HOME:\r\nTEL;WORK:10\r\nTEL:20\r\nTEL;CELL:30\r\nEND:VCARD",
null, null, null, null, null, new String[] { "10", "20", "30" },
new String[] { "WORK", null, "CELL" }, null, null, null, null);
}
private static void doTest(String contents,
String title,
String[] names,
String pronunciation,
String[] addresses,
String[] emails,
String[] phoneNumbers,
String[] phoneTypes,
String org,
String[] urls,
String birthday,
String note) {
RXingResult fakeRXingResult = new RXingResult(contents, null, null, BarcodeFormat.QR_CODE);
ParsedRXingResult result = RXingResultParser.parseRXingResult(fakeRXingResult);
assertSame(ParsedRXingResultType.ADDRESSBOOK, result.getType());
AddressBookParsedRXingResult addressRXingResult = (AddressBookParsedRXingResult) result;
assertEquals(title, addressRXingResult.getTitle());
assertArrayEquals(names, addressRXingResult.getNames());
assertEquals(pronunciation, addressRXingResult.getPronunciation());
assertArrayEquals(addresses, addressRXingResult.getAddresses());
assertArrayEquals(emails, addressRXingResult.getEmails());
assertArrayEquals(phoneNumbers, addressRXingResult.getPhoneNumbers());
assertArrayEquals(phoneTypes, addressRXingResult.getPhoneTypes());
assertEquals(org, addressRXingResult.getOrg());
assertArrayEquals(urls, addressRXingResult.getURLs());
assertEquals(birthday, addressRXingResult.getBirthday());
assertEquals(note, addressRXingResult.getNote());
}
}

View File

@@ -0,0 +1,372 @@
/*
* Copyright 2007 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.
*/
// 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 AddressBookParsedRXingResult}.
*
* @author Sean Owen
*/
// public final class AddressBookParsedRXingResultTestCase extends Assert {
use crate::{
client::result::{ParsedClientResult, ParsedRXingResult, ParsedRXingResultType, ResultParser},
BarcodeFormat, RXingResult,
};
#[test]
fn testAddressBookDocomo() {
doTest(
"MECARD:N:Sean Owen;;",
"",
&vec!["Sean Owen"],
"",
&Vec::new(),
&Vec::new(),
&Vec::new(),
&Vec::new(),
"",
&Vec::new(),
"",
"",
);
doTest(
"MECARD:NOTE:ZXing Team;N:Sean Owen;URL:google.com;EMAIL:srowen@example.org;;",
"",
&vec!["Sean Owen"],
"",
&Vec::new(),
&vec!["srowen@example.org"],
&Vec::new(),
&Vec::new(),
"",
&vec!["google.com"],
"",
"ZXing Team",
);
}
#[test]
fn testAddressBookAU() {
doTest(
"MEMORY:foo\r\nNAME1:Sean\r\nTEL1:+12125551212\r\n",
"",
&vec!["Sean"],
"",
&Vec::new(),
&Vec::new(),
&vec!["+12125551212"],
&Vec::new(),
"",
&Vec::new(),
"",
"foo",
);
}
#[test]
fn testVCard() {
doTest(
"BEGIN:VCARD\r\nADR;HOME:123 Main St\r\nVERSION:2.1\r\nN:Owen;Sean\r\nEND:VCARD",
"",
&vec!["Sean Owen"],
"",
&vec!["123 Main St"],
&Vec::new(),
&Vec::new(),
&Vec::new(),
"",
&Vec::new(),
"",
"",
);
}
#[test]
fn testVCardFullN() {
doTest(
"BEGIN:VCARD\r\nVERSION:2.1\r\nN:Owen;Sean;T;Mr.;Esq.\r\nEND:VCARD",
"",
&vec!["Mr. Sean T Owen Esq."],
"",
&Vec::new(),
&Vec::new(),
&Vec::new(),
&Vec::new(),
"",
&Vec::new(),
"",
"",
);
}
#[test]
fn testVCardFullN2() {
doTest(
"BEGIN:VCARD\r\nVERSION:2.1\r\nN:Owen;Sean;;;\r\nEND:VCARD",
"",
&vec!["Sean Owen"],
"",
&Vec::new(),
&Vec::new(),
&Vec::new(),
&Vec::new(),
"",
&Vec::new(),
"",
"",
);
}
#[test]
fn testVCardFullN3() {
doTest(
"BEGIN:VCARD\r\nVERSION:2.1\r\nN:;Sean;;;\r\nEND:VCARD",
"",
&vec!["Sean"],
"",
&Vec::new(),
&Vec::new(),
&Vec::new(),
&Vec::new(),
"",
&Vec::new(),
"",
"",
);
}
#[test]
fn testVCardCaseInsensitive() {
doTest(
"begin:vcard\r\nadr;HOME:123 Main St\r\nVersion:2.1\r\nn:Owen;Sean\r\nEND:VCARD",
"",
&vec!["Sean Owen"],
"",
&vec!["123 Main St"],
&Vec::new(),
&Vec::new(),
&Vec::new(),
"",
&Vec::new(),
"",
"",
);
}
#[test]
fn testEscapedVCard() {
doTest("BEGIN:VCARD\r\nADR;HOME:123\\;\\\\ Main\\, St\\nHome\r\nVERSION:2.1\r\nN:Owen;Sean\r\nEND:VCARD",
"", &vec!["Sean Owen"], "", &vec!["123;\\ Main, St\nHome"],
&Vec::new(), &Vec::new(), &Vec::new(), "", &Vec::new(), "", "");
}
#[test]
fn testBizcard() {
doTest(
"BIZCARD:N:Sean;X:Owen;C:Google;A:123 Main St;M:+12125551212;E:srowen@example.org;",
"",
&vec!["Sean Owen"],
"",
&vec!["123 Main St"],
&vec!["srowen@example.org"],
&vec!["+12125551212"],
&Vec::new(),
"Google",
&Vec::new(),
"",
"",
);
}
#[test]
fn testSeveralAddresses() {
doTest("MECARD:N:Foo Bar;ORG:Company;TEL:5555555555;EMAIL:foo.bar@xyz.com;ADR:City, 10001;ADR:City, 10001;NOTE:This is the memo.;;",
"", &vec!["Foo Bar"], "", &vec!["City, 10001", "City, 10001"],
&vec!["foo.bar@xyz.com"],
&vec!["5555555555" ], &Vec::new(), "Company", &Vec::new(), "", "This is the memo.");
}
#[test]
fn testQuotedPrintable() {
doTest(
"BEGIN:VCARD\r\nADR;HOME;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:;;=38=38=20=4C=79=6E=62=72=6F=6F=6B=0D=0A=43=\r\n=4F=20=36=39=39=\r\n=39=39;;;\r\nEND:VCARD",
"",
&Vec::new(),
"",
&vec!["88 Lynbrook\r\nCO 69999"],
&Vec::new(),
&Vec::new(),
&Vec::new(),
"",
&Vec::new(),
"",
"",
);
}
#[test]
fn testVCardEscape() {
doTest(
"BEGIN:VCARD\r\nNOTE:foo\\nbar\r\nEND:VCARD",
"",
&Vec::new(),
"",
&Vec::new(),
&Vec::new(),
&Vec::new(),
&Vec::new(),
"",
&Vec::new(),
"",
"foo\nbar",
);
doTest(
"BEGIN:VCARD\r\nNOTE:foo\\;bar\r\nEND:VCARD",
"",
&Vec::new(),
"",
&Vec::new(),
&Vec::new(),
&Vec::new(),
&Vec::new(),
"",
&Vec::new(),
"",
"foo;bar",
);
doTest(
"BEGIN:VCARD\r\nNOTE:foo\\\\bar\r\nEND:VCARD",
"",
&Vec::new(),
"",
&Vec::new(),
&Vec::new(),
&Vec::new(),
&Vec::new(),
"",
&Vec::new(),
"",
"foo\\bar",
);
doTest(
"BEGIN:VCARD\r\nNOTE:foo\\,bar\r\nEND:VCARD",
"",
&Vec::new(),
"",
&Vec::new(),
&Vec::new(),
&Vec::new(),
&Vec::new(),
"",
&Vec::new(),
"",
"foo,bar",
);
}
#[test]
fn testVCardValueURI() {
doTest(
"BEGIN:VCARD\r\nTEL;VALUE=uri:tel:+1-555-555-1212\r\nEND:VCARD",
"",
&Vec::new(),
"",
&Vec::new(),
&Vec::new(),
&vec!["+1-555-555-1212"],
&vec![""],
"",
&Vec::new(),
"",
"",
);
doTest(
"BEGIN:VCARD\r\nN;VALUE=text:Owen;Sean\r\nEND:VCARD",
"",
&vec!["Sean Owen"],
"",
&Vec::new(),
&Vec::new(),
&Vec::new(),
&Vec::new(),
"",
&Vec::new(),
"",
"",
);
}
#[test]
fn testVCardTypes() {
doTest(
"BEGIN:VCARD\r\nTEL;HOME:\r\nTEL;WORK:10\r\nTEL:20\r\nTEL;CELL:30\r\nEND:VCARD",
"",
&Vec::new(),
"",
&Vec::new(),
&Vec::new(),
&vec!["10", "20", "30"],
&vec!["WORK", "", "CELL"],
"",
&Vec::new(),
"",
"",
);
}
fn doTest(
contents: &str,
title: &str,
names: &[&str],
pronunciation: &str,
addresses: &[&str],
emails: &[&str],
phoneNumbers: &[&str],
phoneTypes: &[&str],
org: &str,
urls: &[&str],
birthday: &str,
note: &str,
) {
let fakeRXingResult =
RXingResult::new(contents, Vec::new(), Vec::new(), BarcodeFormat::QR_CODE);
let result = ResultParser::parseRXingResult(&fakeRXingResult);
assert_eq!(ParsedRXingResultType::ADDRESSBOOK, result.getType());
if let ParsedClientResult::AddressBookResult(addressRXingResult) = result {
assert_eq!(title, addressRXingResult.getTitle());
assert_eq!(names, addressRXingResult.getNames());
assert_eq!(pronunciation, addressRXingResult.getPronunciation());
assert_eq!(addresses, addressRXingResult.getAddresses());
assert_eq!(emails, addressRXingResult.getEmails());
assert_eq!(phoneNumbers, addressRXingResult.getPhoneNumbers());
assert_eq!(phoneTypes, addressRXingResult.getPhoneTypes());
assert_eq!(org, addressRXingResult.getOrg());
assert_eq!(urls, addressRXingResult.getURLs());
assert_eq!(birthday, addressRXingResult.getBirthday());
assert_eq!(note, addressRXingResult.getNote());
} else {
panic!("Expected address book result");
}
}
// }

View File

@@ -164,7 +164,7 @@ pub fn maybe_append_multiple(value: &[String], result: &mut String) {
}
}
pub fn maybeWrap(value: Option<&str>) -> Option<Vec<String>> {
pub fn maybeWrap(value: Option<String>) -> Option<Vec<String>> {
if value.is_none() {
None
} else {

View File

@@ -14,45 +14,46 @@
* limitations under the License.
*/
package com.google.zxing.client.result;
// package com.google.zxing.client.result;
import com.google.zxing.RXingResult;
// 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;
// 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 crate::RXingResult;
use super::ParsedClientResult;
const BEGIN_VCARD : &'static str = "BEGIN:VCARD";//, Pattern.CASE_INSENSITIVE);
const VCARD_LIKE_DATE : &'static str = "\\d{4}-?\\d{2}-?\\d{2}";
const CR_LF_SPACE_TAB : &'static str = "\r\n[ \t]";
const NEWLINE_ESCAPE : &'static str = "\\\\[nN]";
const VCARD_ESCAPES : &'static str = "\\\\([,;\\\\])";
const EQUALS : &'static str = "=";
const SEMICOLON : &'static str = ";";
const UNESCAPED_SEMICOLONS : &'static str = "(?<!\\\\);+";
const COMMA : &'static str = ",";
const SEMICOLON_OR_COMMA : &'static str = "[;,]";
/**
* Parses contact information formatted according to the VCard (2.1) format. This is not a complete
* implementation but should parse information as commonly encoded in 2D barcodes.
*
* @author Sean Owen
*/
public final class VCardRXingResultParser extends RXingResultParser {
private static final Pattern BEGIN_VCARD = Pattern.compile("BEGIN:VCARD", Pattern.CASE_INSENSITIVE);
private static final Pattern VCARD_LIKE_DATE = Pattern.compile("\\d{4}-?\\d{2}-?\\d{2}");
private static final Pattern CR_LF_SPACE_TAB = Pattern.compile("\r\n[ \t]");
private static final Pattern NEWLINE_ESCAPE = Pattern.compile("\\\\[nN]");
private static final Pattern VCARD_ESCAPES = Pattern.compile("\\\\([,;\\\\])");
private static final Pattern EQUALS = Pattern.compile("=");
private static final Pattern SEMICOLON = Pattern.compile(";");
private static final Pattern UNESCAPED_SEMICOLONS = Pattern.compile("(?<!\\\\);+");
private static final Pattern COMMA = Pattern.compile(",");
private static final Pattern SEMICOLON_OR_COMMA = Pattern.compile("[;,]");
@Override
public AddressBookParsedRXingResult parse(RXingResult result) {
pub fn parse(result: &RXingResult) -> Option<ParsedClientResult> {
// Although we should insist on the raw text ending with "END:VCARD", there's no reason
// to throw out everything else we parsed just because this was omitted. In fact, Eclair
// is doing just that, and we can't parse its contacts without this leniency.
String rawText = getMassagedText(result);
let rawText = getMassagedText(result);
Matcher m = BEGIN_VCARD.matcher(rawText);
if (!m.find() || m.start() != 0) {
return null;
@@ -100,10 +101,10 @@ public final class VCardRXingResultParser extends RXingResultParser {
geo);
}
static List<List<String>> matchVCardPrefixedField(CharSequence prefix,
String rawText,
boolean trim,
boolean parseFieldDivider) {
fn matchVCardPrefixedField( prefix:&str,
rawText:&str,
trim:bool,
parseFieldDivider:bool) -> Vec<String> {
List<List<String>> matches = null;
int i = 0;
int max = rawText.length();
@@ -220,7 +221,7 @@ public final class VCardRXingResultParser extends RXingResultParser {
return matches;
}
private static String decodeQuotedPrintable(CharSequence value, String charset) {
fn decodeQuotedPrintable( value:&str, charset:&str) -> String{
int length = value.length();
StringBuilder result = new StringBuilder(length);
ByteArrayOutputStream fragmentBuffer = new ByteArrayOutputStream();
@@ -253,9 +254,9 @@ public final class VCardRXingResultParser extends RXingResultParser {
return result.toString();
}
private static void maybeAppendFragment(ByteArrayOutputStream fragmentBuffer,
String charset,
StringBuilder result) {
fn maybeAppendFragment( fragmentBuffer &Vec<u8>,
charset:&str,
result:&mut String) {
if (fragmentBuffer.size() > 0) {
byte[] fragmentBytes = fragmentBuffer.toByteArray();
String fragment;
@@ -273,19 +274,19 @@ public final class VCardRXingResultParser extends RXingResultParser {
}
}
static List<String> matchSingleVCardPrefixedField(CharSequence prefix,
String rawText,
boolean trim,
boolean parseFieldDivider) {
fn matchSingleVCardPrefixedField( prefix:&str,
rawText:&str,
trim :bool,
parseFieldDivider:bool)->Vec<String> {
List<List<String>> values = matchVCardPrefixedField(prefix, rawText, trim, parseFieldDivider);
return values == null || values.isEmpty() ? null : values.get(0);
}
private static String toPrimaryValue(List<String> list) {
fn toPrimaryValue(list:&Vec<String>) -> String{
return list == null || list.isEmpty() ? null : list.get(0);
}
private static String[] toPrimaryValues(Collection<List<String>> lists) {
fn toPrimaryValues( lists:&Vec<String>) -> Vec<String>{
if (lists == null || lists.isEmpty()) {
return null;
}
@@ -299,7 +300,7 @@ public final class VCardRXingResultParser extends RXingResultParser {
return result.toArray(EMPTY_STR_ARRAY);
}
private static String[] toTypes(Collection<List<String>> lists) {
fn toTypes( lists: &Vec<String>) -> Vec<String>{
if (lists == null || lists.isEmpty()) {
return null;
}
@@ -327,7 +328,7 @@ public final class VCardRXingResultParser extends RXingResultParser {
return result.toArray(EMPTY_STR_ARRAY);
}
private static boolean isLikeVCardDate(CharSequence value) {
fn isLikeVCardDate( value:&str) -> bool{
return value == null || VCARD_LIKE_DATE.matcher(value).matches();
}
@@ -337,21 +338,22 @@ public final class VCardRXingResultParser extends RXingResultParser {
*
* @param names name values to format, in place
*/
private static void formatNames(Iterable<List<String>> names) {
if (names != null) {
for (List<String> list : names) {
String name = list.get(0);
String[] components = new String[5];
int start = 0;
int end;
int componentIndex = 0;
while (componentIndex < components.length - 1 && (end = name.indexOf(';', start)) >= 0) {
fn formatNames( names : &mut Vec<String>) {
if !names.is_empty() {
for list in names {
// for (List<String> list : names) {
let name = list.get(0);
let components = vec!["";5];
let start = 0;
let end;
let componentIndex = 0;
while componentIndex < components.len() - 1 && (end = name.indexOf(';', start)) >= 0 {
components[componentIndex] = name.substring(start, end);
componentIndex++;
componentIndex+=1;
start = end + 1;
}
components[componentIndex] = name.substring(start);
StringBuilder newName = new StringBuilder(100);
let newName = String::with_capacity(100);
maybeAppendComponent(components, 3, newName);
maybeAppendComponent(components, 1, newName);
maybeAppendComponent(components, 2, newName);
@@ -362,13 +364,11 @@ public final class VCardRXingResultParser extends RXingResultParser {
}
}
private static void maybeAppendComponent(String[] components, int i, StringBuilder newName) {
if (components[i] != null && !components[i].isEmpty()) {
if (newName.length() > 0) {
newName.append(' ');
fn maybeAppendComponent( components : &Vec<String>, i:usize, newName:&mut String) {
if !components[i].is_empty() {
if newName.len() > 0 {
newName.push(' ');
}
newName.append(components[i]);
newName.push_str(&components[i]);
}
}
}

View File

@@ -26,6 +26,11 @@ mod EmailDoCoMoResultParser;
mod SMTPResultParser;
mod VINParsedResult;
mod VINResultParser;
mod AddressBookParsedResult;
mod AddressBookDoCoMoResultParser;
mod AddressBookAUResultParser;
mod VCardResultParser;
mod AddressBookParsedResultTestCase;
use std::fmt;
@@ -46,6 +51,7 @@ pub use ProductParsedResult::*;
pub use URIParsedResult::*;
pub use EmailAddressParsedResult::*;
pub use VINParsedResult::*;
pub use AddressBookParsedResult::*;
#[cfg(test)]
mod TelParsedResultTestCase;
@@ -77,6 +83,7 @@ pub enum ParsedClientResult {
URIResult(URIParsedRXingResult),
EmailResult(EmailAddressParsedRXingResult),
VINResult(VINParsedRXingResult),
AddressBookResult(AddressBookParsedRXingResult),
}
impl ParsedRXingResult for ParsedClientResult {
@@ -92,6 +99,7 @@ impl ParsedRXingResult for ParsedClientResult {
ParsedClientResult::URIResult(a) => a.getType(),
ParsedClientResult::EmailResult(a) => a.getType(),
ParsedClientResult::VINResult(a) => a.getType(),
ParsedClientResult::AddressBookResult(a) => a.getType(),
}
@@ -109,6 +117,7 @@ impl ParsedRXingResult for ParsedClientResult {
ParsedClientResult::URIResult(a) => a.getDisplayRXingResult(),
ParsedClientResult::EmailResult(a) => a.getDisplayRXingResult(),
ParsedClientResult::VINResult(a) => a.getDisplayRXingResult(),
ParsedClientResult::AddressBookResult(a) => a.getDisplayRXingResult(),