1use super::{
2 decode_u128_varint, encode_u128_varint, encode_u128_varint_to, encoded_u128_varint_len,
3 DecodeError, EncodeError, U128VarintBuffer, Varint,
4};
5
6use core::time::Duration;
7
8pub type DurationBuffer = U128VarintBuffer;
10
11#[inline]
14pub const fn encoded_duration_len(duration: &Duration) -> usize {
15 let value = ((duration.as_secs() as u128) << 32) | (duration.subsec_nanos() as u128);
17 encoded_u128_varint_len(value)
18}
19
20#[inline]
22pub const fn encode_duration(duration: &Duration) -> DurationBuffer {
23 let value = ((duration.as_secs() as u128) << 32) | (duration.subsec_nanos() as u128);
25 encode_u128_varint(value)
26}
27
28#[inline]
30pub const fn encode_duration_to(duration: &Duration, buf: &mut [u8]) -> Result<usize, EncodeError> {
31 let value = ((duration.as_secs() as u128) << 32) | (duration.subsec_nanos() as u128);
33 encode_u128_varint_to(value, buf)
34}
35
36#[inline]
40pub const fn decode_duration(buf: &[u8]) -> Result<(usize, Duration), DecodeError> {
41 match decode_u128_varint(buf) {
42 Ok((bytes_read, value)) => {
43 let secs = (value >> 32) as u64; let nanos = (value & 0xFFFFFFFF) as u32; Ok((bytes_read, Duration::new(secs, nanos)))
46 }
47 Err(e) => Err(e),
48 }
49}
50
51impl Varint for Duration {
52 const MIN_ENCODED_LEN: usize = u128::MIN_ENCODED_LEN;
53 const MAX_ENCODED_LEN: usize = u128::MAX_ENCODED_LEN;
54
55 #[inline]
56 fn encoded_len(&self) -> usize {
57 encoded_duration_len(self)
58 }
59
60 #[inline]
61 fn encode(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
62 encode_duration_to(self, buf)
63 }
64
65 #[inline]
66 fn decode(buf: &[u8]) -> Result<(usize, Self), DecodeError>
67 where
68 Self: Sized,
69 {
70 decode_duration(buf)
71 }
72}
73
74#[cfg(test)]
75mod tests {
76 use super::*;
77
78 use quickcheck_macros::quickcheck;
79
80 #[quickcheck]
81 fn encode_decode_duration(value: Duration) -> bool {
82 let encoded = encode_duration(&value);
83 if encoded.len() != encoded_duration_len(&value)
84 || (encoded.len() > <Duration>::MAX_ENCODED_LEN)
85 {
86 return false;
87 }
88
89 if let Ok((bytes_read, decoded)) = decode_duration(&encoded) {
90 value == decoded && encoded.len() == bytes_read
91 } else {
92 false
93 }
94 }
95
96 #[quickcheck]
97 fn encode_decode_duration_varint(value: Duration) -> bool {
98 let mut buf = [0; <Duration>::MAX_ENCODED_LEN];
99 let Ok(encoded_len) = value.encode(&mut buf) else {
100 return false;
101 };
102 if encoded_len != value.encoded_len() || (value.encoded_len() > <Duration>::MAX_ENCODED_LEN) {
103 return false;
104 }
105
106 if let Ok((bytes_read, decoded)) = <Duration>::decode(&buf) {
107 value == decoded && encoded_len == bytes_read
108 } else {
109 false
110 }
111 }
112}