Skip to content

Commit 02bdd1d

Browse files
authored
archive derive of PartialEq for rkyv - 0.4.x (#959)
1 parent 0f19d6b commit 02bdd1d

File tree

17 files changed

+160
-8
lines changed

17 files changed

+160
-8
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ jobs:
7575
- uses: taiki-e/install-action@cargo-hack
7676
- uses: Swatinem/rust-cache@v2
7777
- run: |
78-
cargo hack check --feature-powerset --optional-deps serde,rkyv \
78+
cargo hack check --feature-powerset --optional-deps serde \
7979
--skip __internal_bench,iana-time-zone,pure-rust-locales,libc,winapi \
8080
--all-targets
8181
# run using `bash` on all platforms for consistent

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,15 @@ clock = ["std", "winapi", "iana-time-zone", "android-tzdata"]
2626
oldtime = []
2727
wasmbind = ["wasm-bindgen", "js-sys"]
2828
unstable-locales = ["pure-rust-locales"]
29+
rkyv-validation = ["rkyv/validation"]
2930
__internal_bench = []
3031

3132
[dependencies]
3233
num-traits = { version = "0.2", default-features = false }
3334
rustc-serialize = { version = "0.3.20", optional = true }
3435
serde = { version = "1.0.99", default-features = false, optional = true }
3536
pure-rust-locales = { version = "0.7", optional = true }
36-
rkyv = { version = "0.7", optional = true }
37+
rkyv = { version = "0.7.41", optional = true }
3738
arbitrary = { version = "1.0.0", features = ["derive"], optional = true }
3839

3940
[target.'cfg(all(target_arch = "wasm32", not(any(target_os = "emscripten", target_os = "wasi"))))'.dependencies]

src/date.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ impl<Tz: TimeZone> Eq for Date<Tz> {}
479479

480480
impl<Tz: TimeZone> PartialOrd for Date<Tz> {
481481
fn partial_cmp(&self, other: &Date<Tz>) -> Option<Ordering> {
482-
self.date.partial_cmp(&other.date)
482+
Some(self.cmp(other))
483483
}
484484
}
485485

src/datetime/mod.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ mod tests;
5151
/// [`TimeZone`](./offset/trait.TimeZone.html) implementations.
5252
#[derive(Clone)]
5353
#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
54+
#[cfg_attr(feature = "rkyv", archive(compare(PartialEq, PartialOrd)))]
55+
#[cfg_attr(feature = "rkyv-validation", archive(check_bytes))]
5456
pub struct DateTime<Tz: TimeZone> {
5557
datetime: NaiveDateTime,
5658
offset: Tz::Offset,
@@ -1504,6 +1506,31 @@ impl<Tz: TimeZone> fmt::Debug for DateTime<Tz> {
15041506
}
15051507
}
15061508

1509+
// `fmt::Debug` is hand implemented for the `rkyv::Archive` variant of `DateTime` because
1510+
// deriving a trait recursively does not propagate trait defined associated types with their own
1511+
// constraints:
1512+
// In our case `<<Tz as offset::TimeZone>::Offset as Archive>::Archived`
1513+
// cannot be formatted using `{:?}` because it doesn't implement `Debug`.
1514+
// See below for further discussion:
1515+
// * https://github.com/rust-lang/rust/issues/26925
1516+
// * https://github.com/rkyv/rkyv/issues/333
1517+
// * https://github.com/dtolnay/syn/issues/370
1518+
#[cfg(feature = "rkyv-validation")]
1519+
impl<Tz: TimeZone> fmt::Debug for ArchivedDateTime<Tz>
1520+
where
1521+
Tz: Archive,
1522+
<Tz as Archive>::Archived: fmt::Debug,
1523+
<<Tz as TimeZone>::Offset as Archive>::Archived: fmt::Debug,
1524+
<Tz as TimeZone>::Offset: fmt::Debug + Archive,
1525+
{
1526+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1527+
f.debug_struct("ArchivedDateTime")
1528+
.field("datetime", &self.datetime)
1529+
.field("offset", &self.offset)
1530+
.finish()
1531+
}
1532+
}
1533+
15071534
impl<Tz: TimeZone> fmt::Display for DateTime<Tz>
15081535
where
15091536
Tz::Offset: fmt::Display,

