diff options
Diffstat (limited to 'src/de.rs')
-rw-r--r-- | src/de.rs | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/src/de.rs b/src/de.rs new file mode 100644 index 0000000..47ad83a --- /dev/null +++ b/src/de.rs @@ -0,0 +1,45 @@ +/// Convert an h:m:s string to a Duration +pub mod hms_duration { + use std::num::ParseIntError; + use std::time::Duration; + + use serde::de::Error; + use serde::Deserialize; + use serde::Deserializer; + use serde::Serializer; + + pub fn serialize<S>(duration: &Duration, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + let secs = duration.as_secs(); + let hours = secs / 3600; + let minutes = (secs % 3600) / 60; + let seconds = secs % 60; + let s = if hours > 0 { + format!("{hours:0>2}:{minutes:0>2}:{seconds:0>2}") + } else { + format!("{minutes:0>2}:{seconds:0>2}") + }; + serializer.serialize_str(&s) + } + + pub fn deserialize<'de, D>(deserializer: D) -> Result<Duration, D::Error> + where + D: Deserializer<'de>, + { + let s = String::deserialize(deserializer)?; + from_string(s).map_err(Error::custom) + } + + pub fn from_string(s: String) -> Result<Duration, ParseIntError> { + let mut total_seconds = 0; + let mut mult = 1; + for x in s.rsplit(":") { + let t: u64 = x.parse()?; + total_seconds += t * mult; + mult *= 60; + } + Ok(Duration::from_secs(total_seconds)) + } +} |