Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
jonasbb committed Dec 25, 2024
1 parent bd08ec0 commit 4dd2fb5
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 16 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions serde_with/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ hashbrown_0_15 = { package = "hashbrown", version = "0.15.0", optional = true, d
hex = { version = "0.4.3", optional = true, default-features = false }
indexmap_1 = { package = "indexmap", version = "1.8", optional = true, default-features = false, features = ["serde-1"] }
indexmap_2 = { package = "indexmap", version = "2.0", optional = true, default-features = false, features = ["serde"] }
num-traits = { version = "0.2.19", features = ["std"] }
schemars_0_8 = { package = "schemars", version = "0.8.16", optional = true, default-features = false }
serde = { version = "1.0.152", default-features = false }
serde_derive = "1.0.152"
Expand Down
10 changes: 7 additions & 3 deletions serde_with/src/chrono_0_4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ fn unix_epoch_naive() -> NaiveDateTime {
#[cfg(feature = "std")]
pub mod datetime_utc_ts_seconds_from_any {
use super::*;
use num_traits::ToPrimitive as _;

/// Deserialize a Unix timestamp with optional subsecond precision into a `DateTime<Utc>`.
pub fn deserialize<'de, D>(deserializer: D) -> Result<DateTime<Utc>, D::Error>
Expand Down Expand Up @@ -110,9 +111,12 @@ pub mod datetime_utc_ts_seconds_from_any {
where
E: DeError,
{
let seconds = value.trunc() as i64;
let nsecs = (value.fract() * 1_000_000_000_f64).abs() as u32;
DateTime::from_timestamp(seconds, nsecs).ok_or_else(|| {
fn f64_to_value(value: f64) -> Option<DateTime<Utc>> {
let seconds = value.trunc().to_i64()?;
let nsecs = (value.fract() * 1_000_000_000_f64).abs().to_u32()?;
DateTime::from_timestamp(seconds, nsecs)
}
f64_to_value(value).ok_or_else(|| {
DeError::custom(format_args!(
"a timestamp which can be represented in a DateTime but received '{value}'"
))
Expand Down
23 changes: 11 additions & 12 deletions serde_with/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub(crate) mod duration;

use crate::prelude::*;
use num_traits::ToPrimitive as _;

Check failure on line 4 in serde_with/src/utils.rs

View workflow job for this annotation

GitHub Actions / clippy_check (ubuntu-latest, stable)

unused import: `num_traits::ToPrimitive as _`

Check failure on line 4 in serde_with/src/utils.rs

View workflow job for this annotation

GitHub Actions / clippy_check (ubuntu-latest, nightly)

unused import: `num_traits::ToPrimitive as _`

Check failure on line 4 in serde_with/src/utils.rs

View workflow job for this annotation

GitHub Actions / Build and Test (ubuntu-latest, nightly)

unused import: `num_traits::ToPrimitive as _`

Check failure on line 4 in serde_with/src/utils.rs

View workflow job for this annotation

GitHub Actions / Build and Test (ubuntu-latest, beta)

unused import: `num_traits::ToPrimitive as _`

Check failure on line 4 in serde_with/src/utils.rs

View workflow job for this annotation

GitHub Actions / Build and Test (ubuntu-latest, 1.80)

unused import: `num_traits::ToPrimitive as _`

Check failure on line 4 in serde_with/src/utils.rs

View workflow job for this annotation

GitHub Actions / Build and Test (ubuntu-latest, 1.70)

unused import: `num_traits::ToPrimitive as _`

Check failure on line 4 in serde_with/src/utils.rs

View workflow job for this annotation

GitHub Actions / Build and Test (ubuntu-latest, 1.75)

unused import: `num_traits::ToPrimitive as _`

Check failure on line 4 in serde_with/src/utils.rs

View workflow job for this annotation

GitHub Actions / Build and Test (ubuntu-latest, stable)

unused import: `num_traits::ToPrimitive as _`

Check failure on line 4 in serde_with/src/utils.rs

View workflow job for this annotation

GitHub Actions / clippy_check (windows-latest, nightly)

unused import: `num_traits::ToPrimitive as _`

Check failure on line 4 in serde_with/src/utils.rs

View workflow job for this annotation

GitHub Actions / clippy_check (windows-latest, stable)

unused import: `num_traits::ToPrimitive as _`

/// Re-Implementation of `serde::private::de::size_hint::cautious`
#[cfg(feature = "alloc")]
Expand Down Expand Up @@ -40,7 +41,10 @@ pub(crate) const NANOS_PER_SEC_F64: f64 = 1_000_000_000.0;
// pub(crate) const NANOS_PER_MICRO: u32 = 1_000;
// pub(crate) const MILLIS_PER_SEC: u64 = 1_000;
// pub(crate) const MICROS_PER_SEC: u64 = 1_000_000;
#[expect(clippy::as_conversions)]

Check failure on line 44 in serde_with/src/utils.rs

View workflow job for this annotation

GitHub Actions / Build and Test (ubuntu-latest, 1.80)

the `#[expect]` attribute is an experimental feature

Check failure on line 44 in serde_with/src/utils.rs

View workflow job for this annotation

GitHub Actions / Build and Test (ubuntu-latest, 1.70)

the `#[expect]` attribute is an experimental feature

Check failure on line 44 in serde_with/src/utils.rs

View workflow job for this annotation

GitHub Actions / Build and Test (ubuntu-latest, 1.75)

the `#[expect]` attribute is an experimental feature
pub(crate) const U64_MAX: u128 = u64::MAX as u128;

Check failure on line 45 in serde_with/src/utils.rs

View workflow job for this annotation

GitHub Actions / clippy_check (ubuntu-latest, stable)

constant `U64_MAX` is never used

Check failure on line 45 in serde_with/src/utils.rs

View workflow job for this annotation

GitHub Actions / clippy_check (ubuntu-latest, nightly)

constant `U64_MAX` is never used

Check failure on line 45 in serde_with/src/utils.rs

View workflow job for this annotation

GitHub Actions / Build and Test (ubuntu-latest, nightly)

constant `U64_MAX` is never used

Check failure on line 45 in serde_with/src/utils.rs

View workflow job for this annotation

GitHub Actions / Build and Test (ubuntu-latest, beta)

constant `U64_MAX` is never used

Check failure on line 45 in serde_with/src/utils.rs

View workflow job for this annotation

GitHub Actions / clippy_check (windows-latest, nightly)

constant `U64_MAX` is never used

Check failure on line 45 in serde_with/src/utils.rs

View workflow job for this annotation

GitHub Actions / clippy_check (windows-latest, stable)

constant `U64_MAX` is never used
#[expect(clippy::as_conversions)]

Check failure on line 46 in serde_with/src/utils.rs

View workflow job for this annotation

GitHub Actions / Build and Test (ubuntu-latest, 1.80)

the `#[expect]` attribute is an experimental feature

Check failure on line 46 in serde_with/src/utils.rs

View workflow job for this annotation

GitHub Actions / Build and Test (ubuntu-latest, 1.70)

the `#[expect]` attribute is an experimental feature

Check failure on line 46 in serde_with/src/utils.rs

View workflow job for this annotation

GitHub Actions / Build and Test (ubuntu-latest, 1.75)

the `#[expect]` attribute is an experimental feature
pub(crate) const U64_MAX_FLOAT: f64 = u64::MAX as f64;

pub(crate) struct MapIter<'de, A, K, V> {
pub(crate) access: A,
Expand Down Expand Up @@ -115,27 +119,22 @@ where
}
}

pub(crate) fn duration_signed_from_secs_f64(secs: f64) -> Result<DurationSigned, &'static str> {
const MAX_NANOS_F64: f64 = ((U64_MAX + 1) * NANOS_PER_SEC) as f64;
// TODO why are the seconds converted to nanoseconds first?
// Does it make sense to just truncate the value?
let mut nanos = secs * NANOS_PER_SEC_F64;
if !nanos.is_finite() {
pub(crate) fn duration_signed_from_secs_f64(mut secs: f64) -> Result<DurationSigned, &'static str> {
if !secs.is_finite() {
return Err("got non-finite value when converting float to duration");
}
if nanos >= MAX_NANOS_F64 {
if secs.trunc() > U64_MAX_FLOAT {
return Err("overflow when converting float to duration");
}
let mut sign = Sign::Positive;
if nanos < 0.0 {
nanos = -nanos;
if secs < 0.0 {
secs = -secs;
sign = Sign::Negative;
}
let nanos = nanos as u128;
Ok(DurationSigned::new(
sign,
(nanos / NANOS_PER_SEC) as u64,
(nanos % NANOS_PER_SEC) as u32,
secs.trunc() as u64,
(secs.fract() * NANOS_PER_SEC_F64) as u32,
))
}

Expand Down
3 changes: 2 additions & 1 deletion serde_with/src/utils/duration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::{
formats::{Flexible, Format, Strict, Strictness},
prelude::*,
};
use num_traits::ToPrimitive as _;

Check failure on line 12 in serde_with/src/utils/duration.rs

View workflow job for this annotation

GitHub Actions / clippy_check (ubuntu-latest, stable)

unused import: `num_traits::ToPrimitive as _`

Check failure on line 12 in serde_with/src/utils/duration.rs

View workflow job for this annotation

GitHub Actions / clippy_check (ubuntu-latest, nightly)

unused import: `num_traits::ToPrimitive as _`

Check failure on line 12 in serde_with/src/utils/duration.rs

View workflow job for this annotation

GitHub Actions / Build and Test (ubuntu-latest, nightly)

unused import: `num_traits::ToPrimitive as _`

Check failure on line 12 in serde_with/src/utils/duration.rs

View workflow job for this annotation

GitHub Actions / Build and Test (ubuntu-latest, beta)

unused import: `num_traits::ToPrimitive as _`

Check failure on line 12 in serde_with/src/utils/duration.rs

View workflow job for this annotation

GitHub Actions / Build and Test (ubuntu-latest, 1.80)

unused import: `num_traits::ToPrimitive as _`

Check failure on line 12 in serde_with/src/utils/duration.rs

View workflow job for this annotation

GitHub Actions / Build and Test (ubuntu-latest, 1.70)

unused import: `num_traits::ToPrimitive as _`

Check failure on line 12 in serde_with/src/utils/duration.rs

View workflow job for this annotation

GitHub Actions / Build and Test (ubuntu-latest, 1.75)

unused import: `num_traits::ToPrimitive as _`

Check failure on line 12 in serde_with/src/utils/duration.rs

View workflow job for this annotation

GitHub Actions / Build and Test (ubuntu-latest, stable)

unused import: `num_traits::ToPrimitive as _`

Check failure on line 12 in serde_with/src/utils/duration.rs

View workflow job for this annotation

GitHub Actions / clippy_check (windows-latest, nightly)

unused import: `num_traits::ToPrimitive as _`

Check failure on line 12 in serde_with/src/utils/duration.rs

View workflow job for this annotation

GitHub Actions / clippy_check (windows-latest, stable)

unused import: `num_traits::ToPrimitive as _`

#[derive(Copy, Clone, PartialEq, Eq)]
#[cfg_attr(test, derive(Debug))]
Expand Down Expand Up @@ -212,7 +213,7 @@ where
where
S: Serializer,
{
let mut secs = source
let mut secs: i64 = source
.sign
.apply_i64(i64::try_from(source.duration.as_secs()).map_err(|_| {
SerError::custom("The Duration of Timestamp is outside the supported range.")
Expand Down

0 comments on commit 4dd2fb5

Please sign in to comment.