src/duration.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,10 @@ macro_rules! try_opt {
5454
#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
5555
#[cfg_attr(
5656
feature = "rkyv",
57+
archive(compare(PartialEq, PartialOrd)),
5758
archive_attr(derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash))
5859
)]
60+
#[cfg_attr(feature = "rkyv-validation", archive(check_bytes))]
5961
pub struct Duration {
6062
secs: i64,
6163
nanos: i32, // Always 0 <= nanos < NANOS_PER_SEC
@@ -795,4 +797,12 @@ mod tests {
795797
Err(OutOfRangeError(()))
796798
);
797799
}
800+
801+
#[test]
802+
#[cfg(feature = "rkyv-validation")]
803+
fn test_rkyv_validation() {
804+
let duration = Duration::seconds(1);
805+
let bytes = rkyv::to_bytes::<_, 16>(&duration).unwrap();
806+
assert_eq!(rkyv::from_bytes::<Duration>(&bytes).unwrap(), duration);
807+
}
798808
}

src/format/scan.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ where
274274
};
275275
s = match s.len() {
276276
len if len >= 2 => &s[2..],
277-
len if len == 0 => s,
277+
0 => s,
278278
_ => return Err(TOO_SHORT),
279279
};
280280

src/month.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,10 @@ use crate::OutOfRange;
3333
#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
3434
#[cfg_attr(
3535
feature = "rkyv",
36+
archive(compare(PartialEq)),
3637
archive_attr(derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash))
3738
)]
39+
#[cfg_attr(feature = "rkyv-validation", archive(check_bytes))]
3840
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
3941
pub enum Month {
4042
/// January
@@ -417,4 +419,12 @@ mod tests {
417419
from_str::<Month>(string).unwrap_err();
418420
}
419421
}
422+
423+
#[test]
424+
#[cfg(feature = "rkyv-validation")]
425+
fn test_rkyv_validation() {
426+
let month = Month::January;
427+
let bytes = rkyv::to_bytes::<_, 1>(&month).unwrap();
428+
assert_eq!(rkyv::from_bytes::<Month>(&bytes).unwrap(), month);
429+
}
420430
}

src/naive/date.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,10 @@ impl Days {
192192
#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
193193
#[cfg_attr(
194194
feature = "rkyv",
195+
archive(compare(PartialEq, PartialOrd)),
195196
archive_attr(derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash))
196197
)]
198+
#[cfg_attr(feature = "rkyv-validation", archive(check_bytes))]
197199
pub struct NaiveDate {
198200
ymdf: DateImpl, // (year << 13) | of
199201
}
@@ -3324,6 +3326,18 @@ mod tests {
33243326
}
33253327
}
33263328

3329+
#[test]
3330+
#[cfg(feature = "rkyv-validation")]
3331+
fn test_rkyv_validation() {
3332+
let date_min = NaiveDate::MIN;
3333+
let bytes = rkyv::to_bytes::<_, 4>(&date_min).unwrap();
3334+
assert_eq!(rkyv::from_bytes::<NaiveDate>(&bytes).unwrap(), date_min);
3335+
3336+
let date_max = NaiveDate::MAX;
3337+
let bytes = rkyv::to_bytes::<_, 4>(&date_max).unwrap();
3338+
assert_eq!(rkyv::from_bytes::<NaiveDate>(&bytes).unwrap(), date_max);
3339+
}
3340+
33273341
// MAX_YEAR-12-31 minus 0000-01-01
33283342
// = (MAX_YEAR-12-31 minus 0000-12-31) + (0000-12-31 - 0000-01-01)
33293343
// = MAX_YEAR * 365 + (# of leap years from 0001 to MAX_YEAR) + 365

