From 752f52b39169d8e5d4c3e42ec3c5ed3c67a9bcbd Mon Sep 17 00:00:00 2001 From: Lethe Lee <87625844+Lethe10137@users.noreply.github.com> Date: Sun, 8 Dec 2024 15:43:41 +0000 Subject: [PATCH] fix(model): resolve deserialization issue with figment (#15) * make it compatible with `figment` --- Cargo.toml | 1 + src/lib.rs | 72 +++++++++++++++++++++++++++++++++++++++++++++++++ src/model/bw.rs | 19 ++++++------- 3 files changed, 83 insertions(+), 9 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 56884e4..95ffff9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,6 +28,7 @@ statrs = { version = "0.17.1", optional = true} [dev-dependencies] serde_json = "1.0" +figment = {version = "0.10.19", features = ["json"]} [features] diff --git a/src/lib.rs b/src/lib.rs index 9445340..6484e1a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -464,4 +464,76 @@ mod test { Some((Bandwidth::from_bps(12132938), Duration::from_millis(100))) ); } + + #[test] + #[cfg(feature = "human")] + fn test_compatibility_with_figment() { + use figment::{ + providers::{Format, Json}, + Figment, + }; + + let config = r##" + { +"RepeatedBwPatternConfig": { + "pattern": [ + {"TraceBwConfig": [["25ms",["10Mbps", "20Mbps"]],["2ms",["11Mbps", "23Mbps"]]]}, + {"SawtoothBwConfig": { + "bottom" : "10Mbps", + "top" : "20Mbps", + "step" : "1ms", + "interval" : "10ms", + "duty_ratio" : 0.5 + } + } + ], + "count": 0 +} +} +"##; + + let trace: Box = Figment::new() + .merge(Json::string(config)) + .extract() + .unwrap(); + + let mut model = trace.into_model(); + + assert_eq!( + model.next_bw(), + Some((Bandwidth::from_mbps(10), Duration::from_millis(25))) + ); + assert_eq!( + model.next_bw(), + Some((Bandwidth::from_mbps(20), Duration::from_millis(25))) + ); + assert_eq!( + model.next_bw(), + Some((Bandwidth::from_mbps(11), Duration::from_millis(2))) + ); + assert_eq!( + model.next_bw(), + Some((Bandwidth::from_mbps(23), Duration::from_millis(2))) + ); + assert_eq!( + model.next_bw(), + Some((Bandwidth::from_mbps(10), Duration::from_millis(1))) + ); + assert_eq!( + model.next_bw(), + Some((Bandwidth::from_mbps(12), Duration::from_millis(1))) + ); + assert_eq!( + model.next_bw(), + Some((Bandwidth::from_mbps(14), Duration::from_millis(1))) + ); + assert_eq!( + model.next_bw(), + Some((Bandwidth::from_mbps(16), Duration::from_millis(1))) + ); + assert_eq!( + model.next_bw(), + Some((Bandwidth::from_mbps(18), Duration::from_millis(1))) + ); + } } diff --git a/src/model/bw.rs b/src/model/bw.rs index 0627341..70f2253 100644 --- a/src/model/bw.rs +++ b/src/model/bw.rs @@ -661,20 +661,21 @@ impl<'de> Deserialize<'de> for TraceBwConfig { let mut pattern = Vec::new(); while let Some((duration_str, bandwidths_str)) = - seq.next_element::<(&str, Vec<&str>)>()? + seq.next_element::<(String, Vec)>()? { - let duration = humantime_serde::re::humantime::parse_duration(duration_str) - .map_err(|e| { - serde::de::Error::custom(format!( - "Failed to parse duration '{}': {}", - duration_str, e - )) - })?; + let duration = + humantime_serde::re::humantime::parse_duration(duration_str.as_str()) + .map_err(|e| { + serde::de::Error::custom(format!( + "Failed to parse duration '{}': {}", + duration_str, e + )) + })?; let bandwidths = bandwidths_str .into_iter() .map(|b| { - human_bandwidth::parse_bandwidth(b).map_err(|e| { + human_bandwidth::parse_bandwidth(&b).map_err(|e| { serde::de::Error::custom(format!( "Failed to parse bandwidth '{}': {}", b, e