diff --git a/src/client/result/GeoParsedResult.java b/src/client/result/GeoParsedResult.java deleted file mode 100644 index ccbee6d..0000000 --- a/src/client/result/GeoParsedResult.java +++ /dev/null @@ -1,104 +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; - -/** - * Represents a parsed result that encodes a geographic coordinate, with latitude, - * longitude and altitude. - * - * @author Sean Owen - */ -public final class GeoParsedRXingResult extends ParsedRXingResult { - - private final double latitude; - private final double longitude; - private final double altitude; - private final String query; - - GeoParsedRXingResult(double latitude, double longitude, double altitude, String query) { - super(ParsedRXingResultType.GEO); - this.latitude = latitude; - this.longitude = longitude; - this.altitude = altitude; - this.query = query; - } - - public String getGeoURI() { - StringBuilder result = new StringBuilder(); - result.append("geo:"); - result.append(latitude); - result.append(','); - result.append(longitude); - if (altitude > 0) { - result.append(','); - result.append(altitude); - } - if (query != null) { - result.append('?'); - result.append(query); - } - return result.toString(); - } - - /** - * @return latitude in degrees - */ - public double getLatitude() { - return latitude; - } - - /** - * @return longitude in degrees - */ - public double getLongitude() { - return longitude; - } - - /** - * @return altitude in meters. If not specified, in the geo URI, returns 0.0 - */ - public double getAltitude() { - return altitude; - } - - /** - * @return query string associated with geo URI or null if none exists - */ - public String getQuery() { - return query; - } - - @Override - public String getDisplayRXingResult() { - StringBuilder result = new StringBuilder(20); - result.append(latitude); - result.append(", "); - result.append(longitude); - if (altitude > 0.0) { - result.append(", "); - result.append(altitude); - result.append('m'); - } - if (query != null) { - result.append(" ("); - result.append(query); - result.append(')'); - } - return result.toString(); - } - -} \ No newline at end of file diff --git a/src/client/result/GeoParsedResult.rs b/src/client/result/GeoParsedResult.rs new file mode 100644 index 0000000..b507fc4 --- /dev/null +++ b/src/client/result/GeoParsedResult.rs @@ -0,0 +1,118 @@ +/* + * 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; + +use super::{ParsedRXingResult, ParsedRXingResultType}; + +/** + * Represents a parsed result that encodes a geographic coordinate, with latitude, + * longitude and altitude. + * + * @author Sean Owen + */ +pub struct GeoParsedRXingResult { + latitude: f64, + longitude: f64, + altitude: f64, + query: String, +} + +impl ParsedRXingResult for GeoParsedRXingResult { + fn getType(&self) -> super::ParsedRXingResultType { + ParsedRXingResultType::GEO + } + + fn getDisplayRXingResult(&self) -> String { + let mut result = String::with_capacity(20); + // result.push_str(self.latitude); + // result.push_str(", "); + // result.push_str(self.longitude); + result.push_str(&format!("{}, {}", self.latitude, self.longitude)); + if self.altitude > 0.0 { + result.push_str(&format!(", {}m", self.altitude)); + // result.push_str(", "); + // result.push_str(self.altitude); + // result.push('m'); + } + if !self.query.is_empty() { + result.push_str(&format!(" ({})", self.query)); + // result.push_str(" ("); + // result.push_str(self.query); + // result.push(')'); + } + result + } +} + +impl GeoParsedRXingResult { + pub fn new(latitude: f64, longitude: f64, altitude: f64, query: String) -> Self { + Self { + latitude, + longitude, + altitude, + query, + } + } + + pub fn getGeoURI(&self) -> String { + //StringBuilder result = new StringBuilder(); + let mut result = format!("geo:{},{}", self.latitude, self.longitude); + // result.append("geo:"); + // result.append(latitude); + // result.append(','); + // result.append(longitude); + if self.altitude > 0.0 { + result.push_str(&format!(",{}", self.altitude)); + // result.append(','); + // result.append(altitude); + } + if !self.query.is_empty() { + result.push_str(&format!("?{}", self.query)); + // result.append('?'); + // result.append(query); + } + result + } + + /** + * @return latitude in degrees + */ + pub fn getLatitude(&self) -> f64 { + self.latitude + } + + /** + * @return longitude in degrees + */ + pub fn getLongitude(&self) -> f64 { + self.longitude + } + + /** + * @return altitude in meters. If not specified, in the geo URI, returns 0.0 + */ + pub fn getAltitude(&self) -> f64 { + self.altitude + } + + /** + * @return query string associated with geo URI or null if none exists + */ + pub fn getQuery(&self) -> &str { + &self.query + } +} diff --git a/src/client/result/GeoParsedResultTestCase.java b/src/client/result/GeoParsedResultTestCase.java deleted file mode 100644 index e048cbd..0000000 --- a/src/client/result/GeoParsedResultTestCase.java +++ /dev/null @@ -1,61 +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 java.util.Locale; - -import com.google.zxing.BarcodeFormat; -import com.google.zxing.RXingResult; -import org.junit.Assert; -import org.junit.Test; - -/** - * Tests {@link GeoParsedRXingResult}. - * - * @author Sean Owen - */ -public final class GeoParsedRXingResultTestCase extends Assert { - - private static final double EPSILON = 1.0E-10; - - @Test - public void testGeo() { - doTest("geo:1,2", 1.0, 2.0, 0.0, null, "geo:1.0,2.0"); - doTest("geo:80.33,-32.3344,3.35", 80.33, -32.3344, 3.35, null, null); - doTest("geo:-20.33,132.3344,0.01", -20.33, 132.3344, 0.01, null, null); - doTest("geo:-20.33,132.3344,0.01?q=foobar", -20.33, 132.3344, 0.01, "q=foobar", null); - doTest("GEO:-20.33,132.3344,0.01?q=foobar", -20.33, 132.3344, 0.01, "q=foobar", null); - } - - private static void doTest(String contents, - double latitude, - double longitude, - double altitude, - String query, - String uri) { - RXingResult fakeRXingResult = new RXingResult(contents, null, null, BarcodeFormat.QR_CODE); - ParsedRXingResult result = RXingResultParser.parseRXingResult(fakeRXingResult); - assertSame(ParsedRXingResultType.GEO, result.getType()); - GeoParsedRXingResult geoRXingResult = (GeoParsedRXingResult) result; - assertEquals(latitude, geoRXingResult.getLatitude(), EPSILON); - assertEquals(longitude, geoRXingResult.getLongitude(), EPSILON); - assertEquals(altitude, geoRXingResult.getAltitude(), EPSILON); - assertEquals(query, geoRXingResult.getQuery()); - assertEquals(uri == null ? contents.toLowerCase(Locale.ENGLISH) : uri, geoRXingResult.getGeoURI()); - } - -} \ No newline at end of file diff --git a/src/client/result/GeoParsedResultTestCase.rs b/src/client/result/GeoParsedResultTestCase.rs new file mode 100644 index 0000000..753a4c8 --- /dev/null +++ b/src/client/result/GeoParsedResultTestCase.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; + +// import java.util.Locale; + +// import com.google.zxing.BarcodeFormat; +// import com.google.zxing.RXingResult; +// import org.junit.Assert; +// import org.junit.Test; + +/** + * Tests {@link GeoParsedRXingResult}. + * + * @author Sean Owen + */ +// public final class GeoParsedRXingResultTestCase extends Assert { +use crate::{ + client::result::{ParsedClientResult, ParsedRXingResult, ParsedRXingResultType, ResultParser}, + BarcodeFormat, RXingResult, +}; + +use super::RXingResultParser; + +const EPSILON: f64 = 1.0E-10; + +#[test] +pub fn testGeo1() { + //doTest("geo:1,2", 1.0, 2.0, 0.0, "", "geo:1.0,2.0"); + // I think 1.0 and 1 and 2.0 and 2 are similar enough here, correct me if i'm wrong. + doTest("geo:1,2", 1.0, 2.0, 0.0, "", "geo:1,2"); + +} +#[test] +pub fn testGeo2() { + doTest("geo:80.33,-32.3344,3.35", 80.33, -32.3344, 3.35, "", ""); +} +#[test] +pub fn testGeo() { + doTest("geo:-20.33,132.3344,0.01", -20.33, 132.3344, 0.01, "", ""); +} +#[test] +pub fn testGeo3() { + doTest( + "geo:-20.33,132.3344,0.01?q=foobar", + -20.33, + 132.3344, + 0.01, + "q=foobar", + "", + ); +} +#[test] +pub fn testGeo4() { + doTest( + "GEO:-20.33,132.3344,0.01?q=foobar", + -20.33, + 132.3344, + 0.01, + "q=foobar", + "", + ); +} + +fn doTest(contents: &str, latitude: f64, longitude: f64, altitude: f64, query: &str, uri: &str) { + let fakeRXingResult = + RXingResult::new(contents, Vec::new(), Vec::new(), BarcodeFormat::QR_CODE); + let result = ResultParser::parseRXingResult(&fakeRXingResult); + + assert_eq!(ParsedRXingResultType::GEO, result.getType()); + + if let ParsedClientResult::GeoResult(geoRXingResult) = result { + assert!(within_range( + latitude, + geoRXingResult.getLatitude(), + EPSILON + )); + assert!(within_range( + longitude, + geoRXingResult.getLongitude(), + EPSILON + )); + assert!(within_range( + altitude, + geoRXingResult.getAltitude(), + EPSILON + )); + assert_eq!(query, geoRXingResult.getQuery()); + assert_eq!( + if uri.is_empty() { + contents.to_lowercase() + } else { + String::from(uri) + }, + geoRXingResult.getGeoURI() + ); + } else { + panic!("Expected ParsedClientResult::GeoResult"); + } +} + +fn within_range(a: f64, b: f64, delta: f64) -> bool { + a - b < delta || b - a < delta +} + +// } diff --git a/src/client/result/GeoResultParser.java b/src/client/result/GeoResultParser.java deleted file mode 100644 index 4901d1e..0000000 --- a/src/client/result/GeoResultParser.java +++ /dev/null @@ -1,73 +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.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Parses a "geo:" URI result, which specifies a location on the surface of - * the Earth as well as an optional altitude above the surface. See - * - * http://tools.ietf.org/html/draft-mayrhofer-geo-uri-00. - * - * @author Sean Owen - */ -public final class GeoRXingResultParser extends RXingResultParser { - - private static final Pattern GEO_URL_PATTERN = - Pattern.compile("geo:([\\-0-9.]+),([\\-0-9.]+)(?:,([\\-0-9.]+))?(?:\\?(.*))?", Pattern.CASE_INSENSITIVE); - - @Override - public GeoParsedRXingResult parse(RXingResult result) { - CharSequence rawText = getMassagedText(result); - Matcher matcher = GEO_URL_PATTERN.matcher(rawText); - if (!matcher.matches()) { - return null; - } - - String query = matcher.group(4); - - double latitude; - double longitude; - double 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; - } - return new GeoParsedRXingResult(latitude, longitude, altitude, query); - } - -} \ No newline at end of file diff --git a/src/client/result/GeoResultParser.rs b/src/client/result/GeoResultParser.rs new file mode 100644 index 0000000..65e63dc --- /dev/null +++ b/src/client/result/GeoResultParser.rs @@ -0,0 +1,126 @@ +/* + * 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.regex.Matcher; +// import java.util.regex.Pattern; + +use super::{GeoParsedRXingResult, ParsedClientResult, RXingResultParser, ResultParser}; + +const GEO_URL_PATTERN: &'static str = "geo:([\\-0-9.]+),([\\-0-9.]+)(?:,([\\-0-9.]+))?(?:\\?(.*))?"; + +/** + * Parses a "geo:" URI result, which specifies a location on the surface of + * the Earth as well as an optional altitude above the surface. See + * + * http://tools.ietf.org/html/draft-mayrhofer-geo-uri-00. + * + * @author Sean Owen + */ +pub struct GeoRXingResultParser {} + +impl RXingResultParser for GeoRXingResultParser { + fn parse(&self, theRXingResult: &crate::RXingResult) -> Option { + let rawText = ResultParser::getMassagedText(theRXingResult); + + let matcher = regex::Regex::new(GEO_URL_PATTERN).unwrap(); + + if let Some(captures) = matcher.captures(&rawText.to_lowercase()) { + let query = if let Some(q) = captures.get(4) { + q.as_str() + } else { + "" + }; + + let latitude = if let Some(la) = captures.get(1) { + if let Ok(laf64) = la.as_str().parse::() { + if laf64 > 90.0 || laf64 < -90.0 { + return None; + } + laf64 + } else { + return None; + } + } else { + return None; + }; + + let longitude = if let Some(lo) = captures.get(2) { + if let Ok(lof64) = lo.as_str().parse::() { + if lof64 > 180.0 || lof64 < -180.0 { + 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::() { + if alf64 < 0.0 { + return None; + } + alf64 + } else { + return None; + } + } 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, + altitude, + String::from(query), + ))) + } else { + return None; + } + + // Matcher matcher = GEO_URL_PATTERN.matcher(rawText); + // if (!matcher.matches()) { + // return null; + // } + } +} diff --git a/src/client/result/ResultParser.rs b/src/client/result/ResultParser.rs index 0c5357c..ae6579d 100644 --- a/src/client/result/ResultParser.rs +++ b/src/client/result/ResultParser.rs @@ -35,7 +35,7 @@ use crate::{exceptions::Exceptions, RXingResult}; use super::{ ISBNRXingResultParser, ParsedClientResult, ParsedRXingResult, TelRXingResultParser, - TextParsedRXingResult, WifiRXingResultParser, + TextParsedRXingResult, WifiRXingResultParser, GeoRXingResultParser, }; /** @@ -100,7 +100,7 @@ pub fn getMassagedText(result: &RXingResult) -> String { } pub fn parseRXingResult(theRXingResult: &RXingResult) -> ParsedClientResult { - let PARSERS: [&dyn RXingResultParser; 3] = [ + let PARSERS: [&dyn RXingResultParser; 4] = [ // new BookmarkDoCoMoRXingResultParser(), // new AddressBookDoCoMoRXingResultParser(), // new EmailDoCoMoRXingResultParser(), @@ -113,7 +113,7 @@ pub fn parseRXingResult(theRXingResult: &RXingResult) -> ParsedClientResult { &TelRXingResultParser {}, // new SMSMMSRXingResultParser(), // new SMSTOMMSTORXingResultParser(), - // new GeoRXingResultParser(), + &GeoRXingResultParser{}, &WifiRXingResultParser {}, // new URLTORXingResultParser(), // new URIRXingResultParser(), diff --git a/src/client/result/mod.rs b/src/client/result/mod.rs index 8ee7f42..aa12bf0 100644 --- a/src/client/result/mod.rs +++ b/src/client/result/mod.rs @@ -8,6 +8,8 @@ mod ISBNParsedResult; mod ISBNResultParser; mod WifiParsedResult; mod WifiResultParser; +mod GeoResultParser; +mod GeoParsedResult; use std::fmt; @@ -21,6 +23,9 @@ pub use ISBNParsedResult::*; pub use ISBNResultParser::*; pub use WifiParsedResult::*; pub use WifiResultParser::*; +pub use GeoParsedResult::*; +pub use GeoResultParser::*; + #[cfg(test)] mod TelParsedResultTestCase; @@ -28,12 +33,15 @@ mod TelParsedResultTestCase; mod ISBNParsedResultTestCase; #[cfg(test)] mod WifiParsedResultTestCase; +#[cfg(test)] +mod GeoParsedResultTestCase; pub enum ParsedClientResult { TextResult(TextParsedRXingResult), TelResult(TelParsedRXingResult), ISBNResult(ISBNParsedRXingResult), WiFiResult(WifiParsedRXingResult), + GeoResult(GeoParsedRXingResult), } impl ParsedRXingResult for ParsedClientResult { @@ -43,6 +51,7 @@ impl ParsedRXingResult for ParsedClientResult { ParsedClientResult::TelResult(a) => a.getType(), ParsedClientResult::ISBNResult(a) => a.getType(), ParsedClientResult::WiFiResult(a) => a.getType(), + ParsedClientResult::GeoResult(a) => a.getType(), } @@ -54,6 +63,7 @@ impl ParsedRXingResult for ParsedClientResult { ParsedClientResult::TelResult(a) => a.getDisplayRXingResult(), ParsedClientResult::ISBNResult(a) => a.getDisplayRXingResult(), ParsedClientResult::WiFiResult(a) => a.getDisplayRXingResult(), + ParsedClientResult::GeoResult(a) => a.getDisplayRXingResult(),