src/naive/datetime/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,10 @@ pub const MAX_DATETIME: NaiveDateTime = NaiveDateTime::MAX;
7777
#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
7878
#[cfg_attr(
7979
feature = "rkyv",
80+
archive(compare(PartialEq, PartialOrd)),
8081
archive_attr(derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash))
8182
)]
83+
#[cfg_attr(feature = "rkyv-validation", archive(check_bytes))]
8284
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
8385
pub struct NaiveDateTime {
8486
date: NaiveDate,

src/naive/datetime/tests.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,3 +536,15 @@ fn test_and_timezone_min_max_dates() {
536536
}
537537
}
538538
}
539+
540+
#[test]
541+
#[cfg(feature = "rkyv-validation")]
542+
fn test_rkyv_validation() {
543+
let dt_min = NaiveDateTime::MIN;
544+
let bytes = rkyv::to_bytes::<_, 12>(&dt_min).unwrap();
545+
assert_eq!(rkyv::from_bytes::<NaiveDateTime>(&bytes).unwrap(), dt_min);
546+
547+
let dt_max = NaiveDateTime::MAX;
548+
let bytes = rkyv::to_bytes::<_, 12>(&dt_max).unwrap();
549+
assert_eq!(rkyv::from_bytes::<NaiveDateTime>(&bytes).unwrap(), dt_max);
550+
}

src/naive/isoweek.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@ use rkyv::{Archive, Deserialize, Serialize};
2020
#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
2121
#[cfg_attr(
2222
feature = "rkyv",
23+
archive(compare(PartialEq)),
2324
archive_attr(derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash))
2425
)]
26+
#[cfg_attr(feature = "rkyv-validation", archive(check_bytes))]
2527
pub struct IsoWeek {
2628
// note that this allows for larger year range than `NaiveDate`.
2729
// this is crucial because we have an edge case for the first and last week supported,
@@ -151,6 +153,8 @@ impl fmt::Debug for IsoWeek {
151153

152154
#[cfg(test)]
153155
mod tests {
156+
#[cfg(feature = "rkyv-validation")]
157+
use super::IsoWeek;
154158
use crate::naive::{internals, NaiveDate};
155159
use crate::Datelike;
156160

@@ -205,4 +209,16 @@ mod tests {
205209
assert!(monday.iso_week() >= friday.iso_week());
206210
assert!(monday.iso_week() <= friday.iso_week());
207211
}
212+
213+
#[test]
214+
#[cfg(feature = "rkyv-validation")]
215+
fn test_rkyv_validation() {
216+
let minweek = NaiveDate::MIN.iso_week();
217+
let bytes = rkyv::to_bytes::<_, 4>(&minweek).unwrap();
218+
assert_eq!(rkyv::from_bytes::<IsoWeek>(&bytes).unwrap(), minweek);
219+
220+
let maxweek = NaiveDate::MAX.iso_week();
221+
let bytes = rkyv::to_bytes::<_, 4>(&maxweek).unwrap();
222+
assert_eq!(rkyv::from_bytes::<IsoWeek>(&bytes).unwrap(), maxweek);
223+
}
208224
}

src/naive/time/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,10 @@ mod tests;
206206
#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
207207
#[cfg_attr(
208208
feature = "rkyv",
209+
archive(compare(PartialEq, PartialOrd)),
209210
archive_attr(derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash))
210211
)]
212+
#[cfg_attr(feature = "rkyv-validation", archive(check_bytes))]
211213
pub struct NaiveTime {
212214
secs: u32,
213215
frac: u32,

src/naive/time/tests.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,3 +376,15 @@ fn test_overflowing_offset() {
376376
assert_eq!(t.overflowing_add_offset(positive_offset).0, t + positive_offset);
377377
assert_eq!(t.overflowing_sub_offset(positive_offset).0, t - positive_offset);
378378
}
379+
380+
#[test]
381+
#[cfg(feature = "rkyv-validation")]
382+
fn test_rkyv_validation() {
383+
let t_min = NaiveTime::MIN;
384+
let bytes = rkyv::to_bytes::<_, 8>(&t_min).unwrap();
385+
assert_eq!(rkyv::from_bytes::<NaiveTime>(&bytes).unwrap(), t_min);
386+
387+
let t_max = NaiveTime::MAX;
388+
let bytes = rkyv::to_bytes::<_, 8>(&t_max).unwrap();
389+
assert_eq!(rkyv::from_bytes::<NaiveTime>(&bytes).unwrap(), t_max);
390+
}

src/offset/fixed.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,12 @@ use crate::naive::{NaiveDate, NaiveDateTime};
2121
/// [`west_opt`](#method.west_opt) methods for examples.
2222
#[derive(PartialEq, Eq, Hash, Copy, Clone)]
2323
#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
24-
#[cfg_attr(feature = "rkyv", archive_attr(derive(Clone, Copy, PartialEq, Eq, Hash, Debug)))]
24+
#[cfg_attr(
25+
feature = "rkyv",
26+
archive(compare(PartialEq)),
27+
archive_attr(derive(Clone, Copy, PartialEq, Eq, Hash, Debug))
28+
)]
29+
#[cfg_attr(feature = "rkyv-validation", archive(check_bytes))]
2530
pub struct FixedOffset {
2631
local_minus_utc: i32,
2732
}
@@ -222,4 +227,12 @@ mod tests {
222227
let offset = FixedOffset::from_str("+06:30").unwrap();
223228
assert_eq!(offset.local_minus_utc, (6 * 3600) + 1800);
224229
}
230+
231+
#[test]
232+
#[cfg(feature = "rkyv-validation")]
233+
fn test_rkyv_validation() {
234+
let offset = FixedOffset::from_str("-0500").unwrap();
235+
let bytes = rkyv::to_bytes::<_, 4>(&offset).unwrap();
236+
assert_eq!(rkyv::from_bytes::<FixedOffset>(&bytes).unwrap(), offset);
237+
}
225238
}

