summaryrefslogtreecommitdiff
path: root/src/de.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/de.rs')
-rw-r--r--src/de.rs45
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))
+ }
+}