Skip to content

Commit 1348657

Browse files
authored
Merge pull request #44 from blockscout/ll/datetime-serialize
fix: correct datetime serialize
2 parents 54129d0 + aeedb36 commit 1348657

5 files changed

Lines changed: 76 additions & 14 deletions

File tree

Cargo.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,17 @@ members = [
99
]
1010

1111
[workspace.package]
12-
version = "0.2.2"
12+
version = "0.2.3"
1313
edition = "2021"
1414
license = "MIT"
1515
repository = "https://github.com/blockscout/actix-prost"
1616
exclude = ["tests"]
1717

1818
[workspace.dependencies]
19-
actix-prost = { version = "0.2.0", path = "actix-prost" }
20-
actix-prost-build = { version = "0.2.0", path = "actix-prost-build" }
21-
actix-prost-macros = { version = "0.2.0", path = "actix-prost-macros" }
22-
convert-trait = { version = "0.2.0", path = "actix-prost-convert-trait", package = "actix-prost-convert-trait" }
19+
actix-prost = { path = "actix-prost" }
20+
actix-prost-build = { path = "actix-prost-build" }
21+
actix-prost-macros = { path = "actix-prost-macros" }
22+
convert-trait = { path = "actix-prost-convert-trait", package = "actix-prost-convert-trait" }
2323

2424
actix-http = { version = "3" }
2525
actix-web = { version = "4" }

actix-prost-convert-trait/src/datetime.rs

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
1-
use crate::{impl_try_convert_to_string, TryConvert};
1+
use crate::TryConvert;
22
use chrono::{DateTime, FixedOffset, NaiveDateTime, Utc};
33

