Coverage Report

Created: 2026-03-17 06:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/logforth-append-file-0.3.0/src/rotation.rs
Line
Count
Source
1
// Copyright 2024 FastLabs Developers
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 jiff::RoundMode;
16
use jiff::ToSpan;
17
use jiff::Unit;
18
use jiff::Zoned;
19
use jiff::ZonedRound;
20
21
/// Rotation policies for rolling files.
22
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
23
pub enum Rotation {
24
    /// Rotate files every minute.
25
    Minutely,
26
    /// Rotate files every hour.
27
    Hourly,
28
    /// Rotate files every day.
29
    Daily,
30
    /// Never rotate files.
31
    Never,
32
}
33
34
impl Rotation {
35
    /// Get the next date timestamp based on the current date and rotation policy.
36
0
    pub fn next_date_timestamp(&self, current_date: &Zoned) -> Option<usize> {
37
0
        let round = ZonedRound::new().mode(RoundMode::Trunc);
38
0
        let next_date = match *self {
39
0
            Rotation::Never => return None,
40
0
            Rotation::Minutely => (current_date + 1.minute()).round(round.smallest(Unit::Minute)),
41
0
            Rotation::Hourly => (current_date + 1.hour()).round(round.smallest(Unit::Hour)),
42
0
            Rotation::Daily => (current_date + 1.day()).round(round.smallest(Unit::Day)),
43
        };
44
0
        let next_date =
45
0
            next_date.expect("invalid time; this is a bug in logforth rolling file appender");
46
0
        Some(next_date.timestamp().as_millisecond() as usize)
47
0
    }
48
49
    /// Get the date format string for the rotation policy.
50
0
    pub fn date_format(&self) -> &'static str {
51
0
        match *self {
52
0
            Rotation::Minutely => "%F-%H-%M",
53
0
            Rotation::Hourly => "%F-%H",
54
0
            Rotation::Daily => "%F",
55
0
            Rotation::Never => "%F",
56
        }
57
0
    }
58
}
59
60
#[cfg(test)]
61
mod tests {
62
    use std::str::FromStr;
63
64
    use jiff::Timestamp;
65
    use jiff::Zoned;
66
67
    use super::Rotation;
68
69
    #[test]
70
    fn test_next_date_timestamp() {
71
        let current_date = Zoned::from_str("2024-08-10T17:12:52+08[+08]").unwrap();
72
73
        assert_eq!(Rotation::Never.next_date_timestamp(&current_date), None);
74
75
        let expected_date = "2024-08-10T17:13:00+08".parse::<Timestamp>().unwrap();
76
        assert_eq!(
77
            Rotation::Minutely.next_date_timestamp(&current_date),
78
            Some(expected_date.as_millisecond() as usize)
79
        );
80
81
        let expected_date = "2024-08-10T18:00:00+08".parse::<Timestamp>().unwrap();
82
        assert_eq!(
83
            Rotation::Hourly.next_date_timestamp(&current_date),
84
            Some(expected_date.as_millisecond() as usize)
85
        );
86
87
        let expected_date = "2024-08-11T00:00:00+08".parse::<Timestamp>().unwrap();
88
        assert_eq!(
89
            Rotation::Daily.next_date_timestamp(&current_date),
90
            Some(expected_date.as_millisecond() as usize)
91
        );
92
    }
93
}