src/serde/duration_timecode.rs
Line | Count | Source (jump to first uncovered line) |
1 | | use std::fmt; |
2 | | |
3 | | use serde::{ |
4 | | de::{self, Deserializer, Visitor}, |
5 | | ser::Serializer, |
6 | | }; |
7 | | use time::Duration; |
8 | | |
9 | 0 | #[derive(Debug, thiserror::Error)] Unexecuted instantiation: <obws::serde::duration_timecode::Error as core::fmt::Debug>::fmt Unexecuted instantiation: <obws::serde::duration_timecode::Error as core::fmt::Debug>::fmt Unexecuted instantiation: <obws::serde::duration_timecode::Error as core::fmt::Display>::fmt Unexecuted instantiation: <obws::serde::duration_timecode::Error as core::convert::From<core::num::error::ParseIntError>>::from Unexecuted instantiation: <obws::serde::duration_timecode::Error as std::error::Error>::source Unexecuted instantiation: <obws::serde::duration_timecode::Error as std::error::Error>::source Unexecuted instantiation: <obws::serde::duration_timecode::Error as core::fmt::Display>::fmt Unexecuted instantiation: <obws::serde::duration_timecode::Error as core::convert::From<core::num::error::ParseIntError>>::from |
10 | | enum Error { |
11 | | #[error("hours missing")] |
12 | | HoursMissing, |
13 | | #[error("minutes missing")] |
14 | | MinutesMissing, |
15 | | #[error("seconds missing")] |
16 | | SecondsMissing, |
17 | | #[error("milliseconds missing")] |
18 | | MillisecondsMissing, |
19 | | #[error("invalid integer")] |
20 | | InvalidInteger(#[from] std::num::ParseIntError), |
21 | | } |
22 | | |
23 | | #[allow(dead_code)] |
24 | 1 | pub fn serialize<S>(value: &Duration, serializer: S) -> Result<S::Ok, S::Error> |
25 | 1 | where |
26 | 1 | S: Serializer, |
27 | 1 | { |
28 | 1 | let whole_secs = value.whole_seconds(); |
29 | 1 | let hours = whole_secs / 3600; |
30 | 1 | let minutes = whole_secs % 3600 / 60; |
31 | 1 | let seconds = whole_secs % 3600 % 60; |
32 | 1 | let millis = value.subsec_milliseconds(); |
33 | 1 | |
34 | 1 | serializer.serialize_str(&format!("{hours:02}:{minutes:02}:{seconds:02}.{millis:03}")) |
35 | 1 | } Unexecuted instantiation: obws::serde::duration_timecode::serialize::<_> obws::serde::duration_timecode::serialize::<&mut serde_test::ser::Serializer> Line | Count | Source | 24 | 1 | pub fn serialize<S>(value: &Duration, serializer: S) -> Result<S::Ok, S::Error> | 25 | 1 | where | 26 | 1 | S: Serializer, | 27 | 1 | { | 28 | 1 | let whole_secs = value.whole_seconds(); | 29 | 1 | let hours = whole_secs / 3600; | 30 | 1 | let minutes = whole_secs % 3600 / 60; | 31 | 1 | let seconds = whole_secs % 3600 % 60; | 32 | 1 | let millis = value.subsec_milliseconds(); | 33 | 1 | | 34 | 1 | serializer.serialize_str(&format!("{hours:02}:{minutes:02}:{seconds:02}.{millis:03}")) | 35 | 1 | } |
|
36 | | |
37 | 23 | pub fn deserialize<'de, D>(deserializer: D) -> Result<Duration, D::Error> |
38 | 23 | where |
39 | 23 | D: Deserializer<'de>, |
40 | 23 | { |
41 | 23 | deserializer.deserialize_str(DurationTimecodeVisitor) |
42 | 23 | } obws::serde::duration_timecode::deserialize::<serde_json::value::Value> Line | Count | Source | 37 | 21 | pub fn deserialize<'de, D>(deserializer: D) -> Result<Duration, D::Error> | 38 | 21 | where | 39 | 21 | D: Deserializer<'de>, | 40 | 21 | { | 41 | 21 | deserializer.deserialize_str(DurationTimecodeVisitor) | 42 | 21 | } |
Unexecuted instantiation: obws::serde::duration_timecode::deserialize::<_> Unexecuted instantiation: obws::serde::duration_timecode::deserialize::<serde::de::value::MapAccessDeserializer<serde_test::de::DeserializerMapVisitor>> obws::serde::duration_timecode::deserialize::<&mut serde_test::de::Deserializer> Line | Count | Source | 37 | 2 | pub fn deserialize<'de, D>(deserializer: D) -> Result<Duration, D::Error> | 38 | 2 | where | 39 | 2 | D: Deserializer<'de>, | 40 | 2 | { | 41 | 2 | deserializer.deserialize_str(DurationTimecodeVisitor) | 42 | 2 | } |
Unexecuted instantiation: obws::serde::duration_timecode::deserialize::<serde::de::value::SeqAccessDeserializer<serde_test::de::DeserializerSeqVisitor>> |
43 | | |
44 | | struct DurationTimecodeVisitor; |
45 | | |
46 | | impl<'de> Visitor<'de> for DurationTimecodeVisitor { |
47 | | type Value = Duration; |
48 | | |
49 | 0 | fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { |
50 | 0 | formatter.write_str("a duration formatted as 'HH:MM:SS.mmm'") |
51 | 0 | } Unexecuted instantiation: <obws::serde::duration_timecode::DurationTimecodeVisitor as serde::de::Visitor>::expecting Unexecuted instantiation: <obws::serde::duration_timecode::DurationTimecodeVisitor as serde::de::Visitor>::expecting |
52 | | |
53 | 23 | fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> |
54 | 23 | where |
55 | 23 | E: de::Error, |
56 | 23 | { |
57 | 23 | let duration = || -> Result<Duration, Error> { |
58 | 23 | let mut hms = v.splitn(3, ':'); |
59 | 23 | let hours = hms.next().ok_or(Error::HoursMissing)?0 .parse()?0 ; |
60 | 23 | let minutes = hms.next().ok_or(Error::MinutesMissing)?0 .parse()?0 ; |
61 | 23 | let seconds = hms.next().ok_or(Error::SecondsMissing)?0 ; |
62 | | |
63 | 23 | let mut sm = seconds.splitn(2, '.'); |
64 | 23 | let seconds = sm.next().ok_or(Error::SecondsMissing)?0 .parse()?0 ; |
65 | 23 | let millis = sm.next().ok_or(Error::MillisecondsMissing)?0 .parse()?0 ; |
66 | | |
67 | 23 | Ok(Duration::hours(hours) |
68 | 23 | + Duration::minutes(minutes) |
69 | 23 | + Duration::seconds(seconds) |
70 | 23 | + Duration::milliseconds(millis)) |
71 | 23 | }; <obws::serde::duration_timecode::DurationTimecodeVisitor as serde::de::Visitor>::visit_str::<serde_json::error::Error>::{closure#0} Line | Count | Source | 57 | 21 | let duration = || -> Result<Duration, Error> { | 58 | 21 | let mut hms = v.splitn(3, ':'); | 59 | 21 | let hours = hms.next().ok_or(Error::HoursMissing)?0 .parse()?0 ; | 60 | 21 | let minutes = hms.next().ok_or(Error::MinutesMissing)?0 .parse()?0 ; | 61 | 21 | let seconds = hms.next().ok_or(Error::SecondsMissing)?0 ; | 62 | | | 63 | 21 | let mut sm = seconds.splitn(2, '.'); | 64 | 21 | let seconds = sm.next().ok_or(Error::SecondsMissing)?0 .parse()?0 ; | 65 | 21 | let millis = sm.next().ok_or(Error::MillisecondsMissing)?0 .parse()?0 ; | 66 | | | 67 | 21 | Ok(Duration::hours(hours) | 68 | 21 | + Duration::minutes(minutes) | 69 | 21 | + Duration::seconds(seconds) | 70 | 21 | + Duration::milliseconds(millis)) | 71 | 21 | }; |
Unexecuted instantiation: <obws::serde::duration_timecode::DurationTimecodeVisitor as serde::de::Visitor>::visit_str::<_>::{closure#0} <obws::serde::duration_timecode::DurationTimecodeVisitor as serde::de::Visitor>::visit_str::<serde_test::error::Error>::{closure#0} Line | Count | Source | 57 | 2 | let duration = || -> Result<Duration, Error> { | 58 | 2 | let mut hms = v.splitn(3, ':'); | 59 | 2 | let hours = hms.next().ok_or(Error::HoursMissing)?0 .parse()?0 ; | 60 | 2 | let minutes = hms.next().ok_or(Error::MinutesMissing)?0 .parse()?0 ; | 61 | 2 | let seconds = hms.next().ok_or(Error::SecondsMissing)?0 ; | 62 | | | 63 | 2 | let mut sm = seconds.splitn(2, '.'); | 64 | 2 | let seconds = sm.next().ok_or(Error::SecondsMissing)?0 .parse()?0 ; | 65 | 2 | let millis = sm.next().ok_or(Error::MillisecondsMissing)?0 .parse()?0 ; | 66 | | | 67 | 2 | Ok(Duration::hours(hours) | 68 | 2 | + Duration::minutes(minutes) | 69 | 2 | + Duration::seconds(seconds) | 70 | 2 | + Duration::milliseconds(millis)) | 71 | 2 | }; |
|
72 | | |
73 | 23 | duration().map_err(de::Error::custom) |
74 | 23 | } <obws::serde::duration_timecode::DurationTimecodeVisitor as serde::de::Visitor>::visit_str::<serde_json::error::Error> Line | Count | Source | 53 | 21 | fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> | 54 | 21 | where | 55 | 21 | E: de::Error, | 56 | 21 | { | 57 | 21 | let duration = || -> Result<Duration, Error> { | 58 | | let mut hms = v.splitn(3, ':'); | 59 | | let hours = hms.next().ok_or(Error::HoursMissing)?.parse()?; | 60 | | let minutes = hms.next().ok_or(Error::MinutesMissing)?.parse()?; | 61 | | let seconds = hms.next().ok_or(Error::SecondsMissing)?; | 62 | | | 63 | | let mut sm = seconds.splitn(2, '.'); | 64 | | let seconds = sm.next().ok_or(Error::SecondsMissing)?.parse()?; | 65 | | let millis = sm.next().ok_or(Error::MillisecondsMissing)?.parse()?; | 66 | | | 67 | | Ok(Duration::hours(hours) | 68 | | + Duration::minutes(minutes) | 69 | | + Duration::seconds(seconds) | 70 | | + Duration::milliseconds(millis)) | 71 | | }; | 72 | | | 73 | 21 | duration().map_err(de::Error::custom) | 74 | 21 | } |
Unexecuted instantiation: <obws::serde::duration_timecode::DurationTimecodeVisitor as serde::de::Visitor>::visit_str::<_> <obws::serde::duration_timecode::DurationTimecodeVisitor as serde::de::Visitor>::visit_str::<serde_test::error::Error> Line | Count | Source | 53 | 2 | fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> | 54 | 2 | where | 55 | 2 | E: de::Error, | 56 | 2 | { | 57 | 2 | let duration = || -> Result<Duration, Error> { | 58 | | let mut hms = v.splitn(3, ':'); | 59 | | let hours = hms.next().ok_or(Error::HoursMissing)?.parse()?; | 60 | | let minutes = hms.next().ok_or(Error::MinutesMissing)?.parse()?; | 61 | | let seconds = hms.next().ok_or(Error::SecondsMissing)?; | 62 | | | 63 | | let mut sm = seconds.splitn(2, '.'); | 64 | | let seconds = sm.next().ok_or(Error::SecondsMissing)?.parse()?; | 65 | | let millis = sm.next().ok_or(Error::MillisecondsMissing)?.parse()?; | 66 | | | 67 | | Ok(Duration::hours(hours) | 68 | | + Duration::minutes(minutes) | 69 | | + Duration::seconds(seconds) | 70 | | + Duration::milliseconds(millis)) | 71 | | }; | 72 | | | 73 | 2 | duration().map_err(de::Error::custom) | 74 | 2 | } |
|
75 | | } |
76 | | |
77 | | #[cfg(test)] |
78 | | mod tests { |
79 | | use serde::{Deserialize, Serialize}; |
80 | | use serde_test::{assert_tokens, Token}; |
81 | | use time::Duration; |
82 | | |
83 | 8 | #[derive(Debug0 , PartialEq2 , Seri1 aliz1 e1 , D6 eserializ0 e)] Unexecuted instantiation: <obws::serde::duration_timecode::tests::SimpleDuration as core::cmp::PartialEq>::ne <obws::serde::duration_timecode::tests::SimpleDuration as core::cmp::PartialEq>::eq Line | Count | Source | 83 | 2 | #[derive(Debug, PartialEq, Serialize, Deserialize)] |
<obws::serde::duration_timecode::tests::SimpleDuration as serde::ser::Serialize>::serialize::<&mut serde_test::ser::Serializer> Line | Count | Source | 83 | 1 | #[derive(Debug, PartialEq, Serialize, Deserialize)] |
<<obws::serde::duration_timecode::tests::SimpleDuration as serde::ser::Serialize>::serialize::__SerializeWith as serde::ser::Serialize>::serialize::<&mut serde_test::ser::Serializer> Line | Count | Source | 83 | 1 | #[derive(Debug, PartialEq, Serialize, Deserialize)] |
<<obws::serde::duration_timecode::tests::SimpleDuration as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_str::<serde_test::error::Error> Line | Count | Source | 83 | 2 | #[derive(Debug, PartialEq, Serialize, Deserialize)] |
Unexecuted instantiation: <<obws::serde::duration_timecode::tests::SimpleDuration as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<serde_test::de::DeserializerSeqVisitor>::{closure#0} Unexecuted instantiation: <<obws::serde::duration_timecode::tests::SimpleDuration as serde::de::Deserialize>::deserialize::__Field as serde::de::Deserialize>::deserialize::<serde_test::de::BytesDeserializer> Unexecuted instantiation: <<obws::serde::duration_timecode::tests::SimpleDuration as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_map::<serde_test::de::EnumMapVisitor> Unexecuted instantiation: <<obws::serde::duration_timecode::tests::SimpleDuration as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_u64::<serde_test::error::Error> Unexecuted instantiation: <<obws::serde::duration_timecode::tests::SimpleDuration as serde::de::Deserialize>::deserialize::__Field as serde::de::Deserialize>::deserialize::<serde::de::value::U32Deserializer<serde_test::error::Error>> Unexecuted instantiation: <<obws::serde::duration_timecode::tests::SimpleDuration as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::visit_bytes::<serde_test::error::Error> Unexecuted instantiation: <<obws::serde::duration_timecode::tests::SimpleDuration as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::expecting <obws::serde::duration_timecode::tests::SimpleDuration as serde::de::Deserialize>::deserialize::<&mut serde_test::de::Deserializer> Line | Count | Source | 83 | 2 | #[derive(Debug, PartialEq, Serialize, Deserialize)] |
Unexecuted instantiation: <<obws::serde::duration_timecode::tests::SimpleDuration as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<serde_test::de::DeserializerSeqVisitor> Unexecuted instantiation: <<<obws::serde::duration_timecode::tests::SimpleDuration as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_map::__DeserializeWith as serde::de::Deserialize>::deserialize::<serde::de::value::SeqAccessDeserializer<serde_test::de::DeserializerSeqVisitor>> Unexecuted instantiation: <<<obws::serde::duration_timecode::tests::SimpleDuration as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_seq::__DeserializeWith as serde::de::Deserialize>::deserialize::<&mut serde_test::de::Deserializer> <<obws::serde::duration_timecode::tests::SimpleDuration as serde::de::Deserialize>::deserialize::__Field as serde::de::Deserialize>::deserialize::<&mut serde_test::de::Deserializer> Line | Count | Source | 83 | 2 | #[derive(Debug, PartialEq, Serialize, Deserialize)] |
<<obws::serde::duration_timecode::tests::SimpleDuration as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_map::<serde_test::de::DeserializerMapVisitor> Line | Count | Source | 83 | 4 | #[derive(Debug, PartialEq, Serialize, D2 eserialize)] |
Unexecuted instantiation: <<obws::serde::duration_timecode::tests::SimpleDuration as serde::de::Deserialize>::deserialize::__FieldVisitor as serde::de::Visitor>::expecting Unexecuted instantiation: <<obws::serde::duration_timecode::tests::SimpleDuration as serde::de::Deserialize>::deserialize::__Field as serde::de::Deserialize>::deserialize::<serde::de::value::StrDeserializer<serde_test::error::Error>> Unexecuted instantiation: <<<obws::serde::duration_timecode::tests::SimpleDuration as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_map::__DeserializeWith as serde::de::Deserialize>::deserialize::<serde::de::value::MapAccessDeserializer<serde_test::de::DeserializerMapVisitor>> <<<obws::serde::duration_timecode::tests::SimpleDuration as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_map::__DeserializeWith as serde::de::Deserialize>::deserialize::<&mut serde_test::de::Deserializer> Line | Count | Source | 83 | 2 | #[derive(Debug, PartialEq, Serialize, Deserialize)] |
|
84 | | struct SimpleDuration { |
85 | | #[serde(with = "super")] |
86 | | value: Duration, |
87 | | } |
88 | | |
89 | 1 | #[test] |
90 | 1 | fn roundtrip() { |
91 | 1 | assert_tokens( |
92 | 1 | &SimpleDuration { |
93 | 1 | value: Duration::hours(2) |
94 | 1 | + Duration::minutes(15) |
95 | 1 | + Duration::seconds(4) |
96 | 1 | + Duration::milliseconds(310), |
97 | 1 | }, |
98 | 1 | &[ |
99 | 1 | Token::Struct { |
100 | 1 | name: "SimpleDuration", |
101 | 1 | len: 1, |
102 | 1 | }, |
103 | 1 | Token::Str("value"), |
104 | 1 | Token::Str("02:15:04.310"), |
105 | 1 | Token::StructEnd, |
106 | 1 | ], |
107 | 1 | ); |
108 | 1 | } |
109 | | } |