/* Copyright 2020-2023, Savanni D'Gerinel 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 . */ 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(&self, record: &T) -> bool; } /// Specify two criteria that must both be matched. pub struct And { pub lside: A, pub rside: B, } impl Criteria for And where A: Criteria, B: Criteria, { fn apply(&self, record: &T) -> bool { self.lside.apply(record) && self.rside.apply(record) } } /// Specify two criteria, either of which may be matched. pub struct Or { 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(&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(&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, } impl Criteria for Tags { fn apply(&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 { 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 { And { lside: StartTime { time: start, incl: start_incl, }, rside: EndTime { time: end, incl: end_incl, }, } }