Skip to content

Commit be6c560

Browse files
authored
Finish the initial implementation of time primitives (#380)
1 parent 8e5a655 commit be6c560

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+1303
-672
lines changed

.scripts/internal-tests-0.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ $rt test-with-features wtx arbitrary
1515
$rt test-with-features wtx argon2
1616
$rt test-with-features wtx base64
1717
$rt test-with-features wtx borsh
18+
$rt test-with-features wtx calendar
1819
$rt test-with-features wtx chrono
1920
$rt test-with-features wtx cl-aux
2021
$rt test-with-features wtx client-api-framework

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ In a way, `WTX` can be seen as an amalgamation that consolidates the functionali
2727

2828
| Technology | Similar Projects | Feature (`wtx`) |
2929
| ------------------------------------------------------ | ------------------------------------------------------------------ | ------------------------ |
30+
| [Calendar][calendar-doc] | [chrono][chrono], [time][time] | calendar |
3031
| [Client API Framework][client-api-framework-doc] | N/A | client-api-framework |
3132
| [Database Client][database-client-doc] | [jdbc][jdbc], [odbc][odbc], [sqlx][sqlx] | postgres, mysql |
3233
| [Database Schema Manager][database-schema-manager-doc] | [flyway][flyway], [liquibase][liquibase], [refinery][refinery] | schema-manager |
@@ -98,6 +99,7 @@ Demonstrations of different use-cases can be found in the `wtx-instances` direct
9899

99100
[^2]: The sum of optional and required dependencies used by the associated binaries.
100101

102+
[calendar-doc]: https://c410-f3r.github.io/wtx/calendar/index.html
101103
[client-api-framework-doc]: https://c410-f3r.github.io/wtx/client-api-framework/index.html
102104
[database-client-doc]: https://c410-f3r.github.io/wtx/database-client/index.html
103105
[database-schema-manager-doc]: https://c410-f3r.github.io/wtx/database-schema-manager/index.html
@@ -110,6 +112,7 @@ Demonstrations of different use-cases can be found in the `wtx-instances` direct
110112

111113
[axum]: https://github.com/tokio-rs/axum
112114
[bb8]: https://github.com/djc/bb8
115+
[chrono]: https://github.com/chronotope/chrono
113116
[deadpool]: https://github.com/deadpool-rs/deadpool
114117
[diesel]: https://github.com/diesel-rs/diesel
115118
[fastapi]: https://github.com/fastapi/fastapi
@@ -125,6 +128,7 @@ Demonstrations of different use-cases can be found in the `wtx-instances` direct
125128
[reqwest]: https://github.com/seanmonstar/reqwest
126129
[spring-boot]: https://github.com/spring-projects/spring-boot
127130
[sqlx]: https://github.com/launchbadge/sqlx
131+
[time]: https://github.com/time-rs/time
128132
[tokio-tungstenite]: https://github.com/snapview/tokio-tungstenite
129133
[tonic]: https://github.com/hyperium/tonic
130134
[uWebSockets]: https://github.com/uNetworking/uWebSockets

wtx-docs/src/SUMMARY.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Summary
22

33
- [Introduction](README.md)
4+
- [Calendar](calendar/README.md)
45
- [Client API Framework](client-api-framework/README.md)
56
- [Database Client](database-client/README.md)
67
- [Encrypted Connections](database-client/encrypted-connections.md)
@@ -12,7 +13,6 @@
1213
- [HTTP/2](http2/README.md)
1314
- [Internal Development](internal-development/README.md)
1415
- [Pool](pool/README.md)
15-
- [Time](time/README.md)
1616
- [UI tools](ui-tools/README.md)
1717
- [WebSocket](web-socket/README.md)
1818
- [WebSocket over HTTP/2](web-socket-over-http2/README.md)

wtx-docs/src/calendar/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Calendar
2+
3+
Provides basic primitives to work with time-related operations.
4+
5+
* `Time`: Clock time with nanosecond precision.
6+
* `Date`: Proleptic Gregorian calendar. Can represent years from -32767 to 32766.
7+
* `DateTime`: ISO-8601 representation without timezones.
8+
9+
To use this functionality, it is necessary to activate the `calendar` feature.
10+
11+
## Example
12+
13+
```rust,edition2024,no_run
14+
{{#rustdoc_include ../../../wtx-instances/generic-examples/calendar.rs}}
15+
```

wtx-docs/src/time/README.md

Lines changed: 0 additions & 15 deletions
This file was deleted.

wtx-fuzz/date_time.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
#![no_main]
44

5-
use wtx::time::DateTime;
5+
use wtx::calendar::DateTime;
66

77
libfuzzer_sys::fuzz_target!(|(value, fmt): (Vec<u8>, Vec<u8>)| {
88
let _rslt = DateTime::parse(&value, &value);

wtx-instances/Cargo.toml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ required-features = ["database-client-postgres-enum"]
4949

5050
# Generic Examples
5151

52+
[[example]]
53+
name = "calendar"
54+
path = "generic-examples/calendar.rs"
55+
required-features = ["calendar"]
56+
5257
[[example]]
5358
name = "client-api-framework"
5459
path = "generic-examples/client-api-framework.rs"
@@ -74,10 +79,6 @@ name = "pool"
7479
path = "generic-examples/pool.rs"
7580
required-features = ["pool"]
7681

77-
[[example]]
78-
name = "time"
79-
path = "generic-examples/time.rs"
80-
8182
# HTTP Server Framework Examples
8283

8384
[[example]]
@@ -154,6 +155,7 @@ database-client-postgres = ["postgres"]
154155
database-client-postgres-composite-type = ["postgres"]
155156
database-client-postgres-enum = ["postgres"]
156157

158+
calendar = ["wtx/calendar"]
157159
client-api-framework = ["serde", "wtx/client-api-framework", "wtx/http-client-pool", "wtx/serde_json", "wtx/web-socket-handshake", "wtx-macros"]
158160
grpc-client = ["grpc", "wtx/grpc-client"]
159161
grpc-server = ["grpc", "wtx/grpc-server", "wtx/nightly"]
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//! Basic time operation.
2+
3+
extern crate wtx;
4+
5+
use wtx::calendar::{Duration, Instant};
6+
7+
fn main() -> wtx::Result<()> {
8+
println!(
9+
"ISO 8601 representation of the next 2 minutes in UTC: {}",
10+
Instant::now_date_time(0)?.add(Duration::from_minutes(2)?)?
11+
);
12+
Ok(())
13+
}

wtx-instances/generic-examples/time.rs

Lines changed: 0 additions & 15 deletions
This file was deleted.

wtx/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ x509-certificate = { default-features = false, optional = true, version = "0.24"
5252
32-tuple-impls = []
5353
arbitrary = ["dep:arbitrary", "std"]
5454
borsh = ["dep:borsh", "std"]
55+
calendar = []
5556
client-api-framework = ["data-transformation"]
5657
data-transformation = []
5758
database = []
@@ -78,7 +79,7 @@ postgres = ["base64", "crypto-common", "database", "digest", "foldhash", "hashbr
7879
quick-protobuf = ["dep:quick-protobuf", "std"]
7980
rand-compat = ["rand_core"]
8081
rustls = ["dep:rustls", "rustls-pki-types"]
81-
schema-manager = ["database"]
82+
schema-manager = ["calendar", "database"]
8283
schema-manager-dev = ["schema-manager"]
8384
serde = ["cl-aux?/serde", "dep:serde"]
8485
serde_json = ["serde", "dep:serde_json", "std"]

wtx/src/calendar.rs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
//! Simple time utilities
2+
3+
mod calendar_error;
4+
mod instant;
5+
6+
#[cfg(feature = "calendar")]
7+
#[macro_use]
8+
mod macros;
9+
10+
#[cfg(feature = "calendar")]
11+
mod ce_days;
12+
#[cfg(feature = "calendar")]
13+
mod date;
14+
#[cfg(feature = "calendar")]
15+
mod date_time;
16+
#[cfg(feature = "calendar")]
17+
mod day;
18+
#[cfg(feature = "calendar")]
19+
mod day_of_year;
20+
#[cfg(feature = "calendar")]
21+
mod duration;
22+
#[cfg(feature = "calendar")]
23+
mod format;
24+
#[cfg(feature = "calendar")]
25+
mod hour;
26+
#[cfg(feature = "calendar")]
27+
mod microsecond;
28+
#[cfg(feature = "calendar")]
29+
mod millisecond;
30+
#[cfg(feature = "calendar")]
31+
mod minute;
32+
#[cfg(feature = "calendar")]
33+
mod misc;
34+
#[cfg(feature = "calendar")]
35+
mod month;
36+
#[cfg(feature = "calendar")]
37+
mod nanosecond;
38+
#[cfg(feature = "calendar")]
39+
mod second;
40+
#[cfg(feature = "calendar")]
41+
mod time;
42+
#[cfg(feature = "calendar")]
43+
mod weekday;
44+
#[cfg(feature = "calendar")]
45+
mod year;
46+
47+
#[cfg(feature = "calendar")]
48+
mod gated {
49+
pub use crate::calendar::{
50+
ce_days::CeDays,
51+
date::Date,
52+
date_time::DateTime,
53+
day::Day,
54+
day_of_year::DayOfYear,
55+
duration::Duration,
56+
format::{parse_bytes_into_tokens, time_token::TimeToken},
57+
hour::Hour,
58+
microsecond::Microsecond,
59+
millisecond::Millisecond,
60+
minute::Minute,
61+
month::Month,
62+
nanosecond::Nanosecond,
63+
second::Second,
64+
time::Time,
65+
weekday::Weekday,
66+
year::Year,
67+
};
68+
69+
pub(crate) const DAYS_PER_4_YEARS: u16 = 1_461;
70+
pub(crate) const DAYS_PER_NON_LEAP_YEAR: u16 = 365;
71+
pub(crate) const DAYS_PER_QUADCENTURY: u32 = 146_097;
72+
/// Number of days between the Common Era and the UNIX epoch.
73+
pub(crate) const EPOCH_CE_DAYS: u32 = 719_163;
74+
pub(crate) const MINUTES_PER_HOUR: u8 = 60;
75+
pub(crate) const MILLISECONDS_PER_SECOND: u16 = 1_000;
76+
pub(crate) const NANOSECONDS_PER_MICROSECONDS: u32 = 1_000;
77+
pub(crate) const NANOSECONDS_PER_MILLISECOND: u32 = 1_000_000;
78+
pub(crate) const NANOSECONDS_PER_SECOND: u32 = 1_000_000_000;
79+
pub(crate) const SECONDS_PER_DAY: u32 = crate::calendar::misc::u16u32(SECONDS_PER_HOUR) * 24;
80+
pub(crate) const SECONDS_PER_HOUR: u16 = crate::calendar::misc::u8u16(SECONDS_PER_MINUTE) * 60;
81+
pub(crate) const SECONDS_PER_MINUTE: u8 = 60;
82+
pub(crate) const YEARS_PER_QUADCENTURY: u16 = 400;
83+
84+
pub(crate) static DAYS_OF_MONTHS: [[u16; 12]; 2] = [
85+
[0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334],
86+
[0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335],
87+
];
88+
}
89+
90+
pub use calendar_error::CalendarError;
91+
#[cfg(feature = "calendar")]
92+
pub use gated::*;
93+
pub use instant::Instant;

wtx/src/time/time_error.rs renamed to wtx/src/calendar/calendar_error.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
/// Time error
1+
/// Calendar error
22
#[derive(Debug)]
3-
pub enum TimeError {
3+
pub enum CalendarError {
44
// Generic
55
//
6+
/// Underlying time structure couldn't hold the value generated during an arithmetic operation.
7+
ArithmeticOverflow,
68
/// Days from CE must be within the `-11967900` ~ `11967535` range
79
InvalidCeDays {
810
/// Invalid received number
@@ -47,7 +49,7 @@ pub enum TimeError {
4749
/// Invalid received number
4850
received: Option<u8>,
4951
},
50-
/// A second can only have up to `999_999_999` nanoseconds
52+
/// A second can only have up to `999_999_999` nanosecond
5153
InvalidNanosecond {
5254
/// Invalid received number
5355
received: u32,
@@ -61,8 +63,6 @@ pub enum TimeError {
6163
},
6264
/// A timestamp in this project can only go up to `32768-12-31`.
6365
InvalidTimestamp,
64-
/// Underlying time structure couldn't hold the value generated during an arithmetic operation.
65-
InvalidTimeArithmetic,
6666
/// A weekday must be, for example, "Mon" or "Monday"
6767
InvalidWeekday,
6868
/// A year be must between `-32767` and `32766`.

wtx/src/time/ce_days.rs renamed to wtx/src/calendar/ce_days.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::time::{Date, TimeError};
1+
use crate::calendar::{CalendarError, Date};
22

33
/// Number of days since the common era (0001-01-01)
44
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
@@ -12,9 +12,9 @@ impl CeDays {
1212

1313
/// Creates a new instance from a valid `num` number.
1414
#[inline]
15-
pub const fn from_num(num: i32) -> Result<Self, TimeError> {
15+
pub const fn from_num(num: i32) -> Result<Self, CalendarError> {
1616
if num < Date::MIN.ce_days() || num > Date::MAX.ce_days() {
17-
return Err(TimeError::InvalidCeDays { received: num });
17+
return Err(CalendarError::InvalidCeDays { received: num });
1818
}
1919
Ok(Self(num))
2020
}

0 commit comments

Comments
 (0)