fn parse_fun()

in starlark_derive/src/parse.rs [247:324]


fn parse_fun(func: ItemFn) -> syn::Result<StarStmt> {
    let span = func.span();
    let sig_span = func.sig.span();

    let ProcessedAttributes {
        is_attribute,
        type_attribute,
        speculative_exec_safe,
        docstring,
        attrs,
    } = process_attributes(func.span(), func.attrs)?;

    let (return_type, return_type_arg) = match func.sig.output {
        ReturnType::Default => {
            return Err(syn::Error::new(span, "Function must have a return type"));
        }
        ReturnType::Type(_, x) => match is_anyhow_result(&x) {
            Some(return_arg_type) => (x, return_arg_type),
            None => {
                return Err(syn::Error::new(
                    span,
                    "Function return type must be precisely `anyhow::Result<...>`",
                ));
            }
        },
    };
    let mut args: Vec<_> = func
        .sig
        .inputs
        .into_iter()
        .map(parse_arg)
        .collect::<Result<_, _>>()?;

    if is_attribute {
        if args.len() != 1 {
            return Err(syn::Error::new(
                sig_span,
                "Attribute function must have single parameter",
            ));
        }
        let arg = args.pop().unwrap();
        if !arg.is_this() {
            return Err(syn::Error::new(
                sig_span,
                "Attribute function must have `this` as the only parameter",
            ));
        }
        if arg.default.is_some() {
            return Err(syn::Error::new(
                sig_span,
                "Attribute function `this` parameter have no default value",
            ));
        }
        Ok(StarStmt::Attr(StarAttr {
            name: func.sig.ident,
            arg: arg.ty,
            attrs,
            return_type: *return_type,
            return_type_arg,
            speculative_exec_safe,
            body: *func.block,
            docstring,
        }))
    } else {
        Ok(StarStmt::Fun(StarFun {
            name: func.sig.ident,
            type_attribute,
            attrs,
            args,
            return_type: *return_type,
            return_type_arg,
            speculative_exec_safe,
            body: *func.block,
            source: StarFunSource::Unknown,
            docstring,
        }))
    }
}