mirror of
https://github.com/starovoid/rxing.git
synced 2026-07-28 05:12:34 +00:00
Calendar events ported not passing
This commit is contained in:
@@ -15,6 +15,7 @@ encoding = "0.2"
|
|||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
urlencoding = "2.1.2"
|
urlencoding = "2.1.2"
|
||||||
uriparse = "0.6.4"
|
uriparse = "0.6.4"
|
||||||
|
chrono = "0.4.22"
|
||||||
image = {version = "0.24.3", optional = true}
|
image = {version = "0.24.3", optional = true}
|
||||||
imageproc = {version = "0.23.0", optional = true}
|
imageproc = {version = "0.23.0", optional = true}
|
||||||
|
|
||||||
|
|||||||
@@ -1,259 +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 java.text.DateFormat;
|
|
||||||
import java.text.ParseException;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.GregorianCalendar;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.TimeZone;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a parsed result that encodes a calendar event at a certain time, optionally
|
|
||||||
* with attendees and a location.
|
|
||||||
*
|
|
||||||
* @author Sean Owen
|
|
||||||
*/
|
|
||||||
public final class CalendarParsedRXingResult extends ParsedRXingResult {
|
|
||||||
|
|
||||||
private static final Pattern RFC2445_DURATION =
|
|
||||||
Pattern.compile("P(?:(\\d+)W)?(?:(\\d+)D)?(?:T(?:(\\d+)H)?(?:(\\d+)M)?(?:(\\d+)S)?)?");
|
|
||||||
private static final long[] RFC2445_DURATION_FIELD_UNITS = {
|
|
||||||
7 * 24 * 60 * 60 * 1000L, // 1 week
|
|
||||||
24 * 60 * 60 * 1000L, // 1 day
|
|
||||||
60 * 60 * 1000L, // 1 hour
|
|
||||||
60 * 1000L, // 1 minute
|
|
||||||
1000L, // 1 second
|
|
||||||
};
|
|
||||||
|
|
||||||
private static final Pattern DATE_TIME = Pattern.compile("[0-9]{8}(T[0-9]{6}Z?)?");
|
|
||||||
|
|
||||||
private final String summary;
|
|
||||||
private final long start;
|
|
||||||
private final boolean startAllDay;
|
|
||||||
private final long end;
|
|
||||||
private final boolean endAllDay;
|
|
||||||
private final String location;
|
|
||||||
private final String organizer;
|
|
||||||
private final String[] attendees;
|
|
||||||
private final String description;
|
|
||||||
private final double latitude;
|
|
||||||
private final double longitude;
|
|
||||||
|
|
||||||
public CalendarParsedRXingResult(String summary,
|
|
||||||
String startString,
|
|
||||||
String endString,
|
|
||||||
String durationString,
|
|
||||||
String location,
|
|
||||||
String organizer,
|
|
||||||
String[] attendees,
|
|
||||||
String description,
|
|
||||||
double latitude,
|
|
||||||
double longitude) {
|
|
||||||
super(ParsedRXingResultType.CALENDAR);
|
|
||||||
this.summary = summary;
|
|
||||||
|
|
||||||
try {
|
|
||||||
this.start = parseDate(startString);
|
|
||||||
} catch (ParseException pe) {
|
|
||||||
throw new IllegalArgumentException(pe.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (endString == null) {
|
|
||||||
long durationMS = parseDurationMS(durationString);
|
|
||||||
end = durationMS < 0L ? -1L : start + durationMS;
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
this.end = parseDate(endString);
|
|
||||||
} catch (ParseException pe) {
|
|
||||||
throw new IllegalArgumentException(pe.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.startAllDay = startString.length() == 8;
|
|
||||||
this.endAllDay = endString != null && endString.length() == 8;
|
|
||||||
|
|
||||||
this.location = location;
|
|
||||||
this.organizer = organizer;
|
|
||||||
this.attendees = attendees;
|
|
||||||
this.description = description;
|
|
||||||
this.latitude = latitude;
|
|
||||||
this.longitude = longitude;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSummary() {
|
|
||||||
return summary;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return start time
|
|
||||||
* @deprecated use {@link #getStartTimestamp()}
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public Date getStart() {
|
|
||||||
return new Date(start);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return start time
|
|
||||||
* @see #getEndTimestamp()
|
|
||||||
*/
|
|
||||||
public long getStartTimestamp() {
|
|
||||||
return start;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return true if start time was specified as a whole day
|
|
||||||
*/
|
|
||||||
public boolean isStartAllDay() {
|
|
||||||
return startAllDay;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return event end {@link Date}, or {@code null} if event has no duration
|
|
||||||
* @deprecated use {@link #getEndTimestamp()}
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public Date getEnd() {
|
|
||||||
return end < 0L ? null : new Date(end);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return event end {@link Date}, or -1 if event has no duration
|
|
||||||
* @see #getStartTimestamp()
|
|
||||||
*/
|
|
||||||
public long getEndTimestamp() {
|
|
||||||
return end;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return true if end time was specified as a whole day
|
|
||||||
*/
|
|
||||||
public boolean isEndAllDay() {
|
|
||||||
return endAllDay;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLocation() {
|
|
||||||
return location;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getOrganizer() {
|
|
||||||
return organizer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String[] getAttendees() {
|
|
||||||
return attendees;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDescription() {
|
|
||||||
return description;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getLatitude() {
|
|
||||||
return latitude;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getLongitude() {
|
|
||||||
return longitude;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getDisplayRXingResult() {
|
|
||||||
StringBuilder result = new StringBuilder(100);
|
|
||||||
maybeAppend(summary, result);
|
|
||||||
maybeAppend(format(startAllDay, start), result);
|
|
||||||
maybeAppend(format(endAllDay, end), result);
|
|
||||||
maybeAppend(location, result);
|
|
||||||
maybeAppend(organizer, result);
|
|
||||||
maybeAppend(attendees, result);
|
|
||||||
maybeAppend(description, result);
|
|
||||||
return result.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses a string as a date. RFC 2445 allows the start and end fields to be of type DATE (e.g. 20081021)
|
|
||||||
* or DATE-TIME (e.g. 20081021T123000 for local time, or 20081021T123000Z for UTC).
|
|
||||||
*
|
|
||||||
* @param when The string to parse
|
|
||||||
* @throws ParseException if not able to parse as a date
|
|
||||||
*/
|
|
||||||
private static long parseDate(String when) throws ParseException {
|
|
||||||
if (!DATE_TIME.matcher(when).matches()) {
|
|
||||||
throw new ParseException(when, 0);
|
|
||||||
}
|
|
||||||
if (when.length() == 8) {
|
|
||||||
// Show only year/month/day
|
|
||||||
DateFormat format = new SimpleDateFormat("yyyyMMdd", Locale.ENGLISH);
|
|
||||||
// For dates without a time, for purposes of interacting with Android, the resulting timestamp
|
|
||||||
// needs to be midnight of that day in GMT. See:
|
|
||||||
// http://code.google.com/p/android/issues/detail?id=8330
|
|
||||||
format.setTimeZone(TimeZone.getTimeZone("GMT"));
|
|
||||||
return format.parse(when).getTime();
|
|
||||||
}
|
|
||||||
// The when string can be local time, or UTC if it ends with a Z
|
|
||||||
if (when.length() == 16 && when.charAt(15) == 'Z') {
|
|
||||||
long milliseconds = parseDateTimeString(when.substring(0, 15));
|
|
||||||
Calendar calendar = new GregorianCalendar();
|
|
||||||
// Account for time zone difference
|
|
||||||
milliseconds += calendar.get(Calendar.ZONE_OFFSET);
|
|
||||||
// Might need to correct for daylight savings time, but use target time since
|
|
||||||
// now might be in DST but not then, or vice versa
|
|
||||||
calendar.setTime(new Date(milliseconds));
|
|
||||||
return milliseconds + calendar.get(Calendar.DST_OFFSET);
|
|
||||||
}
|
|
||||||
return parseDateTimeString(when);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String format(boolean allDay, long date) {
|
|
||||||
if (date < 0L) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
DateFormat format = allDay
|
|
||||||
? DateFormat.getDateInstance(DateFormat.MEDIUM)
|
|
||||||
: DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
|
|
||||||
return format.format(date);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static long parseDurationMS(CharSequence durationString) {
|
|
||||||
if (durationString == null) {
|
|
||||||
return -1L;
|
|
||||||
}
|
|
||||||
Matcher m = RFC2445_DURATION.matcher(durationString);
|
|
||||||
if (!m.matches()) {
|
|
||||||
return -1L;
|
|
||||||
}
|
|
||||||
long durationMS = 0L;
|
|
||||||
for (int i = 0; i < RFC2445_DURATION_FIELD_UNITS.length; i++) {
|
|
||||||
String fieldValue = m.group(i + 1);
|
|
||||||
if (fieldValue != null) {
|
|
||||||
durationMS += RFC2445_DURATION_FIELD_UNITS[i] * Integer.parseInt(fieldValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return durationMS;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static long parseDateTimeString(String dateTimeString) throws ParseException {
|
|
||||||
DateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.ENGLISH);
|
|
||||||
return format.parse(dateTimeString).getTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
313
src/client/result/CalendarParsedResult.rs
Normal file
313
src/client/result/CalendarParsedResult.rs
Normal file
@@ -0,0 +1,313 @@
|
|||||||
|
/*
|
||||||
|
* 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 java.text.DateFormat;
|
||||||
|
// import java.text.ParseException;
|
||||||
|
// import java.text.SimpleDateFormat;
|
||||||
|
// import java.util.Calendar;
|
||||||
|
// import java.util.Date;
|
||||||
|
// import java.util.GregorianCalendar;
|
||||||
|
// import java.util.Locale;
|
||||||
|
// import java.util.TimeZone;
|
||||||
|
// import java.util.regex.Matcher;
|
||||||
|
// import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
use chrono::{DateTime, NaiveDateTime, Utc};
|
||||||
|
use regex::Regex;
|
||||||
|
|
||||||
|
use crate::exceptions::Exceptions;
|
||||||
|
|
||||||
|
use super::{
|
||||||
|
maybe_append_multiple, maybe_append_string, ParsedRXingResult, ParsedRXingResultType,
|
||||||
|
ResultParser,
|
||||||
|
};
|
||||||
|
|
||||||
|
const RFC2445_DURATION: &'static str =
|
||||||
|
"P(?:(\\d+)W)?(?:(\\d+)D)?(?:T(?:(\\d+)H)?(?:(\\d+)M)?(?:(\\d+)S)?)?";
|
||||||
|
const RFC2445_DURATION_FIELD_UNITS: [i64; 5] = [
|
||||||
|
7 * 24 * 60 * 60 * 1000i64, // 1 week
|
||||||
|
24 * 60 * 60 * 1000i64, // 1 day
|
||||||
|
60 * 60 * 1000i64, // 1 hour
|
||||||
|
60 * 1000i64, // 1 minute
|
||||||
|
1000i64, // 1 second
|
||||||
|
];
|
||||||
|
|
||||||
|
const DATE_TIME: &'static str = "[0-9]{8}(T[0-9]{6}Z?)?";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a parsed result that encodes a calendar event at a certain time, optionally
|
||||||
|
* with attendees and a location.
|
||||||
|
*
|
||||||
|
* @author Sean Owen
|
||||||
|
*/
|
||||||
|
pub struct CalendarParsedRXingResult {
|
||||||
|
summary: String,
|
||||||
|
start: i64,
|
||||||
|
startAllDay: bool,
|
||||||
|
end: i64,
|
||||||
|
endAllDay: bool,
|
||||||
|
location: String,
|
||||||
|
organizer: String,
|
||||||
|
attendees: Vec<String>,
|
||||||
|
description: String,
|
||||||
|
latitude: f64,
|
||||||
|
longitude: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ParsedRXingResult for CalendarParsedRXingResult {
|
||||||
|
fn getType(&self) -> super::ParsedRXingResultType {
|
||||||
|
ParsedRXingResultType::CALENDAR
|
||||||
|
}
|
||||||
|
|
||||||
|
fn getDisplayRXingResult(&self) -> String {
|
||||||
|
let mut result = String::with_capacity(100);
|
||||||
|
maybe_append_string(&self.summary, &mut result);
|
||||||
|
maybe_append_string(
|
||||||
|
&Self::format_event(self.startAllDay, self.start),
|
||||||
|
&mut result,
|
||||||
|
);
|
||||||
|
maybe_append_string(&Self::format_event(self.endAllDay, self.end), &mut result);
|
||||||
|
maybe_append_string(&self.location, &mut result);
|
||||||
|
maybe_append_string(&self.organizer, &mut result);
|
||||||
|
maybe_append_multiple(&self.attendees, &mut result);
|
||||||
|
maybe_append_string(&self.description, &mut result);
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CalendarParsedRXingResult {
|
||||||
|
pub fn new(
|
||||||
|
summary: String,
|
||||||
|
startString: String,
|
||||||
|
endString: String,
|
||||||
|
durationString: String,
|
||||||
|
location: String,
|
||||||
|
organizer: String,
|
||||||
|
attendees: Vec<String>,
|
||||||
|
description: String,
|
||||||
|
latitude: f64,
|
||||||
|
longitude: f64,
|
||||||
|
) -> Result<Self, Exceptions> {
|
||||||
|
let start = Self::parseDate(startString.clone())?;
|
||||||
|
let end = if endString.is_empty() {
|
||||||
|
let durationMS = Self::parseDurationMS(&durationString);
|
||||||
|
if durationMS < 0i64 {
|
||||||
|
-1i64
|
||||||
|
} else {
|
||||||
|
start + durationMS
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Self::parseDate(endString.clone())?
|
||||||
|
};
|
||||||
|
let startAllDay;
|
||||||
|
let endAllDay;
|
||||||
|
|
||||||
|
// try {
|
||||||
|
// this.start = parseDate(startString);
|
||||||
|
// } catch (ParseException pe) {
|
||||||
|
// throw new IllegalArgumentException(pe.toString());
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (endString == null) {
|
||||||
|
// long durationMS = parseDurationMS(durationString);
|
||||||
|
// end = durationMS < 0L ? -1L : start + durationMS;
|
||||||
|
// } else {
|
||||||
|
// try {
|
||||||
|
// this.end = parseDate(endString);
|
||||||
|
// } catch (ParseException pe) {
|
||||||
|
// throw new IllegalArgumentException(pe.toString());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
startAllDay = startString.len() == 8;
|
||||||
|
endAllDay = !endString.is_empty() && endString.len() == 8;
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
summary,
|
||||||
|
start,
|
||||||
|
startAllDay,
|
||||||
|
end,
|
||||||
|
endAllDay,
|
||||||
|
location,
|
||||||
|
organizer,
|
||||||
|
attendees,
|
||||||
|
description,
|
||||||
|
latitude,
|
||||||
|
longitude,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a string as a date. RFC 2445 allows the start and end fields to be of type DATE (e.g. 20081021)
|
||||||
|
* or DATE-TIME (e.g. 20081021T123000 for local time, or 20081021T123000Z for UTC).
|
||||||
|
*
|
||||||
|
* @param when The string to parse
|
||||||
|
* @throws ParseException if not able to parse as a date
|
||||||
|
*/
|
||||||
|
fn parseDate(when: String) -> Result<i64, Exceptions> {
|
||||||
|
let date_time_regex = Regex::new(DATE_TIME).unwrap();
|
||||||
|
if !date_time_regex.is_match(&when) {
|
||||||
|
return Err(Exceptions::ParseException(when));
|
||||||
|
}
|
||||||
|
if when.len() == 8 {
|
||||||
|
// Show only year/month/day
|
||||||
|
let date_format_string = "%Y%m%d";
|
||||||
|
// DateFormat format = new SimpleDateFormat("yyyyMMdd", Locale.ENGLISH);
|
||||||
|
// For dates without a time, for purposes of interacting with Android, the resulting timestamp
|
||||||
|
// needs to be midnight of that day in GMT. See:
|
||||||
|
// http://code.google.com/p/android/issues/detail?id=8330
|
||||||
|
let dtm = DateTime::parse_from_str(&when, date_format_string).unwrap();
|
||||||
|
let dtm = dtm.with_timezone(&Utc);
|
||||||
|
|
||||||
|
// format.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||||
|
// return format.parse(when).getTime();
|
||||||
|
return Ok(dtm.timestamp());
|
||||||
|
}
|
||||||
|
// The when string can be local time, or UTC if it ends with a Z
|
||||||
|
if when.len() == 16 && when.chars().nth(15).unwrap() == 'Z' {
|
||||||
|
let milliseconds = Self::parseDateTimeString(&when[0..15]);
|
||||||
|
// Calendar calendar = new GregorianCalendar();
|
||||||
|
// // Account for time zone difference
|
||||||
|
// milliseconds += calendar.get(Calendar.ZONE_OFFSET);
|
||||||
|
// // Might need to correct for daylight savings time, but use target time since
|
||||||
|
// // now might be in DST but not then, or vice versa
|
||||||
|
// calendar.setTime(new Date(milliseconds));
|
||||||
|
// return milliseconds + calendar.get(Calendar.DST_OFFSET);
|
||||||
|
return milliseconds;
|
||||||
|
}
|
||||||
|
Self::parseDateTimeString(&when)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn format_event(allDay: bool, date: i64) -> String {
|
||||||
|
if date < 0 {
|
||||||
|
return "".to_owned();
|
||||||
|
}
|
||||||
|
let format_string = if allDay { "%F" } else { "%c" };
|
||||||
|
// DateFormat format = allDay
|
||||||
|
// ? DateFormat.getDateInstance(DateFormat.MEDIUM)
|
||||||
|
// : DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
|
||||||
|
// return format.format(date);
|
||||||
|
NaiveDateTime::from_timestamp(date, 0)
|
||||||
|
.format(format_string)
|
||||||
|
.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parseDurationMS(durationString: &str) -> i64 {
|
||||||
|
if durationString.is_empty() {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
let regex = Regex::new(RFC2445_DURATION).unwrap();
|
||||||
|
if let Some(m) = regex.captures(durationString) {
|
||||||
|
let mut durationMS = 0i64;
|
||||||
|
for i in 0..RFC2445_DURATION_FIELD_UNITS.len() {
|
||||||
|
// for (int i = 0; i < RFC2445_DURATION_FIELD_UNITS.length; i++) {
|
||||||
|
let fieldValue = m.get(i + 1);
|
||||||
|
if fieldValue.is_some() {
|
||||||
|
let z = fieldValue.unwrap().as_str().parse::<i64>().unwrap();
|
||||||
|
durationMS += RFC2445_DURATION_FIELD_UNITS[i] * z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
durationMS
|
||||||
|
} else {
|
||||||
|
-1
|
||||||
|
}
|
||||||
|
// if (!m.matches()) {
|
||||||
|
// return -1L;
|
||||||
|
// }
|
||||||
|
// long durationMS = 0L;
|
||||||
|
// for (int i = 0; i < RFC2445_DURATION_FIELD_UNITS.length; i++) {
|
||||||
|
// String fieldValue = m.group(i + 1);
|
||||||
|
// if (fieldValue != null) {
|
||||||
|
// durationMS += RFC2445_DURATION_FIELD_UNITS[i] * Integer.parseInt(fieldValue);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return durationMS;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parseDateTimeString(dateTimeString: &str) -> Result<i64, Exceptions> {
|
||||||
|
if let Ok(dtm) = DateTime::parse_from_str(dateTimeString, "%Y%m%dT%H%M%S") {
|
||||||
|
Ok(dtm.timestamp())
|
||||||
|
} else {
|
||||||
|
Err(Exceptions::ParseException(format!(
|
||||||
|
"Couldn't parse {}",
|
||||||
|
dateTimeString
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
// DateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.ENGLISH);
|
||||||
|
// return format.parse(dateTimeString).getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getSummary(&self) -> &String {
|
||||||
|
&self.summary
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return start time
|
||||||
|
* @see #getEndTimestamp()
|
||||||
|
*/
|
||||||
|
pub fn getStartTimestamp(&self) -> i64 {
|
||||||
|
self.start
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if start time was specified as a whole day
|
||||||
|
*/
|
||||||
|
pub fn isStartAllDay(&self) -> bool {
|
||||||
|
self.startAllDay
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return event end {@link Date}, or -1 if event has no duration
|
||||||
|
* @see #getStartTimestamp()
|
||||||
|
*/
|
||||||
|
pub fn getEndTimestamp(&self) -> i64 {
|
||||||
|
self.end
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if end time was specified as a whole day
|
||||||
|
*/
|
||||||
|
pub fn isEndAllDay(&self) -> bool {
|
||||||
|
self.endAllDay
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getLocation(&self) -> &str {
|
||||||
|
&self.location
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getOrganizer(&self) -> &str {
|
||||||
|
&self.organizer
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getAttendees(&self) -> &Vec<String> {
|
||||||
|
&self.attendees
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getDescription(&self) -> &str {
|
||||||
|
&self.description
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getLatitude(&self) -> f64 {
|
||||||
|
self.latitude
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getLongitude(&self) -> f64 {
|
||||||
|
self.longitude
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,250 +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.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import java.text.DateFormat;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.TimeZone;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests {@link CalendarParsedRXingResult}.
|
|
||||||
*
|
|
||||||
* @author Sean Owen
|
|
||||||
*/
|
|
||||||
public final class CalendarParsedRXingResultTestCase extends Assert {
|
|
||||||
|
|
||||||
private static final double EPSILON = 1.0E-10;
|
|
||||||
|
|
||||||
private static DateFormat makeGMTFormat() {
|
|
||||||
DateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'", Locale.ENGLISH);
|
|
||||||
format.setTimeZone(TimeZone.getTimeZone("GMT"));
|
|
||||||
return format;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() {
|
|
||||||
Locale.setDefault(Locale.ENGLISH);
|
|
||||||
TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testStartEnd() {
|
|
||||||
doTest(
|
|
||||||
"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\n" +
|
|
||||||
"DTSTART:20080504T123456Z\r\n" +
|
|
||||||
"DTEND:20080505T234555Z\r\n" +
|
|
||||||
"END:VEVENT\r\nEND:VCALENDAR",
|
|
||||||
null, null, null, "20080504T123456Z", "20080505T234555Z");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNoVCalendar() {
|
|
||||||
doTest(
|
|
||||||
"BEGIN:VEVENT\r\n" +
|
|
||||||
"DTSTART:20080504T123456Z\r\n" +
|
|
||||||
"DTEND:20080505T234555Z\r\n" +
|
|
||||||
"END:VEVENT",
|
|
||||||
null, null, null, "20080504T123456Z", "20080505T234555Z");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testStart() {
|
|
||||||
doTest(
|
|
||||||
"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\n" +
|
|
||||||
"DTSTART:20080504T123456Z\r\n" +
|
|
||||||
"END:VEVENT\r\nEND:VCALENDAR",
|
|
||||||
null, null, null, "20080504T123456Z", null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDuration() {
|
|
||||||
doTest(
|
|
||||||
"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\n" +
|
|
||||||
"DTSTART:20080504T123456Z\r\n" +
|
|
||||||
"DURATION:P1D\r\n" +
|
|
||||||
"END:VEVENT\r\nEND:VCALENDAR",
|
|
||||||
null, null, null, "20080504T123456Z", "20080505T123456Z");
|
|
||||||
doTest(
|
|
||||||
"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\n" +
|
|
||||||
"DTSTART:20080504T123456Z\r\n" +
|
|
||||||
"DURATION:P1DT2H3M4S\r\n" +
|
|
||||||
"END:VEVENT\r\nEND:VCALENDAR",
|
|
||||||
null, null, null, "20080504T123456Z", "20080505T143800Z");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSummary() {
|
|
||||||
doTest(
|
|
||||||
"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\n" +
|
|
||||||
"SUMMARY:foo\r\n" +
|
|
||||||
"DTSTART:20080504T123456Z\r\n" +
|
|
||||||
"END:VEVENT\r\nEND:VCALENDAR",
|
|
||||||
null, "foo", null, "20080504T123456Z", null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testLocation() {
|
|
||||||
doTest(
|
|
||||||
"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\n" +
|
|
||||||
"LOCATION:Miami\r\n" +
|
|
||||||
"DTSTART:20080504T123456Z\r\n" +
|
|
||||||
"END:VEVENT\r\nEND:VCALENDAR",
|
|
||||||
null, null, "Miami", "20080504T123456Z", null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDescription() {
|
|
||||||
doTest(
|
|
||||||
"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\n" +
|
|
||||||
"DTSTART:20080504T123456Z\r\n" +
|
|
||||||
"DESCRIPTION:This is a test\r\n" +
|
|
||||||
"END:VEVENT\r\nEND:VCALENDAR",
|
|
||||||
"This is a test", null, null, "20080504T123456Z", null);
|
|
||||||
doTest(
|
|
||||||
"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\n" +
|
|
||||||
"DTSTART:20080504T123456Z\r\n" +
|
|
||||||
"DESCRIPTION:This is a test\r\n\t with a continuation\r\n" +
|
|
||||||
"END:VEVENT\r\nEND:VCALENDAR",
|
|
||||||
"This is a test with a continuation", null, null, "20080504T123456Z", null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGeo() {
|
|
||||||
doTest(
|
|
||||||
"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\n" +
|
|
||||||
"DTSTART:20080504T123456Z\r\n" +
|
|
||||||
"GEO:-12.345;-45.678\r\n" +
|
|
||||||
"END:VEVENT\r\nEND:VCALENDAR",
|
|
||||||
null, null, null, "20080504T123456Z", null, null, null, -12.345, -45.678);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testBadGeo() {
|
|
||||||
// Not parsed as VEVENT
|
|
||||||
RXingResult fakeRXingResult = new RXingResult("BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\n" +
|
|
||||||
"GEO:-12.345\r\n" +
|
|
||||||
"END:VEVENT\r\nEND:VCALENDAR", null, null, BarcodeFormat.QR_CODE);
|
|
||||||
ParsedRXingResult result = RXingResultParser.parseRXingResult(fakeRXingResult);
|
|
||||||
assertSame(ParsedRXingResultType.TEXT, result.getType());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testOrganizer() {
|
|
||||||
doTest(
|
|
||||||
"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\n" +
|
|
||||||
"DTSTART:20080504T123456Z\r\n" +
|
|
||||||
"ORGANIZER:mailto:bob@example.org\r\n" +
|
|
||||||
"END:VEVENT\r\nEND:VCALENDAR",
|
|
||||||
null, null, null, "20080504T123456Z", null, "bob@example.org", null, Double.NaN, Double.NaN);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAttendees() {
|
|
||||||
doTest(
|
|
||||||
"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\n" +
|
|
||||||
"DTSTART:20080504T123456Z\r\n" +
|
|
||||||
"ATTENDEE:mailto:bob@example.org\r\n" +
|
|
||||||
"ATTENDEE:mailto:alice@example.org\r\n" +
|
|
||||||
"END:VEVENT\r\nEND:VCALENDAR",
|
|
||||||
null, null, null, "20080504T123456Z", null, null,
|
|
||||||
new String[] {"bob@example.org", "alice@example.org"}, Double.NaN, Double.NaN);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testVEventEscapes() {
|
|
||||||
doTest("BEGIN:VEVENT\n" +
|
|
||||||
"CREATED:20111109T110351Z\n" +
|
|
||||||
"LAST-MODIFIED:20111109T170034Z\n" +
|
|
||||||
"DTSTAMP:20111109T170034Z\n" +
|
|
||||||
"UID:0f6d14ef-6cb7-4484-9080-61447ccdf9c2\n" +
|
|
||||||
"SUMMARY:Summary line\n" +
|
|
||||||
"CATEGORIES:Private\n" +
|
|
||||||
"DTSTART;TZID=Europe/Vienna:20111110T110000\n" +
|
|
||||||
"DTEND;TZID=Europe/Vienna:20111110T120000\n" +
|
|
||||||
"LOCATION:Location\\, with\\, escaped\\, commas\n" +
|
|
||||||
"DESCRIPTION:Meeting with a friend\\nlook at homepage first\\n\\n\n" +
|
|
||||||
" \\n\n" +
|
|
||||||
"SEQUENCE:1\n" +
|
|
||||||
"X-MOZ-GENERATION:1\n" +
|
|
||||||
"END:VEVENT",
|
|
||||||
"Meeting with a friend\nlook at homepage first\n\n\n \n",
|
|
||||||
"Summary line",
|
|
||||||
"Location, with, escaped, commas",
|
|
||||||
"20111110T110000Z",
|
|
||||||
"20111110T120000Z");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAllDayValueDate() {
|
|
||||||
doTest("BEGIN:VEVENT\n" +
|
|
||||||
"DTSTART;VALUE=DATE:20111110\n" +
|
|
||||||
"DTEND;VALUE=DATE:20111110\n" +
|
|
||||||
"END:VEVENT",
|
|
||||||
null, null, null, "20111110T000000Z", "20111110T000000Z");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void doTest(String contents,
|
|
||||||
String description,
|
|
||||||
String summary,
|
|
||||||
String location,
|
|
||||||
String startString,
|
|
||||||
String endString) {
|
|
||||||
doTest(contents, description, summary, location, startString, endString, null, null, Double.NaN, Double.NaN);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void doTest(String contents,
|
|
||||||
String description,
|
|
||||||
String summary,
|
|
||||||
String location,
|
|
||||||
String startString,
|
|
||||||
String endString,
|
|
||||||
String organizer,
|
|
||||||
String[] attendees,
|
|
||||||
double latitude,
|
|
||||||
double longitude) {
|
|
||||||
RXingResult fakeRXingResult = new RXingResult(contents, null, null, BarcodeFormat.QR_CODE);
|
|
||||||
ParsedRXingResult result = RXingResultParser.parseRXingResult(fakeRXingResult);
|
|
||||||
assertSame(ParsedRXingResultType.CALENDAR, result.getType());
|
|
||||||
CalendarParsedRXingResult calRXingResult = (CalendarParsedRXingResult) result;
|
|
||||||
assertEquals(description, calRXingResult.getDescription());
|
|
||||||
assertEquals(summary, calRXingResult.getSummary());
|
|
||||||
assertEquals(location, calRXingResult.getLocation());
|
|
||||||
DateFormat dateFormat = makeGMTFormat();
|
|
||||||
assertEquals(startString, dateFormat.format(calRXingResult.getStartTimestamp()));
|
|
||||||
assertEquals(endString, calRXingResult.getEndTimestamp() < 0L ? null : dateFormat.format(calRXingResult.getEndTimestamp()));
|
|
||||||
assertEquals(organizer, calRXingResult.getOrganizer());
|
|
||||||
assertArrayEquals(attendees, calRXingResult.getAttendees());
|
|
||||||
assertEqualOrNaN(latitude, calRXingResult.getLatitude());
|
|
||||||
assertEqualOrNaN(longitude, calRXingResult.getLongitude());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void assertEqualOrNaN(double expected, double actual) {
|
|
||||||
if (Double.isNaN(expected)) {
|
|
||||||
assertTrue(Double.isNaN(actual));
|
|
||||||
} else {
|
|
||||||
assertEquals(expected, actual, EPSILON);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
257
src/client/result/CalendarParsedResultTestCase.rs
Normal file
257
src/client/result/CalendarParsedResultTestCase.rs
Normal file
@@ -0,0 +1,257 @@
|
|||||||
|
/*
|
||||||
|
* 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.Before;
|
||||||
|
// import org.junit.Test;
|
||||||
|
|
||||||
|
// import java.text.DateFormat;
|
||||||
|
// import java.text.SimpleDateFormat;
|
||||||
|
// import java.util.Locale;
|
||||||
|
// import java.util.TimeZone;
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * Tests {@link CalendarParsedRXingResult}.
|
||||||
|
// *
|
||||||
|
// * @author Sean Owen
|
||||||
|
// */
|
||||||
|
// public final class CalendarParsedRXingResultTestCase extends Assert {
|
||||||
|
|
||||||
|
use chrono::{DateTime, NaiveDateTime, Utc};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
client::result::{ParsedClientResult, ParsedRXingResultType},
|
||||||
|
BarcodeFormat, RXingResult,
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::{ParsedRXingResult, ResultParser};
|
||||||
|
|
||||||
|
const EPSILON: f64 = 1.0E-10;
|
||||||
|
const DATE_FORMAT_STRING: &'static str = "yyyyMMdd'T'HHmmss'Z'";
|
||||||
|
|
||||||
|
// private static DateFormat makeGMTFormat() {
|
||||||
|
// DateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'", Locale.ENGLISH);
|
||||||
|
// format.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||||
|
// return format;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @Before
|
||||||
|
// public void setUp() {
|
||||||
|
// Locale.setDefault(Locale.ENGLISH);
|
||||||
|
// TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
|
||||||
|
// }
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn testStartEnd() {
|
||||||
|
doTestShort(
|
||||||
|
"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20080504T123456Z\r\nDTEND:20080505T234555Z\r\nEND:VEVENT\r\nEND:VCALENDAR",
|
||||||
|
"", "", "", "20080504T123456Z", "20080505T234555Z");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn testNoVCalendar() {
|
||||||
|
doTestShort(
|
||||||
|
"BEGIN:VEVENT\r\nDTSTART:20080504T123456Z\r\nDTEND:20080505T234555Z\r\nEND:VEVENT",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"20080504T123456Z",
|
||||||
|
"20080505T234555Z",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn testStart() {
|
||||||
|
doTestShort(
|
||||||
|
"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20080504T123456Z\r\nEND:VEVENT\r\nEND:VCALENDAR",
|
||||||
|
"", "", "", "20080504T123456Z", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn testDuration() {
|
||||||
|
doTestShort(
|
||||||
|
"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20080504T123456Z\r\nDURATION:P1D\r\nEND:VEVENT\r\nEND:VCALENDAR",
|
||||||
|
"", "", "", "20080504T123456Z", "20080505T123456Z");
|
||||||
|
doTestShort(
|
||||||
|
"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20080504T123456Z\r\nDURATION:P1DT2H3M4S\r\nEND:VEVENT\r\nEND:VCALENDAR",
|
||||||
|
"", "", "", "20080504T123456Z", "20080505T143800Z");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn testSummary() {
|
||||||
|
doTestShort(
|
||||||
|
"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nSUMMARY:foo\r\nDTSTART:20080504T123456Z\r\nEND:VEVENT\r\nEND:VCALENDAR",
|
||||||
|
"", "foo", "", "20080504T123456Z", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn testLocation() {
|
||||||
|
doTestShort(
|
||||||
|
"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nLOCATION:Miami\r\nDTSTART:20080504T123456Z\r\nEND:VEVENT\r\nEND:VCALENDAR",
|
||||||
|
"", "", "Miami", "20080504T123456Z", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn testDescription() {
|
||||||
|
doTestShort(
|
||||||
|
"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20080504T123456Z\r\nDESCRIPTION:This is a test\r\nEND:VEVENT\r\nEND:VCALENDAR",
|
||||||
|
"This is a test", "", "", "20080504T123456Z", "");
|
||||||
|
doTestShort(
|
||||||
|
"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20080504T123456Z\r\nDESCRIPTION:This is a test\r\n\t with a continuation\r\nEND:VEVENT\r\nEND:VCALENDAR",
|
||||||
|
"This is a test with a continuation", "", "", "20080504T123456Z", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn testGeo() {
|
||||||
|
doTest(
|
||||||
|
"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20080504T123456Z\r\nGEO:-12.345;-45.678\r\nEND:VEVENT\r\nEND:VCALENDAR",
|
||||||
|
"", "", "", "20080504T123456Z", "", "", &Vec::new(), -12.345, -45.678);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn testBadGeo() {
|
||||||
|
// Not parsed as VEVENT
|
||||||
|
let fakeRXingResult = RXingResult::new(
|
||||||
|
"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nGEO:-12.345\r\nEND:VEVENT\r\nEND:VCALENDAR",
|
||||||
|
Vec::new(),
|
||||||
|
Vec::new(),
|
||||||
|
BarcodeFormat::QR_CODE,
|
||||||
|
);
|
||||||
|
let result = ResultParser::parseRXingResult(&fakeRXingResult);
|
||||||
|
assert_eq!(ParsedRXingResultType::TEXT, result.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn testOrganizer() {
|
||||||
|
doTest(
|
||||||
|
"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20080504T123456Z\r\nORGANIZER:mailto:bob@example.org\r\nEND:VEVENT\r\nEND:VCALENDAR",
|
||||||
|
"", "", "", "20080504T123456Z", "", "bob@example.org", &Vec::new(), f64::NAN, f64::NAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn testAttendees() {
|
||||||
|
doTest(
|
||||||
|
"BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20080504T123456Z\r\nATTENDEE:mailto:bob@example.org\r\nATTENDEE:mailto:alice@example.org\r\nEND:VEVENT\r\nEND:VCALENDAR",
|
||||||
|
"", "", "", "20080504T123456Z", "", "",
|
||||||
|
&vec!["bob@example.org", "alice@example.org"], f64::NAN, f64::NAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn testVEventEscapes() {
|
||||||
|
doTestShort("BEGIN:VEVENT\nCREATED:20111109T110351Z\nLAST-MODIFIED:20111109T170034Z\nDTSTAMP:20111109T170034Z\nUID:0f6d14ef-6cb7-4484-9080-61447ccdf9c2\nSUMMARY:Summary line\nCATEGORIES:Private\nDTSTART;TZID=Europe/Vienna:20111110T110000\nDTEND;TZID=Europe/Vienna:20111110T120000\nLOCATION:Location\\, with\\, escaped\\, commas\nDESCRIPTION:Meeting with a friend\\nlook at homepage first\\n\\n\n \\n\nSEQUENCE:1\nX-MOZ-GENERATION:1\nEND:VEVENT",
|
||||||
|
"Meeting with a friend\nlook at homepage first\n\n\n \n",
|
||||||
|
"Summary line",
|
||||||
|
"Location, with, escaped, commas",
|
||||||
|
"20111110T110000Z",
|
||||||
|
"20111110T120000Z");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn testAllDayValueDate() {
|
||||||
|
doTestShort(
|
||||||
|
"BEGIN:VEVENT\nDTSTART;VALUE=DATE:20111110\nDTEND;VALUE=DATE:20111110\nEND:VEVENT",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"20111110T000000Z",
|
||||||
|
"20111110T000000Z",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn doTestShort(
|
||||||
|
contents: &str,
|
||||||
|
description: &str,
|
||||||
|
summary: &str,
|
||||||
|
location: &str,
|
||||||
|
startString: &str,
|
||||||
|
endString: &str,
|
||||||
|
) {
|
||||||
|
doTest(
|
||||||
|
contents,
|
||||||
|
description,
|
||||||
|
summary,
|
||||||
|
location,
|
||||||
|
startString,
|
||||||
|
endString,
|
||||||
|
"",
|
||||||
|
&Vec::new(),
|
||||||
|
f64::NAN,
|
||||||
|
f64::NAN,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn doTest(
|
||||||
|
contents: &str,
|
||||||
|
description: &str,
|
||||||
|
summary: &str,
|
||||||
|
location: &str,
|
||||||
|
startString: &str,
|
||||||
|
endString: &str,
|
||||||
|
organizer: &str,
|
||||||
|
attendees: &[&str],
|
||||||
|
latitude: f64,
|
||||||
|
longitude: f64,
|
||||||
|
) {
|
||||||
|
let fakeRXingResult =
|
||||||
|
RXingResult::new(contents, Vec::new(), Vec::new(), BarcodeFormat::QR_CODE);
|
||||||
|
let result = ResultParser::parseRXingResult(&fakeRXingResult);
|
||||||
|
assert_eq!(ParsedRXingResultType::CALENDAR, result.getType());
|
||||||
|
if let ParsedClientResult::CalendarEventResult(calRXingResult) = result {
|
||||||
|
assert_eq!(description, calRXingResult.getDescription());
|
||||||
|
assert_eq!(summary, calRXingResult.getSummary());
|
||||||
|
assert_eq!(location, calRXingResult.getLocation());
|
||||||
|
let dateFormat = "%c"; //makeGMTFormat();
|
||||||
|
assert_eq!(
|
||||||
|
startString,
|
||||||
|
format_date_string(calRXingResult.getStartTimestamp(), dateFormat) // dateFormat.format(calRXingResult.getStartTimestamp())
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
endString,
|
||||||
|
if calRXingResult.getEndTimestamp() < 0i64 {
|
||||||
|
"".to_owned()
|
||||||
|
} else {
|
||||||
|
format_date_string(calRXingResult.getEndTimestamp(), dateFormat)
|
||||||
|
// dateFormat.format(calRXingResult.getEndTimestamp())
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(organizer, calRXingResult.getOrganizer());
|
||||||
|
assert_eq!(attendees, calRXingResult.getAttendees());
|
||||||
|
assertEqualOrNaN(latitude, calRXingResult.getLatitude());
|
||||||
|
assertEqualOrNaN(longitude, calRXingResult.getLongitude());
|
||||||
|
} else {
|
||||||
|
panic!("Expected Calendar");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn assertEqualOrNaN(expected: f64, actual: f64) {
|
||||||
|
if expected.is_nan() {
|
||||||
|
assert!(actual.is_nan());
|
||||||
|
} else {
|
||||||
|
assert!(expected - actual < EPSILON && actual - expected < EPSILON);
|
||||||
|
// assert_eq!(expected, actual, EPSILON);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn format_date_string(timestamp: i64, format_string: &str) -> String {
|
||||||
|
NaiveDateTime::from_timestamp(timestamp, 0)
|
||||||
|
.format(format_string)
|
||||||
|
.to_string()
|
||||||
|
// DateTime::from(timestamp,0).with_timezone(Utc).format(format_string).to_string()
|
||||||
|
}
|
||||||
@@ -153,7 +153,7 @@ pub fn parse(result: &RXingResult) -> Option<ParsedClientResult> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn matchVCardPrefixedField(
|
pub fn matchVCardPrefixedField(
|
||||||
prefix: &str,
|
prefix: &str,
|
||||||
rawText: &str,
|
rawText: &str,
|
||||||
trim: bool,
|
trim: bool,
|
||||||
@@ -427,7 +427,7 @@ fn maybeAppendFragment(fragmentBuffer: &mut Vec<u8>, charset: &str, result: &mut
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn matchSingleVCardPrefixedField(
|
pub fn matchSingleVCardPrefixedField(
|
||||||
prefix: &str,
|
prefix: &str,
|
||||||
rawText: &str,
|
rawText: &str,
|
||||||
trim: bool,
|
trim: bool,
|
||||||
|
|||||||
@@ -1,118 +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.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Partially implements the iCalendar format's "VEVENT" format for specifying a
|
|
||||||
* calendar event. See RFC 2445. This supports SUMMARY, LOCATION, GEO, DTSTART and DTEND fields.
|
|
||||||
*
|
|
||||||
* @author Sean Owen
|
|
||||||
*/
|
|
||||||
public final class VEventRXingResultParser extends RXingResultParser {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CalendarParsedRXingResult parse(RXingResult result) {
|
|
||||||
String rawText = getMassagedText(result);
|
|
||||||
int vEventStart = rawText.indexOf("BEGIN:VEVENT");
|
|
||||||
if (vEventStart < 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
String summary = matchSingleVCardPrefixedField("SUMMARY", rawText);
|
|
||||||
String start = matchSingleVCardPrefixedField("DTSTART", rawText);
|
|
||||||
if (start == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
String end = matchSingleVCardPrefixedField("DTEND", rawText);
|
|
||||||
String duration = matchSingleVCardPrefixedField("DURATION", rawText);
|
|
||||||
String location = matchSingleVCardPrefixedField("LOCATION", rawText);
|
|
||||||
String organizer = stripMailto(matchSingleVCardPrefixedField("ORGANIZER", rawText));
|
|
||||||
|
|
||||||
String[] attendees = matchVCardPrefixedField("ATTENDEE", rawText);
|
|
||||||
if (attendees != null) {
|
|
||||||
for (int i = 0; i < attendees.length; i++) {
|
|
||||||
attendees[i] = stripMailto(attendees[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
String description = matchSingleVCardPrefixedField("DESCRIPTION", rawText);
|
|
||||||
|
|
||||||
String geoString = matchSingleVCardPrefixedField("GEO", rawText);
|
|
||||||
double latitude;
|
|
||||||
double longitude;
|
|
||||||
if (geoString == null) {
|
|
||||||
latitude = Double.NaN;
|
|
||||||
longitude = Double.NaN;
|
|
||||||
} else {
|
|
||||||
int semicolon = geoString.indexOf(';');
|
|
||||||
if (semicolon < 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
latitude = Double.parseDouble(geoString.substring(0, semicolon));
|
|
||||||
longitude = Double.parseDouble(geoString.substring(semicolon + 1));
|
|
||||||
} catch (NumberFormatException ignored) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
return new CalendarParsedRXingResult(summary,
|
|
||||||
start,
|
|
||||||
end,
|
|
||||||
duration,
|
|
||||||
location,
|
|
||||||
organizer,
|
|
||||||
attendees,
|
|
||||||
description,
|
|
||||||
latitude,
|
|
||||||
longitude);
|
|
||||||
} catch (IllegalArgumentException ignored) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String matchSingleVCardPrefixedField(CharSequence prefix,
|
|
||||||
String rawText) {
|
|
||||||
List<String> values = VCardRXingResultParser.matchSingleVCardPrefixedField(prefix, rawText, true, false);
|
|
||||||
return values == null || values.isEmpty() ? null : values.get(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String[] matchVCardPrefixedField(CharSequence prefix, String rawText) {
|
|
||||||
List<List<String>> values = VCardRXingResultParser.matchVCardPrefixedField(prefix, rawText, true, false);
|
|
||||||
if (values == null || values.isEmpty()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
int size = values.size();
|
|
||||||
String[] result = new String[size];
|
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
result[i] = values.get(i).get(0);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String stripMailto(String s) {
|
|
||||||
if (s != null && (s.startsWith("mailto:") || s.startsWith("MAILTO:"))) {
|
|
||||||
s = s.substring(7);
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
174
src/client/result/VEventResultParser.rs
Normal file
174
src/client/result/VEventResultParser.rs
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
/*
|
||||||
|
* 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.List;
|
||||||
|
|
||||||
|
use crate::RXingResult;
|
||||||
|
|
||||||
|
use super::{CalendarParsedRXingResult, ParsedClientResult, ResultParser, VCardResultParser};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Partially implements the iCalendar format's "VEVENT" format for specifying a
|
||||||
|
* calendar event. See RFC 2445. This supports SUMMARY, LOCATION, GEO, DTSTART and DTEND fields.
|
||||||
|
*
|
||||||
|
* @author Sean Owen
|
||||||
|
*/
|
||||||
|
pub fn parse(result: &RXingResult) -> Option<ParsedClientResult> {
|
||||||
|
let rawText = ResultParser::getMassagedText(result);
|
||||||
|
if let None = rawText.find("BEGIN:VEVENT") {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
// if (vEventStart < 0) {
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
|
||||||
|
let summary = matchSingleVCardPrefixedField("SUMMARY", &rawText);
|
||||||
|
let start = matchSingleVCardPrefixedField("DTSTART", &rawText);
|
||||||
|
if start.is_empty() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let end = matchSingleVCardPrefixedField("DTEND", &rawText);
|
||||||
|
let duration = matchSingleVCardPrefixedField("DURATION", &rawText);
|
||||||
|
let location = matchSingleVCardPrefixedField("LOCATION", &rawText);
|
||||||
|
let organizer = stripMailto(&matchSingleVCardPrefixedField("ORGANIZER", &rawText));
|
||||||
|
|
||||||
|
let mut attendees = matchVCardPrefixedField("ATTENDEE", &rawText);
|
||||||
|
if !attendees.is_empty() {
|
||||||
|
for i in 0..attendees.len() {
|
||||||
|
// for (int i = 0; i < attendees.length; i++) {
|
||||||
|
attendees[i] = stripMailto(&attendees[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let description = matchSingleVCardPrefixedField("DESCRIPTION", &rawText);
|
||||||
|
|
||||||
|
let geoString = matchSingleVCardPrefixedField("GEO", &rawText);
|
||||||
|
let latitude;
|
||||||
|
let longitude;
|
||||||
|
if geoString.is_empty() {
|
||||||
|
latitude = f64::NAN;
|
||||||
|
longitude = f64::NAN;
|
||||||
|
} else {
|
||||||
|
if let Some(semicolon) = geoString.find(';') {
|
||||||
|
latitude = if let Ok(l) = geoString[..semicolon].parse() {
|
||||||
|
l
|
||||||
|
} else {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
longitude = if let Ok(l) = geoString[semicolon + 1..].parse() {
|
||||||
|
l
|
||||||
|
} else {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
// if (semicolon < 0) {
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
// try {
|
||||||
|
// latitude = Double.parseDouble(geoString.substring(0, semicolon));
|
||||||
|
// longitude = Double.parseDouble(geoString.substring(semicolon + 1));
|
||||||
|
// } catch (NumberFormatException ignored) {
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Ok(cpr) = CalendarParsedRXingResult::new(
|
||||||
|
summary,
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
duration,
|
||||||
|
location,
|
||||||
|
organizer,
|
||||||
|
attendees,
|
||||||
|
description,
|
||||||
|
latitude,
|
||||||
|
longitude,
|
||||||
|
) {
|
||||||
|
Some(ParsedClientResult::CalendarEventResult(cpr))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
// try {
|
||||||
|
// return new CalendarParsedRXingResult(summary,
|
||||||
|
// start,
|
||||||
|
// end,
|
||||||
|
// duration,
|
||||||
|
// location,
|
||||||
|
// organizer,
|
||||||
|
// attendees,
|
||||||
|
// description,
|
||||||
|
// latitude,
|
||||||
|
// longitude);
|
||||||
|
// } catch (IllegalArgumentException ignored) {
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn matchSingleVCardPrefixedField(prefix: &str, rawText: &str) -> String {
|
||||||
|
if let Some(values) =
|
||||||
|
VCardResultParser::matchSingleVCardPrefixedField(prefix, rawText, true, false)
|
||||||
|
{
|
||||||
|
if values.is_empty() {
|
||||||
|
"".to_owned()
|
||||||
|
} else {
|
||||||
|
values.get(0).unwrap().clone()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
"".to_owned()
|
||||||
|
}
|
||||||
|
// return values == null || values.isEmpty() ? null : values.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn matchVCardPrefixedField(prefix: &str, rawText: &str) -> Vec<String> {
|
||||||
|
if let Some(values) = VCardResultParser::matchVCardPrefixedField(prefix, rawText, true, false) {
|
||||||
|
if values.is_empty() {
|
||||||
|
Vec::new()
|
||||||
|
} else {
|
||||||
|
let size = values.len();
|
||||||
|
let mut result = vec!["".to_owned(); size]; //new String[size];
|
||||||
|
for i in 0..size {
|
||||||
|
// for (int i = 0; i < size; i++) {
|
||||||
|
result[i] = values.get(i).unwrap().get(0).unwrap().clone();
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Vec::new()
|
||||||
|
}
|
||||||
|
// if values == null || values.isEmpty() {
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
// int size = values.size();
|
||||||
|
// String[] result = new String[size];
|
||||||
|
// for (int i = 0; i < size; i++) {
|
||||||
|
// result[i] = values.get(i).get(0);
|
||||||
|
// }
|
||||||
|
// return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn stripMailto(s: &str) -> String {
|
||||||
|
let mut s = s;
|
||||||
|
if !s.is_empty() && (s.starts_with("mailto:") || s.starts_with("MAILTO:")) {
|
||||||
|
s = &s[7..];
|
||||||
|
}
|
||||||
|
s.to_owned()
|
||||||
|
}
|
||||||
@@ -31,6 +31,8 @@ mod AddressBookDoCoMoResultParser;
|
|||||||
mod AddressBookAUResultParser;
|
mod AddressBookAUResultParser;
|
||||||
mod VCardResultParser;
|
mod VCardResultParser;
|
||||||
mod BizcardResultParser;
|
mod BizcardResultParser;
|
||||||
|
mod CalendarParsedResult;
|
||||||
|
mod VEventResultParser;
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
@@ -52,6 +54,8 @@ pub use URIParsedResult::*;
|
|||||||
pub use EmailAddressParsedResult::*;
|
pub use EmailAddressParsedResult::*;
|
||||||
pub use VINParsedResult::*;
|
pub use VINParsedResult::*;
|
||||||
pub use AddressBookParsedResult::*;
|
pub use AddressBookParsedResult::*;
|
||||||
|
pub use CalendarParsedResult::*;
|
||||||
|
pub use CalendarParsedResult::*;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod TelParsedResultTestCase;
|
mod TelParsedResultTestCase;
|
||||||
@@ -73,6 +77,8 @@ mod EmailAddressParsedResultTestCase;
|
|||||||
mod VINParsedResultTestCase;
|
mod VINParsedResultTestCase;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod AddressBookParsedResultTestCase;
|
mod AddressBookParsedResultTestCase;
|
||||||
|
#[cfg(test)]
|
||||||
|
mod CalendarParsedResultTestCase;
|
||||||
|
|
||||||
pub enum ParsedClientResult {
|
pub enum ParsedClientResult {
|
||||||
TextResult(TextParsedRXingResult),
|
TextResult(TextParsedRXingResult),
|
||||||
@@ -86,6 +92,7 @@ pub enum ParsedClientResult {
|
|||||||
EmailResult(EmailAddressParsedRXingResult),
|
EmailResult(EmailAddressParsedRXingResult),
|
||||||
VINResult(VINParsedRXingResult),
|
VINResult(VINParsedRXingResult),
|
||||||
AddressBookResult(AddressBookParsedRXingResult),
|
AddressBookResult(AddressBookParsedRXingResult),
|
||||||
|
CalendarEventResult(CalendarParsedRXingResult),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ParsedRXingResult for ParsedClientResult {
|
impl ParsedRXingResult for ParsedClientResult {
|
||||||
@@ -102,6 +109,7 @@ impl ParsedRXingResult for ParsedClientResult {
|
|||||||
ParsedClientResult::EmailResult(a) => a.getType(),
|
ParsedClientResult::EmailResult(a) => a.getType(),
|
||||||
ParsedClientResult::VINResult(a) => a.getType(),
|
ParsedClientResult::VINResult(a) => a.getType(),
|
||||||
ParsedClientResult::AddressBookResult(a) => a.getType(),
|
ParsedClientResult::AddressBookResult(a) => a.getType(),
|
||||||
|
ParsedClientResult::CalendarEventResult(a) => a.getType(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,6 +126,7 @@ impl ParsedRXingResult for ParsedClientResult {
|
|||||||
ParsedClientResult::EmailResult(a) => a.getDisplayRXingResult(),
|
ParsedClientResult::EmailResult(a) => a.getDisplayRXingResult(),
|
||||||
ParsedClientResult::VINResult(a) => a.getDisplayRXingResult(),
|
ParsedClientResult::VINResult(a) => a.getDisplayRXingResult(),
|
||||||
ParsedClientResult::AddressBookResult(a) => a.getDisplayRXingResult(),
|
ParsedClientResult::AddressBookResult(a) => a.getDisplayRXingResult(),
|
||||||
|
ParsedClientResult::CalendarEventResult(a) => a.getDisplayRXingResult(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,5 +14,6 @@ pub enum Exceptions {
|
|||||||
ReedSolomonException(String),
|
ReedSolomonException(String),
|
||||||
IndexOutOfBoundsException(String),
|
IndexOutOfBoundsException(String),
|
||||||
RuntimeException(String),
|
RuntimeException(String),
|
||||||
|
ParseException(String),
|
||||||
ReaderDecodeException()
|
ReaderDecodeException()
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user