use super::store::HistoryStore;
use chrono::{DateTime, NaiveDate, Utc};
use reedline::{
CommandLineSearch, HistoryItem, Result, SearchDirection, SearchFilter, SearchQuery,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) struct InvalidSince;
pub(crate) fn parse_since(since: &str) -> std::result::Result<DateTime<Utc>, InvalidSince> {
let parsed = DateTime::parse_from_rfc3339(since)
.map(|dt| dt.with_timezone(&Utc))
.or_else(|_| {
NaiveDate::parse_from_str(since, "%Y-%m-%d")
.map(|d| d.and_hms_opt(0, 0, 0).unwrap().and_utc())
})
.map_err(|_| InvalidSince)?;
DateTime::from_timestamp_millis(parsed.timestamp_millis()).ok_or(InvalidSince)
}
pub(crate) struct HistoryQuery {
pub limit: i64,
pub all_sessions: bool,
pub cwd: Option<String>,
pub grep: Option<String>,
pub since: Option<DateTime<Utc>>,
}
impl HistoryStore {
pub(crate) fn query(&self, query: &HistoryQuery) -> Result<Vec<HistoryItem>> {
self.search_strict_session(
|start_id| {
let mut filter = SearchFilter::anything(None);
filter.cwd_exact = query.cwd.clone();
filter.command_line = query.grep.clone().map(CommandLineSearch::Substring);
SearchQuery {
direction: SearchDirection::Backward,
start_time: None,
end_time: None,
start_id,
end_id: None,
limit: None,
filter,
}
},
self.session(),
query.all_sessions,
query.limit,
query.since,
)
}
}