Coverage Report

Created: 2026-02-14 06:16

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ztunnel/src/time.rs
Line
Count
Source
1
// Copyright Istio Authors
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
use std::time::{Instant, SystemTime};
16
17
#[derive(Clone)]
18
pub struct Converter {
19
    now: Instant,
20
    sys_now: SystemTime,
21
}
22
23
impl Converter {
24
0
    pub fn new() -> Self {
25
0
        Self::new_at(SystemTime::now())
26
0
    }
27
28
0
    pub fn new_at(sys_now: SystemTime) -> Self {
29
0
        Self {
30
0
            sys_now,
31
0
            now: Instant::now(),
32
0
        }
33
0
    }
34
35
0
    pub fn system_time_to_instant(&self, t: SystemTime) -> Option<Instant> {
36
0
        match t.duration_since(self.sys_now) {
37
0
            Ok(d) => Some(self.now + d),
38
0
            Err(_) => match self.sys_now.duration_since(t) {
39
0
                Ok(d) => self.now.checked_sub(d),
40
0
                Err(_) => panic!("time both before and after"),
41
            },
42
        }
43
0
    }
44
45
0
    pub fn instant_to_system_time(&self, t: Instant) -> Option<SystemTime> {
46
0
        if t > self.now {
47
0
            self.sys_now
48
0
                .checked_add(t.saturating_duration_since(self.now))
49
        } else {
50
0
            self.sys_now
51
0
                .checked_sub(self.now.saturating_duration_since(t))
52
        }
53
0
    }
54
55
0
    pub fn elapsed_nanos(&self, now: Instant) -> u128 {
56
0
        now.duration_since(self.now).as_nanos()
57
0
    }
58
59
0
    pub fn subsec_nanos(&self) -> u32 {
60
0
        self.sys_now
61
0
            .duration_since(SystemTime::UNIX_EPOCH)
62
0
            .unwrap()
63
0
            .subsec_nanos()
64
0
    }
65
}
66
67
impl Default for Converter {
68
0
    fn default() -> Self {
69
0
        Self::new()
70
0
    }
71
}
72
73
#[cfg(test)]
74
mod tests {
75
    use std::time::{Duration, Instant};
76
77
    #[test]
78
    fn test_converter() {
79
        const DELAY: Duration = Duration::from_secs(1);
80
        let conv = super::Converter::new();
81
        let now = Instant::now();
82
        let sys_now = conv.instant_to_system_time(now).unwrap();
83
        let later = conv.system_time_to_instant(sys_now + DELAY);
84
        assert_eq!(later, Some(now + DELAY));
85
    }
86
}