Исправление сериализации Epoch #13

Merged
DarkCat09 merged 2 commits from fix/hifitime-serde into master 2024-06-01 21:25:50 +03:00
3 changed files with 763 additions and 647 deletions
Showing only changes of commit 9edfcb3af7 - Show all commits

1294
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,8 @@
use crate::ingest_protocol::{
parser::{parse_mac_address, parse_packet},
SensorValue,
};
use hifitime::Epoch; use hifitime::Epoch;
use crate::ingest_protocol::parser::{parse_mac_address, parse_packet};
#[test] #[test]
fn test_asd() { fn test_asd() {
@ -16,13 +19,17 @@ fn test_asd() {
"# "#
.trim(); .trim();
let packet = parse_packet(asd).unwrap().1; let packet = parse_packet(asd).unwrap().1;
assert!(serde_json::to_string_pretty(&packet).unwrap() assert!(serde_json::to_string_pretty(&packet)
.unwrap()
.contains(r#""time": 1000000.0"#)); .contains(r#""time": 1000000.0"#));
} }
#[test] #[test]
fn test_mac() { fn test_mac() {
assert_eq!(parse_mac_address("12-34-AA-12-55-AA").unwrap(), ("", [18, 52, 170, 18, 85, 170]) ); assert_eq!(
parse_mac_address("12-34-AA-12-55-AA").unwrap(),
("", [18, 52, 170, 18, 85, 170])
);
dbg!(Epoch::now().unwrap().to_unix_seconds()); dbg!(Epoch::now().unwrap().to_unix_seconds());
@ -40,3 +47,42 @@ fn test_packet() {
println!("{:#?}", parse_packet(inp)); println!("{:#?}", parse_packet(inp));
} }
#[test]
fn test_hex_parsing() {
let inp = r#"
{"mac": "T1", "value": "123", "time": "665B514B"}
"#
.trim();
let sensor_value: SensorValue = serde_json::from_str(inp).unwrap();
assert_eq!(
sensor_value.time.unwrap().0.to_unix_seconds(),
1717260619.0,
"hex text"
);
let inp = r#"
{"mac": "T1", "value": "123", "time": 1717260619}
"#
.trim();
let sensor_value: SensorValue = serde_json::from_str(inp).unwrap();
assert_eq!(
sensor_value.time.unwrap().0.to_unix_seconds(),
1717260619.0,
"integer test"
);
let inp = r#"
{"mac": "T1", "value": "123", "time": 1717260619.0}
"#
.trim();
let sensor_value: SensorValue = serde_json::from_str(inp).unwrap();
assert_eq!(
sensor_value.time.unwrap().0.to_unix_seconds(),
1717260619.0,
"float test"
);
}

View file

@ -1,7 +1,7 @@
use std::fmt;
use std::fmt::{Formatter, Write};
use hifitime::Epoch; use hifitime::Epoch;
use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
use std::fmt;
use std::fmt::{Formatter, Write};
#[derive(PartialOrd, PartialEq, Ord, Eq, Clone, Copy, Debug, Default)] #[derive(PartialOrd, PartialEq, Ord, Eq, Clone, Copy, Debug, Default)]
#[repr(transparent)] #[repr(transparent)]
@ -16,8 +16,8 @@ impl From<Epoch> for EpochUTC {
impl Serialize for EpochUTC { impl Serialize for EpochUTC {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where where
S: Serializer, S: Serializer,
{ {
serializer.serialize_f64(self.0.to_unix_seconds()) serializer.serialize_f64(self.0.to_unix_seconds())
} }
@ -25,8 +25,8 @@ impl Serialize for EpochUTC {
impl<'de> Deserialize<'de> for EpochUTC { impl<'de> Deserialize<'de> for EpochUTC {
fn deserialize<D>(deserializer: D) -> Result<EpochUTC, D::Error> fn deserialize<D>(deserializer: D) -> Result<EpochUTC, D::Error>
where where
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
struct EpochVisitor; struct EpochVisitor;
@ -34,31 +34,43 @@ impl<'de> Deserialize<'de> for EpochUTC {
type Value = EpochUTC; type Value = EpochUTC;
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
formatter.write_str("a string or a float") formatter.write_str(
"a (string, representing a timestamp in decimal or hexadecimal form) or a decimal",
)
} }
fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E> where E: de::Error { fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
return Ok(Epoch::from_unix_seconds(v as f64).into()) where
} E: de::Error,
fn visit_f32<E>(self, v: f32) -> Result<Self::Value, E> where E: de::Error {
return Ok(Epoch::from_unix_seconds(v as f64).into())
}
fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E> where E: de::Error {
return Ok(Epoch::from_unix_seconds(v).into())
}
fn visit_str<E>(self, value: &str) -> Result<EpochUTC, E>
where
E: de::Error,
{ {
return Ok(Epoch::from_unix_seconds( return Ok(Epoch::from_unix_seconds(v as f64).into());
value.parse().map_err(de::Error::custom)? }
).into())
fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
where
E: de::Error,
{
return Ok(Epoch::from_unix_seconds(v).into());
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
if value.len() == 8 {
let bytes = hex::decode(value).map_err(de::Error::custom)?;
return Ok(Epoch::from_unix_seconds(u32::from_be_bytes(
bytes.as_slice().try_into().unwrap(),
) as f64)
.into());
}
return Ok(
Epoch::from_unix_seconds(value.parse().map_err(de::Error::custom)?).into(),
);
} }
} }
deserializer.deserialize_any(EpochVisitor) deserializer.deserialize_any(EpochVisitor)
} }
} }