ceres_derive/
fun.rs

1//! Host function parser
2use crate::arg::Arg;
3use proc_macro2::Span;
4use syn::{
5    parenthesized,
6    parse::{Parse, ParseStream},
7    punctuated::Punctuated,
8    token::{Fn, Paren},
9    Attribute, Expr, Ident, Result, Token, Type, Visibility,
10};
11
12/// Host function
13pub struct HostFunction {
14    pub attrs: Vec<Attribute>,
15    pub vis: Visibility,
16    _fn: Fn,
17    pub name: Ident,
18    pub paren_token: Paren,
19    pub fields: Punctuated<Arg, Token![,]>,
20    pub arrow_t: Token![->],
21    pub return_t: Type,
22    pub content: Expr,
23}
24
25#[allow(clippy::eval_order_dependence)]
26impl Parse for HostFunction {
27    fn parse(input: ParseStream) -> Result<Self> {
28        let content;
29        Ok(HostFunction {
30            attrs: input.call(Attribute::parse_outer)?,
31            vis: input.parse()?,
32            _fn: input.parse()?,
33            name: input.parse()?,
34            paren_token: parenthesized!(content in input),
35            fields: content.parse_terminated(Arg::parse)?,
36            arrow_t: input.parse()?,
37            return_t: input.parse()?,
38            content: input.parse()?,
39        })
40    }
41}
42
43impl HostFunction {
44    /// Generate struct ident from function name
45    pub fn struct_ident(&self) -> Ident {
46        let name: String = self
47            .name
48            .to_string()
49            .split('_')
50            .into_iter()
51            .map(|s| {
52                s.chars()
53                    .into_iter()
54                    .enumerate()
55                    .map(|(i, v)| {
56                        if i == 0 {
57                            v.to_uppercase().to_string()
58                        } else {
59                            v.to_string()
60                        }
61                    })
62                    .collect::<String>()
63            })
64            .collect();
65        Ident::new(&name, Span::call_site())
66    }
67}