Skip to content

Commit b23a415

Browse files
committed
feat(chrono): refactor chrono support and fuzz testing
- Separate chrono and time feature support by moving chrono-specific code into dedicated modules/files and removing the shared Date component - Implement conversion from DateTimeDecode to chrono::NaiveDateTime and remove the previous conversion from DateTimeEncode - Remove support for chrono::DateTime<FixedOffset> - Add fuzz testing for: - chrono::NaiveTime - chrono::NaiveDate - chrono::NaiveDateTime - chrono::DateTime<Utc> This change improves modularity, eliminates unnecessary shared types, and strengthens testing coverage for the remaining chrono types.
1 parent 804163f commit b23a415

File tree

13 files changed

+75
-173
lines changed

13 files changed

+75
-173
lines changed

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ zstd = "0.13.0"
4444
derive = [ "dep:bitcode_derive" ]
4545
std = [ "serde?/std", "glam?/std", "arrayvec?/std" ]
4646
default = [ "derive", "std" ]
47-
chrono_datetime_fixedoffset = ["dep:chrono"]
4847

4948
[package.metadata.docs.rs]
5049
features = [ "derive", "serde", "std" ]

fuzz/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ cargo-fuzz = true
1010

1111
[dependencies]
1212
arrayvec = { version = "0.7", features = ["serde"] }
13-
bitcode = { path = "..", features = [ "arrayvec", "rust_decimal", "serde", "time" ] }
13+
bitcode = { path = "..", features = [ "arrayvec", "rust_decimal", "serde", "time" ,"chrono"] }
1414
libfuzzer-sys = "0.4"
1515
rust_decimal = "1.36.0"
1616
serde = { version ="1.0", features = [ "derive" ] }
@@ -24,4 +24,4 @@ members = ["."]
2424
name = "fuzz"
2525
path = "fuzz_targets/fuzz.rs"
2626
test = false
27-
doc = false
27+
doc = false

fuzz/fuzz_targets/fuzz.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ use libfuzzer_sys::fuzz_target;
33
extern crate bitcode;
44
use arrayvec::{ArrayString, ArrayVec};
55
use bitcode::{Decode, DecodeOwned, Encode};
6+
use rust_decimal::Decimal;
67
use serde::de::DeserializeOwned;
78
use serde::{Deserialize, Serialize};
89
use std::collections::{BTreeMap, HashMap};
910
use std::fmt::Debug;
11+
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
1012
use std::num::NonZeroU32;
1113
use std::time::Duration;
12-
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
13-
use rust_decimal::Decimal;
1414

