rapport_temporal/lib.rs
1//! Ergonomic, human friendly way to handle date-based time.
2//!
3//! ## Motivation
4//!
5//! `chrono` is a great crate, and this library uses it, but it doesn't easily cover the fact that
6//! lots of time humans just want to talk in dates. They might want to do something tomorrow, they
7//! want a date to do that, and developers want an easy way to make that happen without a lot of
8//! fuss.
9//!
10//! Also with error handling, yes it might be the heat death date of the universe, but we don't want
11//! or need error handling to fail when this is the case. If someone is being weird and giving the
12//! library extreme data, we fall back to sensible dates, to make the whole thing ergonomic and
13//! delightful to use.
14//!
15//! ## Modules
16//!
17//! `date`: simple way of managing simple dates.
18//! `time`: simple way to manage what time it is, as an `Instant`.
19//! `recurrence`: simple, text-driven recurrence rules, that, yes, don't cover every recurrence but
20//! also make it easy for a human to do most things.
21//! `offset`: language for relative dates, like yesterday, tomorrow, or a month from now.
22//! `query`: parser for human and agent friendly expression of relative dates, into this library's types.
23//! `clock`: easily test for time changes with a testable clock.
24
25pub mod clock;
26pub mod date;
27pub mod offset;
28pub mod query;
29pub mod recurrence;
30pub mod time;
31
32pub(crate) trait DisplayExt {
33 fn displayed(self) -> String;
34}
35
36impl<T: std::fmt::Display> DisplayExt for Option<T> {
37 fn displayed(self) -> String {
38 self.map_or_else(|| "none".to_string(), |v| v.to_string())
39 }
40}
41
42#[derive(Debug, thiserror::Error)]
43pub enum Error {
44 #[error("date is not a valid format. Use YYYY-mm-dd format, surrounded by double quotes.")]
45 InvalidDate,
46 #[error("unable to parse recurrence string: {0}")]
47 InvalidRecurrence(String),
48 #[error("invalid offset: {0}")]
49 InvalidOffset(String),
50}