1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//! `timefilter` — human-readable time string parsing, filtering, and formatting.
//!
//! Handles strings like `">=7d"`, `"<2h"`, `"2024-05-01"` — parsing them into
//! `DateTime<Utc>` values and applying comparison filters.
//!
//! Unlike existing crates (`duration-str`, `human-time`), this crate focuses on
//! **relative time → timestamp** resolution and **filter operators** — the
//! `TimeOp`/`TimeFilter` types that let you write `>=7d` or `<2h` as a single
//! filter expression.
//!
//! # Quick Start
//!
//! ```
//! use timefilter::prelude::*;
//!
//! // Parse absolute time
//! let dt = parse_time("2024-05-01 10:00").unwrap();
//!
//! // Parse a filter expression against absolute time
//! let f: TimeFilter = ">=2024-05-01 09:00".parse().unwrap();
//! assert_eq!(f.op, TimeOp::Ge);
//! assert!(f.matches(dt));
//!
//! // Relative time (hours ago) — just check it parses
//! let dt = parse_time("2h").unwrap();
//! let age = chrono::Utc::now() - dt;
//! assert!(age.num_hours() >= 1 && age.num_hours() <= 3);
//! ```
//!
//! # Relative time
//!
//! `parse_time` parses relative durations to `DateTime<Utc>` (now - duration):
//!
//! ```
//! use timefilter::parse_time;
//!
//! let dt = parse_time("7d").unwrap(); // 7 days ago
//! let dt = parse_time("2h").unwrap(); // 2 hours ago
//! let dt = parse_time("30m").unwrap(); // 30 minutes ago
//! let dt = parse_time("30s").unwrap(); // 30 seconds ago
//! ```
//!
//! # Absolute time
//!
//! ```
//! use timefilter::parse_time;
//!
//! parse_time("2024-05-01").unwrap(); // midnight UTC
//! parse_time("2024-05-01 10:00").unwrap(); // hour:minute
//! parse_time("2024-05-01 10:00:00").unwrap(); // with seconds
//! ```
//!
//! # Time filters
//!
//! ```
//! use timefilter::TimeFilter;
//!
//! let f: TimeFilter = ">=7d".parse().unwrap();
//! assert!(f.to_string().starts_with('>'));
//!
//! // Convenience constructors
//! use chrono::{Utc, DateTime};
//! let now: DateTime<Utc> = Utc::now();
//! let f = TimeFilter::lt(now);
//! ```
//!
//! # TimeFilter convenience constructors
//!
//! ```
//! use timefilter::TimeFilter;
//! use chrono::Utc;
//!
//! let now = Utc::now();
//! let f = TimeFilter::gt(now); // value > now
//! let f = TimeFilter::ge(now); // value >= now
//! let f = TimeFilter::lt(now); // value < now
//! let f = TimeFilter::le(now); // value <= now
//! let f = TimeFilter::eq(now); // value == now
//! ```
//!
//! # Using `TimeFilter::matches`
//!
//! ```
//! use timefilter::{parse_time, TimeFilter};
//!
//! let start = parse_time("2024-06-01").unwrap();
//! let end = parse_time("2024-06-30").unwrap();
//! let mid = parse_time("2024-06-15").unwrap();
//!
//! let f = TimeFilter::ge(start);
//! assert!(f.matches(mid));
//! assert!(f.matches(end));
//! assert!(!f.matches(parse_time("2024-05-31").unwrap()));
//! ```
//!
//! # Using `TimeOp::applies`
//!
//! ```
//! use timefilter::{TimeOp, parse_time};
//!
//! let t1 = parse_time("2024-06-15").unwrap();
//! let t2 = parse_time("2024-05-01").unwrap();
//!
//! assert!(TimeOp::Gt.applies(t1, t2));
//! assert!(!TimeOp::Lt.applies(t1, t2));
//! assert!(TimeOp::Eq.applies(t1, t1));
//! ```
//!
//! # Error handling
//!
//! ```
//! use timefilter::{parse_time, parse_time_filter, TimeError};
//!
//! assert_eq!(parse_time(""), Err(TimeError::EmptyInput));
//! assert_eq!(parse_time("abc"), Err(TimeError::InvalidDate));
//! assert_eq!(parse_time_filter("1h"), Err(TimeError::MissingOperator));
//! ```
//!
//! # Serde support
//!
//! With the `serde` feature enabled, [`TimeFilter`] can be serialized and
//! deserialized as a human-readable string:
//!
//! ```toml
//! [dependencies]
//! timefilter = { version = "0.1", features = ["serde"] }
//! ```
pub use *;
/// Easy import of the crate's most common items.