You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
196 lines
4.8 KiB
Rust
196 lines
4.8 KiB
Rust
use crate::time::TimeSpan::{Infinite, Finite};
|
|
|
|
#[derive(Debug, Copy, Clone, Hash, Ord, PartialOrd, Eq, PartialEq)]
|
|
pub enum TimeSpan {
|
|
Infinite,
|
|
Finite(FiniteTimeSpan),
|
|
}
|
|
|
|
#[derive(Default, Debug, Copy, Clone, Hash, Ord, PartialOrd, Eq, PartialEq)]
|
|
pub struct FiniteTimeSpan {
|
|
pub years: usize,
|
|
pub months: usize,
|
|
pub weeks: usize,
|
|
pub days: usize,
|
|
pub hours: usize,
|
|
pub minutes: usize,
|
|
pub seconds: usize,
|
|
pub milliseconds: usize,
|
|
pub microseconds: usize,
|
|
pub nanoseconds: usize,
|
|
}
|
|
|
|
impl FiniteTimeSpan {
|
|
pub fn with_years(&self, years: usize) -> FiniteTimeSpan {
|
|
let mut new = self.clone();
|
|
new.years = years;
|
|
new
|
|
}
|
|
|
|
pub fn with_months(&self, months: usize) -> FiniteTimeSpan {
|
|
let mut new = self.clone();
|
|
new.months = months;
|
|
new
|
|
}
|
|
|
|
pub fn with_weeks(&self, weeks: usize) -> FiniteTimeSpan {
|
|
let mut new = self.clone();
|
|
new.weeks = weeks;
|
|
new
|
|
}
|
|
|
|
pub fn with_days(&self, days: usize) -> FiniteTimeSpan {
|
|
let mut new = self.clone();
|
|
new.days = days;
|
|
new
|
|
}
|
|
|
|
pub fn with_hours(&self, hours: usize) -> FiniteTimeSpan {
|
|
let mut new = self.clone();
|
|
new.hours = hours;
|
|
new
|
|
}
|
|
|
|
pub fn with_minutes(&self, minutes: usize) -> FiniteTimeSpan {
|
|
let mut new = self.clone();
|
|
new.minutes = minutes;
|
|
new
|
|
}
|
|
|
|
pub fn with_seconds(&self, seconds: usize) -> FiniteTimeSpan {
|
|
let mut new = self.clone();
|
|
new.seconds = seconds;
|
|
new
|
|
}
|
|
|
|
pub fn with_milliseconds(&self, milliseconds: usize) -> FiniteTimeSpan {
|
|
let mut new = self.clone();
|
|
new.milliseconds = milliseconds;
|
|
new
|
|
}
|
|
|
|
pub fn with_microseconds(&self, microseconds: usize) -> FiniteTimeSpan {
|
|
let mut new = self.clone();
|
|
new.microseconds = microseconds;
|
|
new
|
|
}
|
|
|
|
pub fn with_nanoseconds(&self, nanoseconds: usize) -> FiniteTimeSpan {
|
|
let mut new = self.clone();
|
|
new.nanoseconds = nanoseconds;
|
|
new
|
|
}
|
|
|
|
pub fn new() -> FiniteTimeSpan {
|
|
FiniteTimeSpan {
|
|
years: 0,
|
|
months: 0,
|
|
weeks: 0,
|
|
days: 0,
|
|
hours: 0,
|
|
minutes: 0,
|
|
seconds: 0,
|
|
milliseconds: 0,
|
|
microseconds: 0,
|
|
nanoseconds: 0,
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn parse_time_span(val: &str) -> Option<TimeSpan> {
|
|
if val.trim() == "infinite" || val.trim() == "infinity" {
|
|
Some(Infinite)
|
|
} else {
|
|
parse_finite_time_span(val).map(|x| Finite(x))
|
|
}
|
|
}
|
|
|
|
pub fn parse_finite_time_span(val: &str) -> Option<FiniteTimeSpan> {
|
|
let parse = val.replace(" ", "");
|
|
let mut time_span = FiniteTimeSpan::default();
|
|
let mut current_value = String::new();
|
|
let mut current_num = 0usize;
|
|
|
|
let finish = &mut |name: &str, amount: usize| {
|
|
match name {
|
|
"nsec" | "ns" => {
|
|
time_span.nanoseconds += amount;
|
|
}
|
|
|
|
"usec" | "us" | "µs" => {
|
|
time_span.microseconds += amount;
|
|
}
|
|
|
|
"msec" | "ms" => {
|
|
time_span.milliseconds += amount;
|
|
}
|
|
|
|
"" | "s" | "sec" | "second" | "seconds" => {
|
|
time_span.seconds += amount;
|
|
}
|
|
|
|
"minutes" | "minute" | "min" | "m" => {
|
|
time_span.minutes += amount;
|
|
}
|
|
|
|
"hours" | "hour" | "hr" | "h" => {
|
|
time_span.hours += amount;
|
|
}
|
|
|
|
"days" | "day" | "d" => {
|
|
time_span.days += amount;
|
|
}
|
|
|
|
"weeks" | "week" | "w" => {
|
|
time_span.weeks += amount;
|
|
}
|
|
|
|
"M" | "months" | "month" => {
|
|
time_span.months += amount;
|
|
}
|
|
|
|
"years" | "year" | "y" => {
|
|
time_span.years += amount;
|
|
}
|
|
|
|
_ => return false
|
|
}
|
|
|
|
true
|
|
};
|
|
|
|
let mut last_is_nr = false;
|
|
for chxr in parse.chars() {
|
|
match chxr.to_ascii_lowercase() {
|
|
'0'..='9' => {
|
|
if !last_is_nr {
|
|
if !finish(current_value.as_str(), current_num) {
|
|
return None;
|
|
}
|
|
current_value = String::new();
|
|
current_num = 0;
|
|
last_is_nr = true
|
|
}
|
|
|
|
current_num *= 10;
|
|
current_num += chxr.to_digit(10).unwrap_or(0) as usize
|
|
}
|
|
|
|
'a'..='z' => {
|
|
current_value += &chxr.to_string();
|
|
last_is_nr = false;
|
|
}
|
|
|
|
_ => {
|
|
return None;
|
|
}
|
|
}
|
|
}
|
|
|
|
if !finish(current_value.as_str(), current_num) {
|
|
None
|
|
} else {
|
|
Some(time_span)
|
|
}
|
|
}
|