1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
use std::time::Duration;
use serde::{Deserialize, Serialize};
use crate::error::{Error, ErrorKind};
/// Different resolutions supported by the time related
/// metric types (e.g. DatetimeMetric).
#[derive(Copy, Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
#[repr(i32)] // use i32 to be compatible with our JNA definition
pub enum TimeUnit {
/// Truncate to nanosecond precision.
Nanosecond,
/// Truncate to microsecond precision.
Microsecond,
/// Truncate to millisecond precision.
Millisecond,
/// Truncate to second precision.
Second,
/// Truncate to minute precision.
Minute,
/// Truncate to hour precision.
Hour,
/// Truncate to day precision.
Day,
}
impl TimeUnit {
/// Formats the given time unit, truncating the time if needed.
pub fn format_pattern(self) -> &'static str {
use TimeUnit::*;
match self {
Nanosecond => "%Y-%m-%dT%H:%M:%S%.f%:z",
Microsecond => "%Y-%m-%dT%H:%M:%S%.6f%:z",
Millisecond => "%Y-%m-%dT%H:%M:%S%.3f%:z",
Second => "%Y-%m-%dT%H:%M:%S%:z",
Minute => "%Y-%m-%dT%H:%M%:z",
Hour => "%Y-%m-%dT%H%:z",
Day => "%Y-%m-%d%:z",
}
}
/// Converts a duration to the requested time unit.
///
/// # Arguments
///
/// * `duration` - the duration to convert.
///
/// # Returns
///
/// The integer representation of the converted duration.
pub fn duration_convert(self, duration: Duration) -> u64 {
use TimeUnit::*;
match self {
Nanosecond => duration.as_nanos() as u64,
Microsecond => duration.as_micros() as u64,
Millisecond => duration.as_millis() as u64,
Second => duration.as_secs(),
Minute => duration.as_secs() / 60,
Hour => duration.as_secs() / 60 / 60,
Day => duration.as_secs() / 60 / 60 / 24,
}
}
/// Converts a duration in the given unit to nanoseconds.
///
/// # Arguments
///
/// * `duration` - the duration to convert.
///
/// # Returns
///
/// The integer representation of the nanosecond duration.
pub fn as_nanos(self, duration: u64) -> u64 {
use TimeUnit::*;
let duration = match self {
Nanosecond => Duration::from_nanos(duration),
Microsecond => Duration::from_micros(duration),
Millisecond => Duration::from_millis(duration),
Second => Duration::from_secs(duration),
Minute => Duration::from_secs(duration * 60),
Hour => Duration::from_secs(duration * 60 * 60),
Day => Duration::from_secs(duration * 60 * 60 * 24),
};
duration.as_nanos() as u64
}
}
/// Trait implementation for converting an integer value to a TimeUnit.
///
/// This is used in the FFI code.
///
/// Please note that values should match the ordering of the
/// platform specific side of things (e.g. Kotlin implementation).
impl TryFrom<i32> for TimeUnit {
type Error = Error;
fn try_from(value: i32) -> Result<TimeUnit, Self::Error> {
match value {
0 => Ok(TimeUnit::Nanosecond),
1 => Ok(TimeUnit::Microsecond),
2 => Ok(TimeUnit::Millisecond),
3 => Ok(TimeUnit::Second),
4 => Ok(TimeUnit::Minute),
5 => Ok(TimeUnit::Hour),
6 => Ok(TimeUnit::Day),
e => Err(ErrorKind::TimeUnit(e).into()),
}
}
}