gosh_dl/protocol/
scheduler.rs

1//! Bandwidth scheduling types
2//!
3//! Types for time-based bandwidth limit scheduling.
4
5use chrono::Weekday;
6use serde::{Deserialize, Serialize};
7
8/// A rule for time-based bandwidth scheduling
9#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
10pub struct ScheduleRule {
11    /// Start hour (0-23, inclusive)
12    pub start_hour: u8,
13    /// End hour (0-23, inclusive). If end < start, rule wraps around midnight
14    pub end_hour: u8,
15    /// Days of week this rule applies (empty = all days)
16    #[serde(default)]
17    pub days: Vec<Weekday>,
18    /// Download speed limit in bytes/sec (None = unlimited)
19    pub download_limit: Option<u64>,
20    /// Upload speed limit in bytes/sec (None = unlimited)
21    pub upload_limit: Option<u64>,
22}
23
24impl ScheduleRule {
25    /// Create a new schedule rule
26    pub fn new(
27        start_hour: u8,
28        end_hour: u8,
29        days: Vec<Weekday>,
30        download_limit: Option<u64>,
31        upload_limit: Option<u64>,
32    ) -> Self {
33        Self {
34            start_hour: start_hour.min(23),
35            end_hour: end_hour.min(23),
36            days,
37            download_limit,
38            upload_limit,
39        }
40    }
41
42    /// Create a rule that applies to all days
43    pub fn all_days(
44        start_hour: u8,
45        end_hour: u8,
46        download_limit: Option<u64>,
47        upload_limit: Option<u64>,
48    ) -> Self {
49        Self::new(
50            start_hour,
51            end_hour,
52            Vec::new(),
53            download_limit,
54            upload_limit,
55        )
56    }
57
58    /// Create a rule for weekdays only (Mon-Fri)
59    pub fn weekdays(
60        start_hour: u8,
61        end_hour: u8,
62        download_limit: Option<u64>,
63        upload_limit: Option<u64>,
64    ) -> Self {
65        Self::new(
66            start_hour,
67            end_hour,
68            vec![
69                Weekday::Mon,
70                Weekday::Tue,
71                Weekday::Wed,
72                Weekday::Thu,
73                Weekday::Fri,
74            ],
75            download_limit,
76            upload_limit,
77        )
78    }
79
80    /// Create a rule for weekends only (Sat-Sun)
81    pub fn weekends(
82        start_hour: u8,
83        end_hour: u8,
84        download_limit: Option<u64>,
85        upload_limit: Option<u64>,
86    ) -> Self {
87        Self::new(
88            start_hour,
89            end_hour,
90            vec![Weekday::Sat, Weekday::Sun],
91            download_limit,
92            upload_limit,
93        )
94    }
95
96    /// Check if this rule matches the given time
97    pub fn matches(&self, hour: u8, weekday: Weekday) -> bool {
98        // Check day of week
99        if !self.days.is_empty() && !self.days.contains(&weekday) {
100            return false;
101        }
102
103        // Check time range
104        if self.start_hour <= self.end_hour {
105            // Normal range (e.g., 9-17)
106            hour >= self.start_hour && hour <= self.end_hour
107        } else {
108            // Wraps around midnight (e.g., 22-6)
109            hour >= self.start_hour || hour <= self.end_hour
110        }
111    }
112}
113
114/// Current bandwidth limits (possibly from schedule)
115#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
116pub struct BandwidthLimits {
117    /// Download speed limit in bytes/sec (None = unlimited)
118    pub download: Option<u64>,
119    /// Upload speed limit in bytes/sec (None = unlimited)
120    pub upload: Option<u64>,
121}