Skip to content

Commit

Permalink
Add owned String branch to deserialize_option_number_from_string (#43)
Browse files Browse the repository at this point in the history
* Add owned String branch to `deserialize_option_number_from_string` family of functions

* Replace deprecated calls to chrono
  • Loading branch information
andy128k authored Apr 21, 2024
1 parent 6d0e9f0 commit 02470dd
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 18 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: CI
on: [push, pull_request]

env:
minrust: 1.57.0
minrust: 1.61.0

jobs:
test:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
- cron: '0 2 * * *'

env:
minrust: 1.57.0
minrust: 1.61.0

jobs:
test:
Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
[package]
name = "serde-aux"
version = "4.5.0"
version = "4.5.1"
authors = ["Victor Polevoy <maintainer@vpolevoy.com>"]
description = "A serde crate's auxiliary library"
readme = "README.md"
license = "MIT"
keywords = ["serde", "serialization", "deserialization"]
edition = "2021"
rust-version = "1.57"
rust-version = "1.61"
repository = "https://github.com/iddm/serde-aux"
documentation = "https://docs.rs/serde-aux"

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ The minimal rust version the library supports:
- Up to version `3.0.0` (excluding) - rustc `1.36`.
- Since `3.0.0` - rustc `1.56`.
- Since `4.3.0` - rustc `1.57`.
- Since `4.5.1` - rustc `1.61`.

## License
This project is [licensed under the MIT license](https://github.com/iddm/serde-aux/blob/master/LICENSE).
44 changes: 30 additions & 14 deletions src/field_attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,15 +205,9 @@ where
{
use chrono::prelude::*;

let number = deserialize_number_from_string::<i64, D>(deserializer)?;
let seconds = number / 1000;
let millis = (number % 1000) as u32;
let nanos = millis * 1_000_000;

Ok(Utc.from_utc_datetime(
&NaiveDateTime::from_timestamp_opt(seconds, nanos)
.ok_or_else(|| D::Error::custom("Couldn't parse the timestamp"))?,
))
let millis = deserialize_number_from_string::<i64, D>(deserializer)?;
DateTime::<Utc>::from_timestamp_millis(millis)
.ok_or_else(|| D::Error::custom("Couldn't parse the timestamp"))
}

/// Deserializes a `chrono::DateTime<Utc>` from a seconds time stamp.
Expand Down Expand Up @@ -247,11 +241,8 @@ where
use chrono::prelude::*;

let seconds = deserialize_number_from_string::<i64, D>(deserializer)?;

Ok(Utc.from_utc_datetime(
&NaiveDateTime::from_timestamp_opt(seconds, 0)
.ok_or_else(|| D::Error::custom("Couldn't parse the timestamp"))?,
))
DateTime::<Utc>::from_timestamp(seconds, 0)
.ok_or_else(|| D::Error::custom("Couldn't parse the timestamp"))
}

/// Deserializes a number from string or a number.
Expand Down Expand Up @@ -401,6 +392,7 @@ where
#[serde(untagged)]
enum NumericOrNull<'a, T> {
Str(&'a str),
String(String),
FromStr(T),
Null,
}
Expand All @@ -410,6 +402,10 @@ where
"" => Ok(None),
_ => T::from_str(s).map(Some).map_err(serde::de::Error::custom),
},
NumericOrNull::String(s) => match s.as_str() {
"" => Ok(None),
_ => T::from_str(&s).map(Some).map_err(serde::de::Error::custom),
},
NumericOrNull::FromStr(i) => Ok(Some(i)),
NumericOrNull::Null => Ok(None),
}
Expand All @@ -432,12 +428,19 @@ macro_rules! wrap_option_number_from_string_fn {
#[serde(untagged)]
enum NumericOrNull<'a, T> {
Str(&'a str),
String(String),
FromStr(T),
Null,
}

match NumericOrNull::<T>::deserialize(deserializer)? {
NumericOrNull::Str(s) => match s {
"" => Ok(None.into()),
_ => T::from_str(s)
.map(|i| Some(i).into())
.map_err(serde::de::Error::custom),
},
NumericOrNull::String(s) => match s.as_str() {
"" => Ok(None.into()),
_ => T::from_str(&s)
.map(|i| Some(i).into())
Expand Down Expand Up @@ -1414,4 +1417,17 @@ mod tests {
serde_json_err!({});
serde_json_err!([]);
}

#[derive(Debug, serde::Deserialize)]
struct TestStruct {
#[serde(default, deserialize_with = "deserialize_option_number_from_string")]
value: Option<f32>,
}

#[test]
fn deserialize_string_variant_valid_number() {
let json = r#"{"value": "4\u0032.5"}"#;
let result: TestStruct = serde_json::from_str(json).unwrap();
assert_eq!(result.value, Some(42.5));
}
}

0 comments on commit 02470dd

Please sign in to comment.