diff --git a/src/client/result/EmailAddressParsedResult.java b/src/client/result/EmailAddressParsedResult.java deleted file mode 100644 index f76c70b..0000000 --- a/src/client/result/EmailAddressParsedResult.java +++ /dev/null @@ -1,99 +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 an email message including recipients, subject - * and body text. - * - * @author Sean Owen - */ -public final class EmailAddressParsedRXingResult extends ParsedRXingResult { - - private final String[] tos; - private final String[] ccs; - private final String[] bccs; - private final String subject; - private final String body; - - EmailAddressParsedRXingResult(String to) { - this(new String[] {to}, null, null, null, null); - } - - EmailAddressParsedRXingResult(String[] tos, - String[] ccs, - String[] bccs, - String subject, - String body) { - super(ParsedRXingResultType.EMAIL_ADDRESS); - this.tos = tos; - this.ccs = ccs; - this.bccs = bccs; - this.subject = subject; - this.body = body; - } - - /** - * @return first elements of {@link #getTos()} or {@code null} if none - * @deprecated use {@link #getTos()} - */ - @Deprecated - public String getEmailAddress() { - return tos == null || tos.length == 0 ? null : tos[0]; - } - - public String[] getTos() { - return tos; - } - - public String[] getCCs() { - return ccs; - } - - public String[] getBCCs() { - return bccs; - } - - public String getSubject() { - return subject; - } - - public String getBody() { - return body; - } - - /** - * @return "mailto:" - * @deprecated without replacement - */ - @Deprecated - public String getMailtoURI() { - return "mailto:"; - } - - @Override - public String getDisplayRXingResult() { - StringBuilder result = new StringBuilder(30); - maybeAppend(tos, result); - maybeAppend(ccs, result); - maybeAppend(bccs, result); - maybeAppend(subject, result); - maybeAppend(body, result); - return result.toString(); - } - -} \ No newline at end of file diff --git a/src/client/result/EmailAddressParsedResult.rs b/src/client/result/EmailAddressParsedResult.rs new file mode 100644 index 0000000..14ed4d7 --- /dev/null +++ b/src/client/result/EmailAddressParsedResult.rs @@ -0,0 +1,120 @@ +/* + * 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 super::{maybe_append_string, ParsedRXingResult, ParsedRXingResultType, ResultParser}; + +/** + * Represents a parsed result that encodes an email message including recipients, subject + * and body text. + * + * @author Sean Owen + */ +pub struct EmailAddressParsedRXingResult { + tos: Vec, + ccs: Vec, + bccs: Vec, + subject: String, + body: String, +} +impl ParsedRXingResult for EmailAddressParsedRXingResult { + fn getType(&self) -> super::ParsedRXingResultType { + ParsedRXingResultType::EMAIL_ADDRESS + } + + fn getDisplayRXingResult(&self) -> String { + let mut result = String::with_capacity(30); + ResultParser::maybe_append_multiple(&self.tos, &mut result); + ResultParser::maybe_append_multiple(&self.ccs, &mut result); + ResultParser::maybe_append_multiple(&self.bccs, &mut result); + ResultParser::maybe_append_string(&self.subject, &mut result); + ResultParser::maybe_append_string(&self.body, &mut result); + + result + } +} + +impl EmailAddressParsedRXingResult { + pub fn new(to: String) -> Self { + Self::with_details( + vec![to], + Vec::new(), + Vec::new(), + "".to_owned(), + "".to_owned(), + ) + } + + pub fn with_details( + tos: Vec, + ccs: Vec, + bccs: Vec, + subject: String, + body: String, + ) -> Self { + Self { + tos, + ccs, + bccs, + subject, + body, + } + } + + /** + * @return first elements of {@link #getTos()} or {@code null} if none + * @deprecated use {@link #getTos()} + */ + #[deprecated] + pub fn getEmailAddress(&self) -> &str { + if self.tos.is_empty() { + "" + } else { + &self.tos[0] + } + // return tos == null || tos.length == 0 ? null : tos[0]; + } + + pub fn getTos(&self) -> &[String] { + &self.tos + } + + pub fn getCCs(&self) -> &[String] { + &self.ccs + } + + pub fn getBCCs(&self) -> &[String] { + &self.bccs + } + + pub fn getSubject(&self) -> &str { + &self.subject + } + + pub fn getBody(&self) -> &str { + &self.body + } + + /** + * @return "mailto:" + * @deprecated without replacement + */ + #[deprecated] + pub fn getMailtoURI() -> &'static str { + "mailto:" + } +} diff --git a/src/client/result/EmailAddressParsedResultTestCase.java b/src/client/result/EmailAddressParsedResultTestCase.java deleted file mode 100644 index 6509879..0000000 --- a/src/client/result/EmailAddressParsedResultTestCase.java +++ /dev/null @@ -1,121 +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 EmailAddressParsedRXingResult}. - * - * @author Sean Owen - */ -public final class EmailAddressParsedRXingResultTestCase extends Assert { - - @Test - public void testEmailAddress() { - doTest("srowen@example.org", "srowen@example.org", null, null); - doTest("mailto:srowen@example.org", "srowen@example.org", null, null); - } - - @Test - public void testTos() { - doTest("mailto:srowen@example.org,bob@example.org", - new String[] {"srowen@example.org", "bob@example.org"}, - null, null, null, null); - doTest("mailto:?to=srowen@example.org,bob@example.org", - new String[] {"srowen@example.org", "bob@example.org"}, - null, null, null, null); - } - - @Test - public void testCCs() { - doTest("mailto:?cc=srowen@example.org", - null, - new String[] {"srowen@example.org"}, - null, null, null); - doTest("mailto:?cc=srowen@example.org,bob@example.org", - null, - new String[] {"srowen@example.org", "bob@example.org"}, - null, null, null); - } - - @Test - public void testBCCs() { - doTest("mailto:?bcc=srowen@example.org", - null, null, - new String[] {"srowen@example.org"}, - null, null); - doTest("mailto:?bcc=srowen@example.org,bob@example.org", - null, null, - new String[] {"srowen@example.org", "bob@example.org"}, - null, null); - } - - @Test - public void testAll() { - doTest("mailto:bob@example.org?cc=foo@example.org&bcc=srowen@example.org&subject=baz&body=buzz", - new String[] {"bob@example.org"}, - new String[] {"foo@example.org"}, - new String[] {"srowen@example.org"}, - "baz", - "buzz"); - } - - @Test - public void testEmailDocomo() { - doTest("MATMSG:TO:srowen@example.org;;", "srowen@example.org", null, null); - doTest("MATMSG:TO:srowen@example.org;SUB:Stuff;;", "srowen@example.org", "Stuff", null); - doTest("MATMSG:TO:srowen@example.org;SUB:Stuff;BODY:This is some text;;", "srowen@example.org", - "Stuff", "This is some text"); - } - - @Test - public void testSMTP() { - doTest("smtp:srowen@example.org", "srowen@example.org", null, null); - doTest("SMTP:srowen@example.org", "srowen@example.org", null, null); - doTest("smtp:srowen@example.org:foo", "srowen@example.org", "foo", null); - doTest("smtp:srowen@example.org:foo:bar", "srowen@example.org", "foo", "bar"); - } - - private static void doTest(String contents, - String to, - String subject, - String body) { - doTest(contents, new String[] {to}, null, null, subject, body); - } - - private static void doTest(String contents, - String[] tos, - String[] ccs, - String[] bccs, - String subject, - String body) { - RXingResult fakeRXingResult = new RXingResult(contents, null, null, BarcodeFormat.QR_CODE); - ParsedRXingResult result = RXingResultParser.parseRXingResult(fakeRXingResult); - assertSame(ParsedRXingResultType.EMAIL_ADDRESS, result.getType()); - EmailAddressParsedRXingResult emailRXingResult = (EmailAddressParsedRXingResult) result; - assertArrayEquals(tos, emailRXingResult.getTos()); - assertArrayEquals(ccs, emailRXingResult.getCCs()); - assertArrayEquals(bccs, emailRXingResult.getBCCs()); - assertEquals(subject, emailRXingResult.getSubject()); - assertEquals(body, emailRXingResult.getBody()); - } - -} \ No newline at end of file diff --git a/src/client/result/EmailAddressParsedResultTestCase.rs b/src/client/result/EmailAddressParsedResultTestCase.rs new file mode 100644 index 0000000..6510e61 --- /dev/null +++ b/src/client/result/EmailAddressParsedResultTestCase.rs @@ -0,0 +1,171 @@ +/* + * 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; + +use crate::{ + client::result::{ParsedClientResult, ParsedRXingResultType, ResultParser, ParsedRXingResult}, + BarcodeFormat, RXingResult, +}; + +/** + * Tests {@link EmailAddressParsedRXingResult}. + * + * @author Sean Owen + */ + +#[test] +fn testEmailAddress() { + do_test_single("srowen@example.org", "srowen@example.org", "", ""); + do_test_single("mailto:srowen@example.org", "srowen@example.org", "", ""); +} + +#[test] +fn testTos() { + do_test( + "mailto:srowen@example.org,bob@example.org", + &vec!["srowen@example.org", "bob@example.org"], + &Vec::new(), + &Vec::new(), + "", + "", + ); + do_test( + "mailto:?to=srowen@example.org,bob@example.org", + &vec!["srowen@example.org", "bob@example.org"], + &Vec::new(), + &Vec::new(), + "", + "", + ); +} + +#[test] +fn testCCs() { + do_test( + "mailto:?cc=srowen@example.org", + &Vec::new(), + &vec!["srowen@example.org"], + &Vec::new(), + "", + "", + ); + do_test( + "mailto:?cc=srowen@example.org,bob@example.org", + &Vec::new(), + &vec!["srowen@example.org", "bob@example.org"], + &Vec::new(), + "", + "", + ); +} + +#[test] +fn testBCCs() { + do_test( + "mailto:?bcc=srowen@example.org", + &Vec::new(), + &Vec::new(), + &vec!["srowen@example.org"], + "", + "", + ); + do_test( + "mailto:?bcc=srowen@example.org,bob@example.org", + &Vec::new(), + &Vec::new(), + &vec!["srowen@example.org", "bob@example.org"], + "", + "", + ); +} + +#[test] +fn testAll() { + do_test( + "mailto:bob@example.org?cc=foo@example.org&bcc=srowen@example.org&subject=baz&body=buzz", + &vec!["bob@example.org"], + &vec!["foo@example.org"], + &vec!["srowen@example.org"], + "baz", + "buzz", + ); +} + +#[test] +fn testEmailDocomo() { + do_test_single( + "MATMSG:TO:srowen@example.org;;", + "srowen@example.org", + "", + "", + ); + do_test_single( + "MATMSG:TO:srowen@example.org;SUB:Stuff;;", + "srowen@example.org", + "Stuff", + "", + ); + do_test_single( + "MATMSG:TO:srowen@example.org;SUB:Stuff;BODY:This is some text;;", + "srowen@example.org", + "Stuff", + "This is some text", + ); +} + +#[test] +fn testSMTP() { + do_test_single("smtp:srowen@example.org", "srowen@example.org", "", ""); + do_test_single("SMTP:srowen@example.org", "srowen@example.org", "", ""); + do_test_single( + "smtp:srowen@example.org:foo", + "srowen@example.org", + "foo", + "", + ); + do_test_single( + "smtp:srowen@example.org:foo:bar", + "srowen@example.org", + "foo", + "bar", + ); +} + +fn do_test_single(contents: &str, to: &str, subject: &str, body: &str) { + do_test(contents, &vec![to], &Vec::new(), &Vec::new(), subject, body); +} + +fn do_test(contents: &str, tos: &[&str], ccs: &[&str], bccs: &[&str], subject: &str, body: &str) { + let fakeRXingResult = + RXingResult::new(contents, Vec::new(), Vec::new(), BarcodeFormat::QR_CODE); + let result = ResultParser::parseRXingResult(&fakeRXingResult); + assert_eq!(ParsedRXingResultType::EMAIL_ADDRESS, result.getType()); + if let ParsedClientResult::EmailResult(emailRXingResult) = result { + assert_eq!(tos, emailRXingResult.getTos()); + assert_eq!(ccs, emailRXingResult.getCCs()); + assert_eq!(bccs, emailRXingResult.getBCCs()); + assert_eq!(subject, emailRXingResult.getSubject()); + assert_eq!(body, emailRXingResult.getBody()); + } else { + panic!("Expected EmailResult"); + } +} diff --git a/src/client/result/EmailAddressResultParser.java b/src/client/result/EmailAddressResultParser.java deleted file mode 100644 index 5a380f8..0000000 --- a/src/client/result/EmailAddressResultParser.java +++ /dev/null @@ -1,85 +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; - -import java.util.Map; -import java.util.regex.Pattern; - -/** - * Represents a result that encodes an e-mail address, either as a plain address - * like "joe@example.org" or a mailto: URL like "mailto:joe@example.org". - * - * @author Sean Owen - */ -public final class EmailAddressRXingResultParser extends RXingResultParser { - - private static final Pattern COMMA = Pattern.compile(","); - - @Override - public EmailAddressParsedRXingResult parse(RXingResult result) { - String rawText = getMassagedText(result); - if (rawText.startsWith("mailto:") || rawText.startsWith("MAILTO:")) { - // If it starts with mailto:, assume it is definitely trying to be an email address - String hostEmail = rawText.substring(7); - int queryStart = hostEmail.indexOf('?'); - if (queryStart >= 0) { - hostEmail = hostEmail.substring(0, queryStart); - } - try { - hostEmail = urlDecode(hostEmail); - } catch (IllegalArgumentException iae) { - return null; - } - String[] tos = null; - if (!hostEmail.isEmpty()) { - tos = COMMA.split(hostEmail); - } - Map nameValues = parseNameValuePairs(rawText); - String[] ccs = null; - String[] bccs = null; - String subject = null; - String body = null; - if (nameValues != null) { - if (tos == null) { - String tosString = nameValues.get("to"); - if (tosString != null) { - tos = COMMA.split(tosString); - } - } - String ccString = nameValues.get("cc"); - if (ccString != null) { - ccs = COMMA.split(ccString); - } - String bccString = nameValues.get("bcc"); - if (bccString != null) { - bccs = COMMA.split(bccString); - } - subject = nameValues.get("subject"); - body = nameValues.get("body"); - } - return new EmailAddressParsedRXingResult(tos, ccs, bccs, subject, body); - } else { - if (!EmailDoCoMoRXingResultParser.isBasicallyValidEmailAddress(rawText)) { - return null; - } - return new EmailAddressParsedRXingResult(rawText); - } - } - -} \ No newline at end of file diff --git a/src/client/result/EmailAddressResultParser.rs b/src/client/result/EmailAddressResultParser.rs new file mode 100644 index 0000000..f62fec8 --- /dev/null +++ b/src/client/result/EmailAddressResultParser.rs @@ -0,0 +1,106 @@ +/* + * 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; + +// import java.util.Map; +// import java.util.regex.Pattern; + +use regex::Regex; + +use crate::RXingResult; + +use super::{ParsedClientResult, ResultParser, EmailDoCoMoResultParser, EmailAddressParsedRXingResult}; + +/** + * Represents a result that encodes an e-mail address, either as a plain address + * like "joe@example.org" or a mailto: URL like "mailto:joe@example.org". + * + * @author Sean Owen + */ + pub fn parse(result: &RXingResult) -> Option { + let comma_regex = Regex::new(",").unwrap(); + // private static final Pattern COMMA = Pattern.compile(","); + let rawText = ResultParser::getMassagedText(result); + if rawText.starts_with("mailto:") || rawText.starts_with("MAILTO:") { + // If it starts with mailto:, assume it is definitely trying to be an email address + let mut hostEmail = &rawText[7..]; + if let Some(queryStart) = hostEmail.find('?'){ + hostEmail = &hostEmail[..queryStart]; + } + // int queryStart = hostEmail.indexOf('?'); + // if (queryStart >= 0) { + // hostEmail = hostEmail.substring(0, queryStart); + // } + // try { + let tmp = if let Ok(res) = ResultParser::urlDecode(hostEmail){ + res + }else { + return None; + }; + hostEmail = tmp.as_str(); + // } catch (IllegalArgumentException iae) { + // return null; + // } + let mut tos = if hostEmail.is_empty() { + Vec::new() + }else { + comma_regex.split(hostEmail).into_iter().map(|s| s.to_owned()).collect() + }; + // if (!hostEmail.isEmpty()) { + // tos = COMMA.split(hostEmail); + // } + let nameValues = ResultParser::parseNameValuePairs(&rawText); + let mut ccs:Vec = Vec::new(); + let mut bccs:Vec = Vec::new(); + let mut subject = "".to_owned(); + let mut body = "".to_owned(); + if let Some(nv) = nameValues { + // if (nameValues != null) { + if tos.is_empty() { + if let Some(tosString) = nv.get("to"){ + tos = comma_regex.split(tosString).into_iter().map(|s| s.to_owned()).collect(); + } + // if tosString != null { + // tos = COMMA.split(tosString); + // } + } + if let Some(ccString) = nv.get("cc"){ + ccs = comma_regex.split(ccString).into_iter().map(|s| s.to_owned()).collect(); + } + // if ccString != null { + // ccs = COMMA.split(ccString); + // } + if let Some(bccString) = nv.get("bcc"){ + bccs = comma_regex.split(bccString).into_iter().map(|s| s.to_owned()).collect(); + } + // if bccString != null { + // bccs = COMMA.split(bccString); + // } + subject = nv.get("subject").unwrap_or(&"".to_owned()).clone(); + body = nv.get("body").unwrap_or(&"".to_owned()).clone(); + } + return Some(ParsedClientResult::EmailResult(EmailAddressParsedRXingResult::with_details(tos, ccs, bccs, subject.to_owned(), body.to_owned()))); + } else { + let atext_alphanumeric = Regex::new("[a-zA-Z0-9@.!#$%&'*+\\-/=?^_`{|}~]+").unwrap(); + if !EmailDoCoMoResultParser::isBasicallyValidEmailAddress(&rawText,&atext_alphanumeric) { + return None; + } + return Some(ParsedClientResult::EmailResult(EmailAddressParsedRXingResult::new(rawText))); + } + } diff --git a/src/client/result/EmailDoCoMoResultParser.java b/src/client/result/EmailDoCoMoResultParser.java deleted file mode 100644 index d5ac692..0000000 --- a/src/client/result/EmailDoCoMoResultParser.java +++ /dev/null @@ -1,64 +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; - -import java.util.regex.Pattern; - -/** - * Implements the "MATMSG" email message entry format. - * - * Supported keys: TO, SUB, BODY - * - * @author Sean Owen - */ -public final class EmailDoCoMoRXingResultParser extends AbstractDoCoMoRXingResultParser { - - private static final Pattern ATEXT_ALPHANUMERIC = Pattern.compile("[a-zA-Z0-9@.!#$%&'*+\\-/=?^_`{|}~]+"); - - @Override - public EmailAddressParsedRXingResult parse(RXingResult result) { - String rawText = getMassagedText(result); - if (!rawText.startsWith("MATMSG:")) { - return null; - } - String[] tos = matchDoCoMoPrefixedField("TO:", rawText); - if (tos == null) { - return null; - } - for (String to : tos) { - if (!isBasicallyValidEmailAddress(to)) { - return null; - } - } - String subject = matchSingleDoCoMoPrefixedField("SUB:", rawText, false); - String body = matchSingleDoCoMoPrefixedField("BODY:", rawText, false); - return new EmailAddressParsedRXingResult(tos, null, null, subject, body); - } - - /** - * This implements only the most basic checking for an email address's validity -- that it contains - * an '@' and contains no characters disallowed by RFC 2822. This is an overly lenient definition of - * validity. We want to generally be lenient here since this class is only intended to encapsulate what's - * in a barcode, not "judge" it. - */ - static boolean isBasicallyValidEmailAddress(String email) { - return email != null && ATEXT_ALPHANUMERIC.matcher(email).matches() && email.indexOf('@') >= 0; - } - -} diff --git a/src/client/result/EmailDoCoMoResultParser.rs b/src/client/result/EmailDoCoMoResultParser.rs new file mode 100644 index 0000000..957c78a --- /dev/null +++ b/src/client/result/EmailDoCoMoResultParser.rs @@ -0,0 +1,71 @@ +/* + * 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; + +// import java.util.regex.Pattern; + +use regex::Regex; + +use crate::RXingResult; + +use super::{ParsedClientResult, ResultParser, EmailAddressParsedRXingResult}; + +/** + * Implements the "MATMSG" email message entry format. + * + * Supported keys: TO, SUB, BODY + * + * @author Sean Owen + */ + pub fn parse(result: &RXingResult) -> Option { + let atext_alphanumeric = Regex::new("[a-zA-Z0-9@.!#$%&'*+\\-/=?^_`{|}~]+").unwrap(); + + let rawText = ResultParser::getMassagedText(result); + if !rawText.starts_with("MATMSG:") { + return None; + } + let tos = ResultParser::match_do_co_mo_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).unwrap_or_default(); + let body = ResultParser::match_single_do_co_mo_prefixed_field("BODY:", &rawText, false).unwrap_or_default(); +Some(ParsedClientResult::EmailResult(EmailAddressParsedRXingResult::with_details(tos, Vec::new(), Vec::new(), subject, body))) + } + + /** + * This implements only the most basic checking for an email address's validity -- that it contains + * an '@' and contains no characters disallowed by RFC 2822. This is an overly lenient definition of + * validity. We want to generally be lenient here since this class is only intended to encapsulate what's + * in a barcode, not "judge" it. + */ + pub fn isBasicallyValidEmailAddress( email:&str, regex:&Regex)-> bool { + let email_exists = !email.is_empty(); + let email_has_at = matches!(email.find('@'),Some(_)); + let email_alphamatcher = if let Some(mtch) = regex.find(email) { + mtch.start() ==0 && mtch.end() == email.len() + }else{ + false + }; + email_exists && email_alphamatcher && email_has_at + // return email != null && ATEXT_ALPHANUMERIC.matcher(email).matches() && email.indexOf('@') >= 0; + } diff --git a/src/client/result/ResultParser.rs b/src/client/result/ResultParser.rs index 3ba8d4b..c90b426 100644 --- a/src/client/result/ResultParser.rs +++ b/src/client/result/ResultParser.rs @@ -34,9 +34,10 @@ use urlencoding::decode; use crate::{exceptions::Exceptions, RXingResult}; use super::{ - BookmarkDoCoMoResultParser, GeoResultParser, ISBNResultParser, ParsedClientResult, - ParsedRXingResult, ProductResultParser, SMSMMSResultParser, TelResultParser, - TextParsedRXingResult, URIResultParser, URLTOResultParser, WifiResultParser, + BookmarkDoCoMoResultParser, EmailAddressResultParser, EmailDoCoMoResultParser, GeoResultParser, + ISBNResultParser, ParsedClientResult, ParsedRXingResult, ProductResultParser, + SMSMMSResultParser, SMTPResultParser, TelResultParser, TextParsedRXingResult, URIResultParser, + URLTOResultParser, WifiResultParser, }; /** @@ -103,16 +104,16 @@ pub fn getMassagedText(result: &RXingResult) -> String { } pub fn parseRXingResult(theRXingResult: &RXingResult) -> ParsedClientResult { - let PARSERS: [&ParserFunction; 10] = [ + let PARSERS: [&ParserFunction; 13] = [ &BookmarkDoCoMoResultParser::parse, // new AddressBookDoCoMoRXingResultParser(), - // new EmailDoCoMoRXingResultParser(), + &EmailDoCoMoResultParser::parse, // new AddressBookAURXingResultParser(), // new VCardRXingResultParser(), // new BizcardRXingResultParser(), // new VEventRXingResultParser(), - // new EmailAddressRXingResultParser(), - // new SMTPRXingResultParser(), + &EmailAddressResultParser::parse, + &SMTPResultParser::parse, &TelResultParser::parse, &SMSMMSResultParser::parse, &SMSMMSResultParser::parse, diff --git a/src/client/result/SMTPResultParser.java b/src/client/result/SMTPResultParser.java deleted file mode 100644 index 7f83a95..0000000 --- a/src/client/result/SMTPResultParser.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2010 ZXing authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.zxing.client.result; - -import com.google.zxing.RXingResult; - -/** - *

Parses an "smtp:" URI result, whose format is not standardized but appears to be like: - * {@code smtp[:subject[:body]]}.

- * - * @author Sean Owen - */ -public final class SMTPRXingResultParser extends RXingResultParser { - - @Override - public EmailAddressParsedRXingResult parse(RXingResult result) { - String rawText = getMassagedText(result); - if (!(rawText.startsWith("smtp:") || rawText.startsWith("SMTP:"))) { - return null; - } - String emailAddress = rawText.substring(5); - String subject = null; - String body = null; - int 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); - } - } - return new EmailAddressParsedRXingResult(new String[] {emailAddress}, - null, - null, - subject, - body); - } -} diff --git a/src/client/result/SMTPResultParser.rs b/src/client/result/SMTPResultParser.rs new file mode 100644 index 0000000..12834bc --- /dev/null +++ b/src/client/result/SMTPResultParser.rs @@ -0,0 +1,63 @@ +/* + * Copyright 2010 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// package com.google.zxing.client.result; + +// import com.google.zxing.RXingResult; + +use crate::RXingResult; + +use super::{ResultParser, ParsedClientResult, EmailAddressParsedRXingResult}; + +/** + *

Parses an "smtp:" URI result, whose format is not standardized but appears to be like: + * {@code smtp[:subject[:body]]}.

+ * + * @author Sean Owen + */ +pub fn parse(result: &RXingResult) -> Option { + let rawText = ResultParser::getMassagedText(result); + if !(rawText.starts_with("smtp:") || rawText.starts_with("SMTP:")) { + return None; + } + let mut emailAddress = &rawText[5..]; + let mut subject = ""; + let mut body = ""; + if let Some(colon) = emailAddress.find(':') { + subject = &emailAddress[colon+1..]; + emailAddress = &emailAddress[..colon]; + if let Some(new_colon) = subject.find(':') { + body = &subject[new_colon+1..]; + 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()],Vec::new(), Vec::new(), subject.to_owned(), body.to_owned()))) + // return new EmailAddressParsedRXingResult(new String[] {emailAddress}, + // null, + // null, + // subject, + // body); + } diff --git a/src/client/result/mod.rs b/src/client/result/mod.rs index 2683029..b815c72 100644 --- a/src/client/result/mod.rs +++ b/src/client/result/mod.rs @@ -20,6 +20,10 @@ mod URLTOResultParser; mod AbstractDoCoMoResultParser; mod BookmarkDoCoMoResultParser; mod SMSTOMMSTOResultParser; +mod EmailAddressParsedResult; +mod EmailAddressResultParser; +mod EmailDoCoMoResultParser; +mod SMTPResultParser; use std::fmt; @@ -38,6 +42,7 @@ pub use GeoParsedResult::*; pub use SMSParsedResult::*; pub use ProductParsedResult::*; pub use URIParsedResult::*; +pub use EmailAddressParsedResult::*; #[cfg(test)] mod TelParsedResultTestCase; @@ -53,6 +58,8 @@ mod SMSMMSParsedResultTestCase; mod ProductParsedResultTestCase; #[cfg(test)] mod URIParsedResultTestCase; +#[cfg(test)] +mod EmailAddressParsedResultTestCase; pub enum ParsedClientResult { TextResult(TextParsedRXingResult), @@ -63,6 +70,7 @@ pub enum ParsedClientResult { SMSResult(SMSParsedRXingResult), ProductResult(ProductParsedRXingResult), URIResult(URIParsedRXingResult), + EmailResult(EmailAddressParsedRXingResult), } impl ParsedRXingResult for ParsedClientResult { @@ -76,6 +84,7 @@ impl ParsedRXingResult for ParsedClientResult { ParsedClientResult::SMSResult(a) => a.getType(), ParsedClientResult::ProductResult(a) => a.getType(), ParsedClientResult::URIResult(a) => a.getType(), + ParsedClientResult::EmailResult(a) => a.getType(), } @@ -91,6 +100,7 @@ impl ParsedRXingResult for ParsedClientResult { ParsedClientResult::SMSResult(a) => a.getDisplayRXingResult(), ParsedClientResult::ProductResult(a) => a.getDisplayRXingResult(), ParsedClientResult::URIResult(a) => a.getDisplayRXingResult(), + ParsedClientResult::EmailResult(a) => a.getDisplayRXingResult(),