diff --git a/Cargo.toml b/Cargo.toml index b338acb..3006183 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,22 +13,23 @@ exclude = [ # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -serde = { version = "1.0.159", features = ["derive"] } +serde = { version = "1.0.195", features = ["derive"] } serde_repr = "0.1.12" regex = "1.7.3" time = { version = "0.3.20", features = ["serde-human-readable", "macros"]} lazy_static = "1.4.0" fast-float = { version = "0.2", optional = true } +serde_json = "1.0.40" [dev-dependencies] -serde_json = "1.0.40" bincode = "1.3.3" criterion = "0.3" mimalloc = "0.1.25" +rmp-serde = "1.1.2" [features] fastfloat = ["fast-float"] [[bench]] name = "benchmark" -harness = false \ No newline at end of file +harness = false diff --git a/dumped_data/bus_arrival.json b/dumped_data/bus_arrival.json index 58d4af0..4ecaf2d 100644 --- a/dumped_data/bus_arrival.json +++ b/dumped_data/bus_arrival.json @@ -41,7 +41,7 @@ }, { "ServiceNo": "154", - "Operator": "SBST", + "Operator": "GAS", "NextBus": { "OriginCode": "82009", "DestinationCode": "22009", diff --git a/src/lib.rs b/src/lib.rs index 1b4606e..3bff2de 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -92,7 +92,17 @@ mod tests { use std::fmt::Debug; use time::{macros::datetime, OffsetDateTime}; - fn generate_test<'de, I, S, F>(input_fn: F) -> (String, Vec, S, S) + #[allow(unused)] + struct TestItems { + serde_json: String, + serde_bincode: Vec, + serde_messagepack: Vec, + serde_struct: T, + serde_bincode_struct: T, + serde_messagepack_struct: T, + } + + fn generate_test<'de, I, S, F>(input_fn: F) -> TestItems where F: FnOnce() -> &'de str, I: Deserialize<'de> + Into, @@ -107,13 +117,22 @@ mod tests { let ser_json_new = serde_json::to_string(&de_2).unwrap(); let ser_bincode = bincode::serialize(&de).unwrap(); + let ser_messagepack = rmp_serde::to_vec(&de).unwrap(); println!("{}", ser_json_new); // println!("{:X?}", ser_bincode); let de_bincode = bincode::deserialize::(&ser_bincode[..]).unwrap(); - - (ser_json_new, ser_bincode, de, de_bincode) + let de_messagepack = rmp_serde::from_slice::(&ser_messagepack[..]).unwrap(); + + TestItems { + serde_json: ser_json_new, + serde_bincode: ser_bincode, + serde_messagepack: ser_messagepack, + serde_struct: de, + serde_bincode_struct: de_bincode, + serde_messagepack_struct: de_messagepack, + } } macro_rules! gen_test { @@ -198,6 +217,48 @@ mod tests { assert_eq!(de, sample_data); } + #[test] + fn test_messagepack_nextbus() { + let sample_data = NextBus { + origin_code: 77009, + dest_code: 77009, + est_arrival: datetime!(2023-04-06 14:47:57 +8), + lat: 1.314452, + long: 103.910009, + visit_no: 1, + load: BusLoad::SeatsAvailable, + feature: BusFeature::WheelChairAccessible, + bus_type: BusType::SingleDecker, + }; + + let ser = rmp_serde::to_vec(&sample_data).unwrap(); + let de = rmp_serde::from_slice::(&ser[..]).unwrap(); + assert_eq!(de, sample_data); + } + + #[test] + fn test_message_datetime() { + use time::serde::iso8601; + + #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] + pub struct Dt { + #[serde( + rename = "EstimatedArrival", + deserialize_with = "iso8601::deserialize", + serialize_with = "iso8601::serialize" + )] + inner: OffsetDateTime, + } + + let dt = Dt { + inner: datetime!(2023-04-06 14:47:57 +8), + }; + + let ser = rmp_serde::to_vec(&dt).unwrap(); + let de = rmp_serde::from_slice::
(&ser[..]).unwrap(); + assert_eq!(de, dt); + } + #[test] fn test_bc_datetime() { use time::serde::iso8601; @@ -243,24 +304,31 @@ mod tests { #[test] fn bus_arrival() { - let (_, _, bus, bus_bincode) = gen_test!( + let TestItems { + serde_json: _, + serde_bincode: _, + serde_messagepack: _, + serde_struct: bus, + serde_bincode_struct: bus_bincode, + serde_messagepack_struct: _, + } = gen_test!( RawBusArrivalResp, BusArrivalResp, "../dumped_data/bus_arrival.json" ); - assert_eq!(bus.bus_stop_code, 83139); - assert_eq!(bus.services.len(), 3); - assert_eq!(bus.services[0].operator, Operator::Gas); - assert_eq!(bus.services[1].operator, Operator::Sbst); - assert_eq!(bus.services[2].operator, Operator::Sbst); + assert_eq!(bus.bus_stop_code, 82009); + assert_eq!(bus.services.len(), 11); + assert_eq!(bus.services[0].operator, Operator::Sbst); + assert_eq!(bus.services[1].operator, Operator::Gas); + assert_eq!(bus.services[5].operator, Operator::Smrt); let sample_data = NextBus { - origin_code: 77009, - dest_code: 77009, - est_arrival: datetime!(2023-04-06 14:47:57 +8), - lat: 1.314452, - long: 103.910009, + origin_code: 82009, + dest_code: 82009, + est_arrival: datetime!(2024-01-17 18:00:00 +8), + lat: 0.0, + long: 0.0, visit_no: 1, load: BusLoad::SeatsAvailable, feature: BusFeature::WheelChairAccessible, diff --git a/src/utils.rs b/src/utils.rs index f6ddfdb..afbecfe 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -218,6 +218,7 @@ pub mod de { use serde::de::{self, Visitor}; use serde::{Deserialize, Deserializer}; + use serde_json::Value; use std::fmt::Formatter; /// Error for wrapped data @@ -234,15 +235,13 @@ pub mod de { } } - /// # Errors - /// Fails when data cant be deserialized to String. Returns None if data is invalid pub fn treat_error_as_none<'de, T, D>(deserializer: D) -> Result, D::Error> where T: Deserialize<'de>, D: Deserializer<'de>, { - // let value: Value = Deserialize::deserialize(deserializer)?; - Ok(T::deserialize(deserializer).ok()) + let value: Value = Deserialize::deserialize(deserializer)?; + Ok(T::deserialize(value).ok()) } /// Simple conversion of `Y`,`Yes` and `N`, `No` to boolean