extendr_macros/
extendr_options.rs

1use syn::{meta::ParseNestedMeta, Lit, LitBool};
2
3#[derive(Debug, Default)]
4pub(crate) struct ExtendrOptions {
5    pub r_name: Option<String>,
6    pub mod_name: Option<String>,
7    pub use_rng: bool,
8}
9
10impl ExtendrOptions {
11    /// Parse a set of attribute arguments for `#[extendr(opts...)]`
12    ///
13    /// Supported options:
14    ///
15    /// - `r_name = "name"` which specifies the name of the wrapper on the R-side.
16    /// - `use_rng = bool` ensures the RNG-state is pulled and pushed
17    ///
18    pub fn parse(&mut self, meta: ParseNestedMeta) -> syn::parse::Result<()> {
19        let value = meta.value()?;
20        let path = meta
21            .path
22            .get_ident()
23            .ok_or(meta.error("Unexpected syntax"))?;
24
25        match path.to_string().as_str() {
26            "r_name" => {
27                if let Ok(Lit::Str(litstr)) = value.parse() {
28                    self.r_name = Some(litstr.value());
29                    Ok(())
30                } else {
31                    Err(value.error("`r_name` must be a string literal"))
32                }
33            }
34            "mod_name" => {
35                if let Ok(Lit::Str(litstr)) = value.parse() {
36                    self.mod_name = Some(litstr.value());
37                    Ok(())
38                } else {
39                    Err(value.error("`mod_name` must be a string literal"))
40                }
41            }
42            "use_rng" => {
43                if let Ok(LitBool { value, .. }) = value.parse() {
44                    self.use_rng = value;
45                    Ok(())
46                } else {
47                    Err(value.error("`use_rng` must be `true` or `false`"))
48                }
49            }
50            _ => Err(syn::Error::new_spanned(meta.path, "Unexpected key")),
51        }
52    }
53}