4+
macro_rules! impl_try_convert_datetime_to_string {
5+
($type:ty) => {
6+
impl TryConvert<$type> for String {
7+
fn try_convert(value: $type) -> Result<Self, String> {
8+
Ok(value.to_rfc3339())
9+
}
10+
}
11+
};
12+
}
13+
414
// DateTime<Utc> conversions
515
impl TryConvert<String> for DateTime<Utc> {
616
fn try_convert(value: String) -> Result<Self, String> {
@@ -20,7 +30,7 @@ impl TryConvert<String> for DateTime<Utc> {
2030
}
2131
}
2232

23-
impl_try_convert_to_string!(DateTime<Utc>);
33+
impl_try_convert_datetime_to_string!(DateTime<Utc>);
2434

2535
// DateTime<FixedOffset> conversions
2636
impl TryConvert<String> for DateTime<FixedOffset> {
@@ -46,7 +56,7 @@ impl TryConvert<String> for DateTime<FixedOffset> {
4656
}
4757
}
4858

49-
impl_try_convert_to_string!(DateTime<FixedOffset>);
59+
impl_try_convert_datetime_to_string!(DateTime<FixedOffset>);
5060

5161
// NaiveDateTime conversions
5262
impl TryConvert<String> for NaiveDateTime {
@@ -68,15 +78,23 @@ impl TryConvert<String> for NaiveDateTime {
6878
}
6979
}
7080

71-
impl_try_convert_to_string!(NaiveDateTime);
81+
82+
// implemented via Debug according to the implementation of the serde module
83+
// https://github.com/chronotope/chrono/blob/e632ffd3b89d3cfaa96776f2368ee4c21a972766/src/naive/datetime/serde.rs#L6-L26
84+
// https://docs.rs/chrono/latest/chrono/naive/struct.NaiveDateTime.html#impl-Debug-for-NaiveDateTime
85+
impl TryConvert<NaiveDateTime> for String {
86+
fn try_convert(value: NaiveDateTime) -> Result<Self, String> {
87+
Ok(format!("{:?}", value))
88+
}
89+
}
7290

7391
#[cfg(test)]
7492
mod tests {
7593
use super::*;
7694
use pretty_assertions::assert_eq;
7795

7896
#[test]
79-
fn test_conversion_datetime() {
97+
fn test_conversion_datetime_from_string() {
8098
let datetime = DateTime::<Utc>::try_convert("1645491600".to_string()).unwrap();
8199
assert_eq!(
82100
datetime,
@@ -151,7 +169,10 @@ mod tests {
151169
datetime,
152170
"2021-01-01T00:00:00Z".parse::<DateTime<Utc>>().unwrap()
153171
);
172+
}
154173

174+
#[test]
175+
fn test_conversion_datetime_errors() {
155176
// Error cases
156177
let error = DateTime::<Utc>::try_convert("2021-01-01T00:00:00".to_string())
157178
.expect_err("Invalid datetime");
@@ -177,4 +198,23 @@ mod tests {
177198
"failed to parse '' as NaiveDateTime: premature end of input"
178199
);
179200
}
201+
202+
#[test]
203+
fn test_conversion_datetime_to_string() {
204+
let datetime = "2021-01-01T00:00:00.123456789+00:00"
205+
.parse::<DateTime<Utc>>()
206+
.unwrap();
207+
let string = String::try_convert(datetime).unwrap();
208+
assert_eq!(string, "2021-01-01T00:00:00.123456789+00:00");
209+
210+
let datetime = "2021-01-01T00:00:00.123456789+00:00"
211+
.parse::<DateTime<FixedOffset>>()
212+
.unwrap();
213+
let string = String::try_convert(datetime).unwrap();
214+
assert_eq!(string, "2021-01-01T00:00:00.123456789+00:00");
215+
216+
let datetime = "2021-01-01T00:00:00.123456789".parse::<NaiveDateTime>().unwrap();
217+
let string = String::try_convert(datetime).unwrap();
218+
assert_eq!(string, "2021-01-01T00:00:00.123456789");
219+
}
180220
}

tests/proto/conversions.proto

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,10 @@ message ConversionsResponse {
9191

9292
// Response fields with conversions
9393
string response_utc_datetime = 5 [ (convert_options.convert) = { type : "chrono::DateTime<chrono::Utc>" } ];
94-
string response_uuid = 6 [ (convert_options.convert) = { type : "uuid::Uuid" } ];
95-
string response_decimal = 7 [ (convert_options.convert) = { type : "rust_decimal::Decimal" } ];
94+
string response_fixed_offset_datetime = 7 [ (convert_options.convert) = { type : "chrono::DateTime<chrono::FixedOffset>" } ];
95+
string response_naive_datetime = 8 [ (convert_options.convert) = { type : "chrono::NaiveDateTime" } ];
96+
string response_uuid = 9 [ (convert_options.convert) = { type : "uuid::Uuid" } ];
97+
string response_decimal = 10 [ (convert_options.convert) = { type : "rust_decimal::Decimal" } ];
9698
}
9799

98100

tests/src/conversions.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ impl ConversionsRpc for ConversionsServer {
3535
map_field: internal_request.map_field,
3636
config: None,
3737
response_utc_datetime: internal_request.utc_datetime,
38+
response_fixed_offset_datetime: internal_request.fixed_offset_datetime,
39+
response_naive_datetime: internal_request.naive_datetime,
3840
response_uuid: internal_request.uuid_field,
3941
response_decimal: internal_request.decimal_field,
4042
};
@@ -189,6 +191,12 @@ async fn conversions() {
189191
assert_eq!(status, StatusCode::OK, "error: {res}");
190192
let res: ConversionsResponse = serde_json::from_str(&res).unwrap();
191193
assert_eq!(res.nested.unwrap().address, test_address);
194+
assert_eq!(res.response_utc_datetime, "2023-01-01T00:00:00+00:00");
195+
assert_eq!(
196+
res.response_fixed_offset_datetime,
197+
"2023-01-01T00:00:00+01:00"
198+
);
199+
assert_eq!(res.response_naive_datetime, "2023-01-01T00:00:00");
192200
}
193201

194202
#[test]

tests/src/proto/conversions.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,13 @@ pub struct ConversionsResponse {
113113
/// Response fields with conversions
114114
#[prost(string, tag = "5")]
115115
pub response_utc_datetime: ::prost::alloc::string::String,
116-
#[prost(string, tag = "6")]
117-
pub response_uuid: ::prost::alloc::string::String,
118116
#[prost(string, tag = "7")]
117+
pub response_fixed_offset_datetime: ::prost::alloc::string::String,
118+
#[prost(string, tag = "8")]
119+
pub response_naive_datetime: ::prost::alloc::string::String,
120+
#[prost(string, tag = "9")]
121+
pub response_uuid: ::prost::alloc::string::String,
122+
#[prost(string, tag = "10")]
119123
pub response_decimal: ::prost::alloc::string::String,
120124
}
121125
#[actix_prost_macros::serde]
@@ -401,6 +405,8 @@ pub struct ConversionsResponseInternal {
401405
>,
402406
pub config: ::core::option::Option<ConfigInternal>,
403407
pub response_utc_datetime: chrono::DateTime<chrono::Utc>,
408+
pub response_fixed_offset_datetime: chrono::DateTime<chrono::FixedOffset>,
409+
pub response_naive_datetime: chrono::NaiveDateTime,
404410
pub response_uuid: uuid::Uuid,
405411
pub response_decimal: rust_decimal::Decimal,
406412
}
@@ -414,6 +420,12 @@ impl convert_trait::TryConvert<ConversionsResponseInternal> for ConversionsRespo
414420
response_utc_datetime: convert_trait::TryConvert::try_convert(
415421
from.response_utc_datetime,
416422
)?,
423+
response_fixed_offset_datetime: convert_trait::TryConvert::try_convert(
424+
from.response_fixed_offset_datetime,
425+
)?,
426+
response_naive_datetime: convert_trait::TryConvert::try_convert(
427+
from.response_naive_datetime,
428+
)?,
417429
response_uuid: convert_trait::TryConvert::try_convert(from.response_uuid)?,
418430
response_decimal: convert_trait::TryConvert::try_convert(
419431
from.response_decimal,

0 commit comments

Comments
 (0)