120 lines
3.4 KiB
Rust
120 lines
3.4 KiB
Rust
/*
|
|
Copyright 2020-2023, Savanni D'Gerinel <savanni@luminescent-dreams.com>
|
|
|
|
This file is part of the Luminescent Dreams Tools.
|
|
|
|
Luminescent Dreams Tools is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
|
|
|
Luminescent Dreams Tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License along with Lumeto. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
use date_time_tz::DateTimeTz;
|
|
use types::{Recordable, Timestamp};
|
|
|
|
/// This trait is used for constructing queries for searching the database.
|
|
pub trait Criteria {
|
|
/// Apply this criteria element to a record, returning true only if the record matches the
|
|
/// criteria.
|
|
fn apply<T: Recordable>(&self, record: &T) -> bool;
|
|
}
|
|
|
|
/// Specify two criteria that must both be matched.
|
|
pub struct And<A: Criteria, B: Criteria> {
|
|
pub lside: A,
|
|
pub rside: B,
|
|
}
|
|
|
|
impl<A, B> Criteria for And<A, B>
|
|
where
|
|
A: Criteria,
|
|
B: Criteria,
|
|
{
|
|
fn apply<T: Recordable>(&self, record: &T) -> bool {
|
|
self.lside.apply(record) && self.rside.apply(record)
|
|
}
|
|
}
|
|
|
|
/// Specify two criteria, either of which may be matched.
|
|
pub struct Or<A: Criteria, B: Criteria> {
|
|
pub lside: A,
|
|
pub rside: B,
|
|
}
|
|
|
|
/// Specify the starting time for a search. This consists of a UTC timestamp and a specifier as to
|
|
/// whether the exact time is included in the search criteria.
|
|
pub struct StartTime {
|
|
pub time: Timestamp,
|
|
pub incl: bool,
|
|
}
|
|
|
|
impl Criteria for StartTime {
|
|
fn apply<T: Recordable>(&self, record: &T) -> bool {
|
|
if self.incl {
|
|
record.timestamp() >= self.time
|
|
} else {
|
|
record.timestamp() > self.time
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Specify the ending time for a search. This consists of a UTC timestamp and a specifier as to
|
|
/// whether the exact time is included in the search criteria.
|
|
pub struct EndTime {
|
|
pub time: Timestamp,
|
|
pub incl: bool,
|
|
}
|
|
|
|
impl Criteria for EndTime {
|
|
fn apply<T: Recordable>(&self, record: &T) -> bool {
|
|
if self.incl {
|
|
record.timestamp() <= self.time
|
|
} else {
|
|
record.timestamp() < self.time
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Specify a list of tags that must exist on the record.
|
|
pub struct Tags {
|
|
pub tags: Vec<String>,
|
|
}
|
|
|
|
impl Criteria for Tags {
|
|
fn apply<T: Recordable>(&self, record: &T) -> bool {
|
|
let record_tags = record.tags();
|
|
self.tags.iter().all(|v| record_tags.contains(v))
|
|
}
|
|
}
|
|
|
|
/// Specify a criteria that searches for records matching an exact time.
|
|
pub fn exact_time(time: Timestamp) -> And<StartTime, EndTime> {
|
|
And {
|
|
lside: StartTime {
|
|
time: time.clone(),
|
|
incl: true,
|
|
},
|
|
rside: EndTime { time, incl: true },
|
|
}
|
|
}
|
|
|
|
/// Specify a criteria that searches for all records within a time range.
|
|
pub fn time_range(
|
|
start: Timestamp,
|
|
start_incl: bool,
|
|
end: Timestamp,
|
|
end_incl: bool,
|
|
) -> And<StartTime, EndTime> {
|
|
And {
|
|
lside: StartTime {
|
|
time: start,
|
|
incl: start_incl,
|
|
},
|
|
rside: EndTime {
|
|
time: end,
|
|
incl: end_incl,
|
|
},
|
|
}
|
|
}
|