Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat:Support for Duration and SystemTime #60

Merged
merged 3 commits into from
Jul 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
5 changes: 5 additions & 0 deletions savefile-abi/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions savefile-abi/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "savefile-abi"
version = "0.17.4"
version = "0.17.5"
edition = "2021"
authors = ["Anders Musikka <[email protected]>"]
documentation = "https://docs.rs/savefile-abi/"
Expand All @@ -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"

Expand Down
2 changes: 1 addition & 1 deletion savefile-derive/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "savefile-derive"
version = "0.17.4"
version = "0.17.5"
authors = ["Anders Musikka <[email protected]>"]
repository = "https://github.com/avl/savefile"
rust-version = "1.74"
Expand Down
2 changes: 1 addition & 1 deletion savefile-test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
32 changes: 31 additions & 1 deletion savefile-test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
@@ -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: []
5 changes: 5 additions & 0 deletions savefile/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions savefile/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "savefile"
version = "0.17.4"
version = "0.17.5"
authors = ["Anders Musikka <[email protected]>"]
documentation = "https://docs.rs/savefile/"
homepage = "https://github.com/avl/savefile/"
Expand Down Expand Up @@ -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"
Expand Down
93 changes: 92 additions & 1 deletion savefile/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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<impl Write>) -> Result<(), SavefileError> {
serializer.write_u128(self.as_nanos())
}
}
impl Deserialize for Duration {
fn deserialize(deserializer: &mut Deserializer<impl Read>) -> Result<Self, SavefileError> {
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<impl Write>) -> 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<impl Read>) -> Result<Self, SavefileError> {
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,
Expand Down
Loading