redis_cell_rs/
command.rs

1use redis::{Cmd as RedisCmd, ToRedisArgs};
2use std::time::Duration;
3
4#[derive(Clone, Copy, Debug)]
5#[non_exhaustive]
6pub struct Policy {
7    pub burst: usize,
8
9    pub tokens: usize,
10
11    pub period: Duration,
12
13    pub apply: usize,
14
15    pub name: Option<&'static str>,
16}
17
18impl Policy {
19    pub const fn new(burst: usize, tokens: usize, period: Duration, apply: usize) -> Policy {
20        Self {
21            burst,
22            tokens,
23            period,
24            apply,
25            name: None,
26        }
27    }
28
29    pub const fn from_tokens_per_second(tokens: usize) -> Policy {
30        Policy::from_tokens_per_period(tokens, Duration::from_secs(1))
31    }
32
33    pub const fn from_tokens_per_minute(tokens: usize) -> Policy {
34        Policy::from_tokens_per_period(tokens, Duration::from_secs(60))
35    }
36
37    pub const fn from_tokens_per_hour(tokens: usize) -> Policy {
38        Policy::from_tokens_per_period(tokens, Duration::from_secs(60 * 60))
39    }
40
41    pub const fn from_tokens_per_day(tokens: usize) -> Policy {
42        Policy::from_tokens_per_period(tokens, Duration::from_secs(60 * 60 * 24))
43    }
44
45    pub const fn from_tokens_per_period(tokens: usize, period: Duration) -> Policy {
46        Policy::new(0, tokens, period, 1)
47    }
48
49    pub const fn max_burst(mut self, burst: usize) -> Policy {
50        self.burst = burst;
51        self
52    }
53
54    pub const fn apply_tokens(mut self, apply: usize) -> Policy {
55        self.apply = apply;
56        self
57    }
58
59    pub const fn name(mut self, name: &'static str) -> Policy {
60        self.name = Some(name);
61        self
62    }
63}
64
65pub struct Cmd<'a, K> {
66    key: K,
67    policy: &'a Policy,
68}
69
70impl<'a, K> Cmd<'a, K> {
71    pub fn new(key: K, policy: &'a Policy) -> Self {
72        Cmd { key, policy }
73    }
74}
75
76impl<'a, K> From<Cmd<'a, K>> for RedisCmd
77where
78    K: ToRedisArgs,
79{
80    fn from(Cmd { key, policy }: Cmd<'a, K>) -> Self {
81        let mut cmd = RedisCmd::new();
82        cmd.arg("CL.THROTTLE")
83            .arg(key)
84            .arg(policy.burst)
85            .arg(policy.tokens)
86            .arg(policy.period.as_secs())
87            .arg(policy.apply);
88        cmd
89    }
90}