src/offset/local/mod.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ mod tz_info;
105105
/// ```
106106
#[derive(Copy, Clone, Debug)]
107107
#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
108-
#[cfg_attr(feature = "rkyv", archive_attr(derive(Clone, Copy, Debug)))]
108+
#[cfg_attr(feature = "rkyv", archive(compare(PartialEq)), archive_attr(derive(Clone, Copy, Debug)))]
109+
#[cfg_attr(feature = "rkyv-validation", archive(check_bytes))]
109110
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
110111
pub struct Local;
111112

@@ -258,4 +259,17 @@ mod tests {
258259
);
259260
}
260261
}
262+
263+
#[test]
264+
#[cfg(feature = "rkyv-validation")]
265+
fn test_rkyv_validation() {
266+
let local = Local;
267+
// Local is a ZST and serializes to 0 bytes
268+
let bytes = rkyv::to_bytes::<_, 0>(&local).unwrap();
269+
assert_eq!(bytes.len(), 0);
270+
271+
// but is deserialized to an archived variant without a
272+
// wrapping object
273+
assert_eq!(rkyv::from_bytes::<Local>(&bytes).unwrap(), super::ArchivedLocal);
274+
}
261275
}

src/offset/utc.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,12 @@ use crate::{Date, DateTime};
4242
/// ```
4343
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
4444
#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
45-
#[cfg_attr(feature = "rkyv", archive_attr(derive(Clone, Copy, PartialEq, Eq, Debug, Hash)))]
45+
#[cfg_attr(
46+
feature = "rkyv",
47+
archive(compare(PartialEq)),
48+
archive_attr(derive(Clone, Copy, PartialEq, Eq, Debug, Hash))
49+
)]
50+
#[cfg_attr(feature = "rkyv-validation", archive(check_bytes))]
4651
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
4752
pub struct Utc;
4853

src/weekday.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,12 @@ use crate::OutOfRange;
3232
#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)]
3333
#[cfg_attr(feature = "rustc-serialize", derive(RustcEncodable, RustcDecodable))]
3434
#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
35-
#[cfg_attr(feature = "rkyv", archive_attr(derive(Clone, Copy, PartialEq, Eq, Debug, Hash)))]
35+
#[cfg_attr(
36+
feature = "rkyv",
37+
archive(compare(PartialEq)),
38+
archive_attr(derive(Clone, Copy, PartialEq, Eq, Debug, Hash))
39+
)]
40+
#[cfg_attr(feature = "rkyv-validation", archive(check_bytes))]
3641
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
3742
pub enum Weekday {
3843
/// Monday.
@@ -381,4 +386,13 @@ mod tests {
381386
from_str::<Weekday>(str).unwrap_err();
382387
}
383388
}
389+
390+
#[test]
391+
#[cfg(feature = "rkyv-validation")]
392+
fn test_rkyv_validation() {
393+
let mon = Weekday::Mon;
394+
let bytes = rkyv::to_bytes::<_, 1>(&mon).unwrap();
395+
396+
assert_eq!(rkyv::from_bytes::<Weekday>(&bytes).unwrap(), mon);
397+
}
384398
}

0 commit comments

Comments
 (0)