From bf476ed2c859f00854136d881fe76a18b14c9762 Mon Sep 17 00:00:00 2001 From: Anders Musikka Date: Tue, 2 Jul 2024 15:53:50 +0200 Subject: [PATCH 1/3] feat:Support for Duration and SystemTime --- savefile-test/src/lib.rs | 32 ++++++- ...ompatibility__abi_schemas_get_def.snap.new | 64 +++++++++++++ savefile/src/lib.rs | 93 ++++++++++++++++++- 3 files changed, 187 insertions(+), 2 deletions(-) create mode 100644 savefile-test/src/savefile_abi_test/snapshots/savefile_test__savefile_abi_test__argument_backward_compatibility__abi_schemas_get_def.snap.new diff --git a/savefile-test/src/lib.rs b/savefile-test/src/lib.rs index 368ebd7..39c9534 100644 --- a/savefile-test/src/lib.rs +++ b/savefile-test/src/lib.rs @@ -840,7 +840,7 @@ use std::sync::atomic::{AtomicI16, AtomicI32, AtomicI64, AtomicI8, AtomicIsize, #[cfg(test)] use std::sync::atomic::{AtomicU8, AtomicUsize, Ordering}; use std::sync::Arc; -use std::time::Instant; +use std::time::{Duration, Instant, SystemTime}; #[test] pub fn test_atomic() { @@ -1545,6 +1545,36 @@ pub fn test_indexset() { assert_roundtrip(iset.clone()); } +#[test] +fn test_systemtime() { + roundtrip(SystemTime::UNIX_EPOCH); + roundtrip(SystemTime::UNIX_EPOCH + Duration::from_nanos(1)); + roundtrip(SystemTime::UNIX_EPOCH - Duration::from_nanos(1)); + + roundtrip(SystemTime::UNIX_EPOCH + Duration::from_nanos(4_000_000_000)); + + roundtrip(SystemTime::UNIX_EPOCH + Duration::from_secs(1_000_000_000)); + + + roundtrip(SystemTime::UNIX_EPOCH + Duration::from_nanos(u64::MAX)); + roundtrip(SystemTime::UNIX_EPOCH - Duration::from_nanos(u64::MAX)); + roundtrip(SystemTime::UNIX_EPOCH + Duration::from_secs(4_000_000_000)); + roundtrip(SystemTime::UNIX_EPOCH - Duration::from_secs(4_000_000_000)); + + roundtrip(SystemTime::UNIX_EPOCH + Duration::from_secs(58_000_000_000) + Duration::from_nanos((1u64)<<55)); + roundtrip(SystemTime::UNIX_EPOCH - (Duration::from_secs(8_000_000_000) + Duration::from_nanos((1u64)<<55))); + + roundtrip(SystemTime::UNIX_EPOCH + Duration::from_secs(365u64*86400 * 150_000_000_000)); //Test we can roundtrip dates 150 billion years into the future. It should be enough (oh man if this would ever come back to hurt us it would be funny ...) + roundtrip(SystemTime::UNIX_EPOCH - Duration::from_secs(365u64*86400 * 15_000_000_000)); +} +#[test] +fn test_duration() { + roundtrip(Duration::from_nanos(0)); + roundtrip(Duration::from_nanos(1)); + roundtrip(Duration::from_nanos(u64::MAX)); + roundtrip(Duration::from_nanos(999_999_999) + Duration::from_secs(u64::MAX)); +} + #[cfg(test)] struct RawStruct { a: u64, diff --git a/savefile-test/src/savefile_abi_test/snapshots/savefile_test__savefile_abi_test__argument_backward_compatibility__abi_schemas_get_def.snap.new b/savefile-test/src/savefile_abi_test/snapshots/savefile_test__savefile_abi_test__argument_backward_compatibility__abi_schemas_get_def.snap.new new file mode 100644 index 0000000..1f5a383 --- /dev/null +++ b/savefile-test/src/savefile_abi_test/snapshots/savefile_test__savefile_abi_test__argument_backward_compatibility__abi_schemas_get_def.snap.new @@ -0,0 +1,64 @@ +--- +source: savefile-test/src/savefile_abi_test/argument_backward_compatibility.rs +assertion_line: 95 +expression: exportable +--- +name: ArgInterfaceV2 +methods: + - name: sums + info: + return_value: + Primitive: schema_u32 + arguments: + - schema: + Struct: + dbg_name: ArgArgument + size: 8 + alignment: 4 + fields: + - name: data1 + value: + Primitive: schema_u32 + offset: ~ + - name: data2 + value: + Primitive: schema_u32 + offset: 0 + - schema: + Struct: + dbg_name: ArgArgument + size: 8 + alignment: 4 + fields: + - name: data1 + value: + Primitive: schema_u32 + offset: ~ + - name: data2 + value: + Primitive: schema_u32 + offset: 0 + - name: enum_arg + info: + return_value: + Primitive: + schema_string: DataCapacityLength + arguments: + - schema: + Enum: + dbg_name: EnumArgument + variants: + - name: Variant1 + discriminant: 0 + fields: [] + - name: Variant2 + discriminant: 1 + fields: [] + discriminant_size: 1 + has_explicit_repr: false + size: 1 + alignment: 1 + - name: function_existing_in_v2 + info: + return_value: ZeroSize + arguments: [] diff --git a/savefile/src/lib.rs b/savefile/src/lib.rs index 29a89aa..4cd4c48 100644 --- a/savefile/src/lib.rs +++ b/savefile/src/lib.rs @@ -6532,7 +6532,7 @@ use std::path::{Path, PathBuf}; use std::ptr::NonNull; use std::slice; use std::sync::Arc; - +use std::time::{Duration, SystemTime}; use byteorder::{ReadBytesExt, WriteBytesExt}; use memoffset::offset_of_tuple; @@ -7385,6 +7385,97 @@ impl WithSchema for Canary1 { } } +impl WithSchema for Duration { + fn schema(_version: u32, _context: &mut WithSchemaContext) -> Schema { + Schema::Struct(SchemaStruct{ + dbg_name: "Duration".to_string(), + size: None, + alignment: None, + fields: vec![ + Field { + name: "Duration".to_string(), + value: Box::new(Schema::Primitive(SchemaPrimitive::schema_u128)), + offset: None, + } + ], + }) + } +} +impl Packed for Duration { + +} +impl Serialize for Duration { + fn serialize(&self, serializer: &mut Serializer) -> Result<(), SavefileError> { + serializer.write_u128(self.as_nanos()) + } +} +impl Deserialize for Duration { + fn deserialize(deserializer: &mut Deserializer) -> Result { + let temp = deserializer.read_u128()?; + Ok(Duration::from_secs((temp/1_000_000_000) as u64) + Duration::from_nanos((temp % 1_000_000_000) as u64)) + } +} + +impl WithSchema for SystemTime { + fn schema(_version: u32, _context: &mut WithSchemaContext) -> Schema { + Schema::Struct(SchemaStruct{ + dbg_name: "SystemTime".to_string(), + size: None, + alignment: None, + fields: vec![ + Field { + name: "SystemTimeDuration".to_string(), + value: Box::new(Schema::Primitive(SchemaPrimitive::schema_u128)), + offset: None, + } + ], + }) + } +} +impl Packed for SystemTime { + +} +impl Serialize for SystemTime { + fn serialize(&self, serializer: &mut Serializer) -> Result<(), SavefileError> { + match self.duration_since(SystemTime::UNIX_EPOCH) { + Ok(nanos) => { + let temp = nanos.as_nanos(); + if temp >= 1u128<<120 { + return Err(SavefileError::GeneralError {msg: "Savefile cannot handle dates where the year is larger than ca 10^19 years.".to_string()}); + } + serializer.write_u128(temp)?; + } + Err(err) => { //Before UNIX Epoch + let mut temp = err.duration().as_nanos(); + if temp >= 1u128<<120 { + return Err(SavefileError::GeneralError {msg: "Savefile cannot handle dates much earlier than the creation of the universe.".to_string()}); + } + temp |= 1u128<<127; + serializer.write_u128(temp)?; + } + } + Ok(()) + } +} +fn u128_duration_nanos(nanos: u128) -> Duration { + if nanos > u64::MAX as u128 { + Duration::from_nanos((nanos % 1_000_000_000) as u64) + Duration::from_secs((nanos/1_000_000_000) as u64) + } else { + Duration::from_nanos(nanos as u64) + } +} +impl Deserialize for SystemTime { + fn deserialize(deserializer: &mut Deserializer) -> Result { + let mut temp = deserializer.read_u128()?; + if temp >= (1u128<<127) { + temp &= (1u128<<127)-1; //Before UNIX Epoch + return Ok(SystemTime::UNIX_EPOCH - u128_duration_nanos(temp)); + } else { + return Ok(SystemTime::UNIX_EPOCH + u128_duration_nanos(temp)); + } + } +} + #[derive(Clone, Debug)] struct PathElement { key: String, From 291e3d7023750a2957f6f0c76e42b91e5b8350c6 Mon Sep 17 00:00:00 2001 From: Anders Musikka Date: Tue, 2 Jul 2024 22:11:33 +0200 Subject: [PATCH 2/3] chore: release (#61) * chore: release * chore: Bump savefile-derive also, so it stays in sync --- Cargo.lock | 6 +++--- savefile-abi/CHANGELOG.md | 5 +++++ savefile-abi/Cargo.toml | 6 +++--- savefile-derive/Cargo.toml | 2 +- savefile-test/Cargo.toml | 2 +- savefile/CHANGELOG.md | 5 +++++ savefile/Cargo.toml | 6 +++--- 7 files changed, 21 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3fbf31a..2ce6042 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -448,7 +448,7 @@ dependencies = [ [[package]] name = "savefile" -version = "0.17.4" +version = "0.17.5" dependencies = [ "arrayvec", "bit-set", @@ -471,7 +471,7 @@ dependencies = [ [[package]] name = "savefile-abi" -version = "0.17.4" +version = "0.17.5" dependencies = [ "byteorder", "libloading", @@ -512,7 +512,7 @@ dependencies = [ [[package]] name = "savefile-derive" -version = "0.17.4" +version = "0.17.5" dependencies = [ "proc-macro-error", "proc-macro2", diff --git a/savefile-abi/CHANGELOG.md b/savefile-abi/CHANGELOG.md index 57cd15a..74b92fd 100644 --- a/savefile-abi/CHANGELOG.md +++ b/savefile-abi/CHANGELOG.md @@ -6,6 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.17.5](https://github.com/avl/savefile/compare/savefile-abi-v0.17.4...savefile-abi-v0.17.5) - 2024-07-02 + +### Other +- updated the following local packages: savefile + ## [0.17.4](https://github.com/avl/savefile/compare/savefile-abi-v0.17.3...savefile-abi-v0.17.4) - 2024-05-12 ### Added diff --git a/savefile-abi/Cargo.toml b/savefile-abi/Cargo.toml index 165837b..5757db0 100644 --- a/savefile-abi/Cargo.toml +++ b/savefile-abi/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "savefile-abi" -version = "0.17.4" +version = "0.17.5" edition = "2021" authors = ["Anders Musikka "] documentation = "https://docs.rs/savefile-abi/" @@ -17,8 +17,8 @@ keywords = ["dylib", "dlopen", "ffi"] license = "MIT/Apache-2.0" [dependencies] -savefile = { path="../savefile", version = "=0.17.4" } -savefile-derive = { path="../savefile-derive", version = "=0.17.4" } +savefile = { path="../savefile", version = "=0.17.5" } +savefile-derive = { path="../savefile-derive", version = "=0.17.5" } byteorder = "1.4" libloading = "0.8" diff --git a/savefile-derive/Cargo.toml b/savefile-derive/Cargo.toml index d88e828..9ccc414 100644 --- a/savefile-derive/Cargo.toml +++ b/savefile-derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "savefile-derive" -version = "0.17.4" +version = "0.17.5" authors = ["Anders Musikka "] repository = "https://github.com/avl/savefile" rust-version = "1.74" diff --git a/savefile-test/Cargo.toml b/savefile-test/Cargo.toml index 8c62e7f..d124842 100644 --- a/savefile-test/Cargo.toml +++ b/savefile-test/Cargo.toml @@ -12,7 +12,7 @@ nightly=["savefile/nightly"] [dependencies] savefile = { path = "../savefile", features = ["size_sanity_checks", "encryption", "compression","bit-set","bit-vec","rustc-hash","serde_derive", "quickcheck"]} -savefile-derive = { path = "../savefile-derive", version = "=0.17.4" } +savefile-derive = { path = "../savefile-derive", version = "=0.17.5" } savefile-abi = { path = "../savefile-abi" } bit-vec = "0.6" arrayvec="0.7" diff --git a/savefile/CHANGELOG.md b/savefile/CHANGELOG.md index dd4d9ce..be22028 100644 --- a/savefile/CHANGELOG.md +++ b/savefile/CHANGELOG.md @@ -6,6 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.17.5](https://github.com/avl/savefile/compare/savefile-v0.17.4...savefile-v0.17.5) - 2024-07-02 + +### Added +- Support for Duration and SystemTime + ## [0.17.4](https://github.com/avl/savefile/compare/savefile-v0.17.3...savefile-v0.17.4) - 2024-05-12 ### Added diff --git a/savefile/Cargo.toml b/savefile/Cargo.toml index 33b35c9..098a646 100644 --- a/savefile/Cargo.toml +++ b/savefile/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "savefile" -version = "0.17.4" +version = "0.17.5" authors = ["Anders Musikka "] documentation = "https://docs.rs/savefile/" homepage = "https://github.com/avl/savefile/" @@ -59,13 +59,13 @@ bit-set = {version = "0.5", optional = true} rustc-hash = {version = "1.1", optional = true} memoffset = "0.9" byteorder = "1.4" -savefile-derive = {path="../savefile-derive", version = "=0.17.4", optional = true } +savefile-derive = {path="../savefile-derive", version = "=0.17.5", optional = true } serde_derive = {version= "1.0", optional = true} serde = {version= "1.0", optional = true} quickcheck = {version= "1.0", optional = true} [dev-dependencies] -savefile-derive = { path="../savefile-derive", version = "=0.17.4" } +savefile-derive = { path="../savefile-derive", version = "=0.17.5" } [build-dependencies] rustc_version="0.2" From a7d31cd65912d3d3b137cf36707f9016252210e6 Mon Sep 17 00:00:00 2001 From: Anders Musikka Date: Tue, 2 Jul 2024 22:17:43 +0200 Subject: [PATCH 3/3] Update Changelog --- README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/README.md b/README.md index 74231ce..b54ed84 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,22 @@ See the docs for more information, including schema-versioning: https://docs.rs/ # Changelog +## 0.17.5 + +Support for std::time::Duration and std::time::SystemTime . + +## 0.17.4 + +Improvements to error messages. + +## 0.17.3 + +Improved error messages for certain compilation failures. + +## 0.17.2 + +Fix failing tests on new rustc-version. + ## 0.17.1 Just minor improvements to documentation.