blob: 069e038c19e7dcf96288f7fbc47c76c65e581a06 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//! Utilities useful when parsing and serializing wire formats.
use core::time::Duration;
/// A zero-valued `Duration`.
const ZERO_DURATION: Duration = Duration::from_secs(0);
/// A thin wrapper over a [`Duration`] that guarantees that the underlying
/// `Duration` is non-zero.
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
pub struct NonZeroDuration(Duration);
impl NonZeroDuration {
/// Creates a non-zero without checking the value.
pub const unsafe fn new_unchecked(d: Duration) -> NonZeroDuration {
NonZeroDuration(d)
}
/// Creates a non-zero if the given value is not zero.
pub fn new(d: Duration) -> Option<NonZeroDuration> {
if d == ZERO_DURATION {
return None;
}
Some(NonZeroDuration(d))
}
/// Returns the value as a [`Duration`].
pub const fn get(&self) -> Duration {
self.0
}
}
impl Into<Duration> for NonZeroDuration {
fn into(self) -> Duration {
self.0
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn non_zero_duration() {
// `NonZeroDuration` should not hold a zero duration.
assert_eq!(NonZeroDuration::new(Duration::from_secs(0)), None);
let d = Duration::from_secs(1);
// `new_unchecked` should hold the duration as is.
assert_eq!(unsafe { NonZeroDuration::new_unchecked(d) }, NonZeroDuration(d));
// `NonZeroDuration` should hold a non-zero duration.
let non_zero = NonZeroDuration::new(d);
assert_eq!(non_zero, Some(NonZeroDuration(d)));
// `get` and `Into::into` should return the underlying duration.
let non_zero = non_zero.unwrap();
assert_eq!(d, non_zero.get());
assert_eq!(d, non_zero.into());
}
}