1515
#[inline(never)]
1616
fn test_derive<T: Debug + PartialEq + Encode + DecodeOwned>(data: &[u8]) {
@@ -148,10 +148,20 @@ fuzz_target!(|data: &[u8]| {
148148
A,
149149
B,
150150
C(u16),
151-
D { a: u8, b: u8, #[serde(skip)] #[bitcode(skip)] c: u8 },
151+
D {
152+
a: u8,
153+
b: u8,
154+
#[serde(skip)]
155+
#[bitcode(skip)]
156+
c: u8,
157+
},
152158
E(String),
153159
F,
154-
G(#[bitcode(skip)] #[serde(skip)] i16),
160+
G(
161+
#[bitcode(skip)]
162+
#[serde(skip)]
163+
i16,
164+
),
155165
P(BTreeMap<u16, u8>),
156166
}
157167

@@ -233,5 +243,9 @@ fuzz_target!(|data: &[u8]| {
233243
SocketAddrV6,
234244
SocketAddr,
235245
time::Time,
246+
chrono::NaiveTime,
247+
chrono::NaiveDate,
248+
chrono::NaiveDateTime,
249+
chrono::DateTime<Utc>,
236250
);
237251
});

src/ext/chrono.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
mod date_time_utc;
2+
mod naive_date;
3+
mod naive_date_time;
4+
mod naive_time;
5+
6+
use crate::int::ranged_int;
7+
8+
ranged_int!(Hour, u8, 0, 23);
9+
ranged_int!(Minute, u8, 0, 59);
10+
ranged_int!(Second, u8, 0, 59);
11+
ranged_int!(Nanosecond, u32, 0, 1_999_999_999);
12+
13+
type TimeEncode = (u8, u8, u8, u32);
14+
type TimeDecode = (Hour, Minute, Second, Nanosecond);
15+
16+
type DateEncode = i32;
17+
type DateDecode = i32;
18+
19+
type DateTimeEncode = (DateEncode, TimeEncode);
20+
type DateTimeDecode = (DateEncode, TimeDecode);
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use chrono::{DateTime, NaiveDateTime, Utc};
22

33
use crate::{
44
convert::{impl_convert, ConvertFrom},
5-
ext::date::{DateTimeDecode, DateTimeEncode},
5+
ext::chrono::{DateTimeDecode, DateTimeEncode},
66
};
77

88
impl_convert!(DateTime<Utc>, DateTimeEncode, DateTimeDecode);
@@ -13,8 +13,8 @@ impl ConvertFrom<&DateTime<Utc>> for DateTimeEncode {
1313
}
1414
}
1515

16-
impl ConvertFrom<DateTimeEncode> for DateTime<Utc> {
17-
fn convert_from(enc: DateTimeEncode) -> Self {
16+
impl ConvertFrom<DateTimeDecode> for DateTime<Utc> {
17+
fn convert_from(enc: DateTimeDecode) -> Self {
1818
let naive = NaiveDateTime::convert_from(enc);
1919

2020
DateTime::from_naive_utc_and_offset(naive, Utc)
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,20 @@ use chrono::{Datelike, NaiveDate};
22

33
use crate::{
44
convert::{impl_convert, ConvertFrom},
5-
ext::date::{DateDecode, DateEncode},
5+
ext::chrono::{DateDecode, DateEncode},
66
};
77

88
impl_convert!(NaiveDate, DateEncode, DateDecode);
99

1010
impl ConvertFrom<&NaiveDate> for DateEncode {
1111
fn convert_from(days: &NaiveDate) -> Self {
12-
days.num_days_from_ce() - 719_163 // 1970-1-1
12+
days.num_days_from_ce()
1313
}
1414
}
1515

1616
impl ConvertFrom<DateDecode> for NaiveDate {
1717
fn convert_from(days: DateDecode) -> Self {
18-
NaiveDate::from_num_days_from_ce_opt(days + 719_163).unwrap() // 1970-1-1
18+
NaiveDate::from_num_days_from_ce_opt(days).unwrap()
1919
}
2020
}
2121

@@ -28,6 +28,7 @@ mod tests {
2828
NaiveDate::from_ymd_opt(2025, 10, 6).unwrap(),
2929
NaiveDate::from_ymd_opt(1, 1, 1).unwrap(),
3030
NaiveDate::from_ymd_opt(-44, 3, 15).unwrap(), // BCE
31+
NaiveDate::from_ymd_opt(-44, 3, 15).unwrap(), // BCE
3132
NaiveDate::from_ymd_opt(9999, 12, 31).unwrap(),
3233
];
3334

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ use chrono::{NaiveDate, NaiveDateTime, NaiveTime};
22

33
use crate::{
44
convert::{impl_convert, ConvertFrom},
5-
ext::date::{DateEncode, DateTimeDecode, DateTimeEncode, TimeEncode},
5+
ext::chrono::{DateEncode, DateTimeDecode, DateTimeEncode, TimeEncode},
66
};
77

88
impl_convert!(NaiveDateTime, DateTimeEncode, DateTimeDecode);
99

1010
impl ConvertFrom<&NaiveDateTime> for DateTimeEncode {
11+
#[inline(always)]
1112
fn convert_from(x: &NaiveDateTime) -> Self {
1213
(
1314
DateEncode::convert_from(&x.date()),
@@ -16,13 +17,10 @@ impl ConvertFrom<&NaiveDateTime> for DateTimeEncode {
1617
}
1718
}
1819

19-
impl ConvertFrom<DateTimeEncode> for NaiveDateTime {
20-
fn convert_from((date, time): DateTimeEncode) -> Self {
21-
NaiveDateTime::new(
22-
NaiveDate::convert_from(date),
23-
NaiveTime::from_hms_nano_opt(time.0 as u32, time.1 as u32, time.2 as u32, time.3)
24-
.unwrap(),
25-
)
20+
impl ConvertFrom<DateTimeDecode> for NaiveDateTime {
21+
#[inline(always)]
22+
fn convert_from((date, time): DateTimeDecode) -> Self {
23+
NaiveDateTime::new(NaiveDate::convert_from(date), NaiveTime::convert_from(time))
2624
}
2725
}
2826

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
use crate::{
22
convert::{impl_convert, ConvertFrom},
3-
ext::date::{TimeDecode, TimeEncode},
3+
ext::chrono::{TimeDecode, TimeEncode},
44
};
55
use chrono::{NaiveTime, Timelike};
66

77
impl_convert!(NaiveTime, TimeEncode, TimeDecode);
88

99
impl ConvertFrom<&NaiveTime> for TimeEncode {
10+
#[inline(always)]
1011
fn convert_from(value: &NaiveTime) -> Self {
1112
(
1213
value.hour() as u8,
@@ -18,12 +19,15 @@ impl ConvertFrom<&NaiveTime> for TimeEncode {
1819
}
1920

2021
impl ConvertFrom<TimeDecode> for NaiveTime {
22+
#[inline(always)]
2123
fn convert_from(value: TimeDecode) -> Self {
24+
let (hour, min, sec, nano) = value;
25+
2226
NaiveTime::from_hms_nano_opt(
23-
value.0.into_inner() as u32,
24-
value.1.into_inner() as u32,
25-
value.2.into_inner() as u32,
26-
value.3.into_inner(),
27+
hour.into_inner() as u32,
28+
min.into_inner() as u32,
29+
sec.into_inner() as u32,
30+
nano.into_inner(),
2731
)
2832
.unwrap()
2933
}

src/ext/date.rs

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

src/ext/date/chrono.rs

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

0 commit comments

Comments
 (0)