Skip to main content

kinetics_parser/params/
worker.rs

1use crate::environment::{parse_environment, Environment};
2use serde::{Deserialize, Serialize};
3use syn::{
4    parse::{Parse, ParseStream},
5    token, Ident, LitBool, LitInt, LitStr,
6};
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct Worker {
10    pub name: Option<String>,
11    pub concurrency: u32,
12    pub fifo: bool,
13    pub environment: Environment,
14    pub batch_size: Option<u32>,
15}
16
17impl Parse for Worker {
18    fn parse(input: ParseStream) -> syn::Result<Self> {
19        let mut name = None;
20        let mut concurrency = None;
21        let mut fifo = None;
22        let mut environment = None;
23        let mut batch_size = None;
24
25        while !input.is_empty() {
26            let ident_span = input.span();
27            let ident: Ident = input.parse()?;
28            input.parse::<token::Eq>()?;
29
30            match ident.to_string().as_str() {
31                "name" => {
32                    if name.is_some() {
33                        return Err(syn::Error::new(ident_span, "Duplicate attribute `name`"));
34                    }
35                    name = Some(input.parse::<LitStr>()?.value());
36                }
37                "environment" => {
38                    if environment.is_some() {
39                        return Err(syn::Error::new(
40                            ident_span,
41                            "Duplicate attribute `environment`",
42                        ));
43                    }
44                    environment = Some(parse_environment(input)?);
45                }
46                "concurrency" => {
47                    if concurrency.is_some() {
48                        return Err(syn::Error::new(
49                            ident_span,
50                            "Duplicate attribute `concurrency`",
51                        ));
52                    }
53                    concurrency = Some(input.parse::<LitInt>()?.base10_parse::<u32>()?);
54                }
55                "fifo" => {
56                    if fifo.is_some() {
57                        return Err(syn::Error::new(ident_span, "Duplicate attribute `fifo`"));
58                    }
59                    fifo = match input.parse::<LitBool>() {
60                        Ok(bool) => Some(bool.value),
61                        Err(_) => {
62                            return Err(input.error("expected boolean value for 'fifo'"));
63                        }
64                    };
65                }
66                "batch_size" => {
67                    if batch_size.is_some() {
68                        return Err(syn::Error::new(
69                            ident_span,
70                            "Duplicate attribute `batch_size`",
71                        ));
72                    }
73
74                    let parsed = input.parse::<LitInt>()?.base10_parse::<u32>()?;
75
76                    if !(1..=10).contains(&parsed) {
77                        return Err(
78                            input.error("Batch size must be a positive integer between 1 and 10")
79                        );
80                    }
81
82                    batch_size = Some(parsed);
83                }
84                // Ignore unknown attributes
85                _ => {}
86            }
87
88            if !input.is_empty() {
89                input.parse::<token::Comma>()?;
90            }
91        }
92
93        Ok(Self {
94            name,
95            concurrency: concurrency.unwrap_or(1),
96            fifo: fifo.unwrap_or_default(),
97            environment: environment.unwrap_or_default(),
98            batch_size,
99        })
100    }
101}