sentinel_macros/
hotspot.rs

1use darling::FromMeta;
2use proc_macro2::TokenStream as TokenStream2;
3use quote::quote;
4
5#[derive(Debug, FromMeta)]
6pub(crate) struct Params {
7    // sentinel
8    #[darling(default)]
9    pub traffic_type: Option<String>,
10    #[darling(default)]
11    pub args: Option<String>,
12    // rule
13    #[darling(default)]
14    pub threshold: Option<u64>,
15    #[darling(default)]
16    pub metric_type: Option<String>,
17    #[darling(default)]
18    pub control_strategy: Option<String>,
19    #[darling(default)]
20    pub param_index: Option<isize>,
21    #[darling(default)]
22    pub max_queueing_time_ms: Option<u64>,
23    #[darling(default)]
24    pub burst_count: Option<u64>,
25    #[darling(default)]
26    pub duration_in_sec: Option<u64>,
27    #[darling(default)]
28    pub param_max_capacity: Option<usize>,
29}
30
31pub(crate) fn process_rule(resource_name: &str, rule: &Params) -> TokenStream2 {
32    let control_strategy = parse_strategy(&rule.control_strategy);
33    let metric_type = parse_metric(&rule.metric_type);
34    let optional_params = expand_optional_params!(
35        rule,
36        threshold,
37        param_index,
38        max_queueing_time_ms,
39        burst_count,
40        duration_in_sec,
41        param_max_capacity
42    );
43    quote! {
44        hotspot::Rule {
45            id: String::from(#resource_name), // incase of duplication
46            resource: String::from(#resource_name),
47            #control_strategy
48            #metric_type
49            #optional_params
50            ..Default::default()
51        }
52    }
53}
54
55fn parse_metric(input: &Option<String>) -> TokenStream2 {
56    let mut metric = TokenStream2::new();
57    if let Some(val) = input {
58        metric.extend(match &val[..] {
59            "Concurrency" => quote! {metric_type: hotspot::MetricType::Concurrency,},
60            "QPS" => quote! {metric_type: hotspot::MetricType::QPS,},
61            _ => quote! {},
62        })
63    }
64    metric
65}
66
67fn parse_strategy(input: &Option<String>) -> TokenStream2 {
68    let mut strategy = TokenStream2::new();
69    if let Some(val) = input {
70        strategy.extend(match &val[..] {
71            "Reject" => quote! {control_strategy: hotspot::ControlStrategy::Reject,},
72            "Throttling" => quote! {control_strategy: hotspot::ControlStrategy::Throttling,},
73            _ => quote! {},
74        })
75    }
76    strategy
77}