#![allow(unexpected_cfgs)]
use syn::{ItemFn, ReturnType, Type};
use crate::internals::{ast::FnVariable, ctx::Context};
pub(crate) mod item_fn {
use super::*;
#[cfg(not(feature = "no_main"))]
pub(crate) fn ident_is_main(ctx: &Context, input_fn: &ItemFn) {
if input_fn.sig.ident != "main" {
let msg = "the function name must be `main`";
ctx.error_spanned_by(&input_fn.sig.ident, msg);
}
}
pub(crate) fn is_async(ctx: &Context, input_fn: &ItemFn) {
if input_fn.sig.asyncness.is_none() {
let msg = "the `async` keyword is missing from the function declaration";
ctx.error_spanned_by(input_fn.sig.fn_token, msg);
}
}
pub(crate) fn has_one_arg(ctx: &Context, input_fn: &ItemFn) {
if input_fn.sig.inputs.len() != 1 {
let msg = "the function must have exactly one argument";
ctx.error_spanned_by(&input_fn.sig.inputs, msg);
}
}
pub(crate) fn has_ockam_ctx_arg<'a>(
ctx: &Context,
input_fn: &'a ItemFn,
ockam_ctx: &'a Option<FnVariable<'a>>,
) -> &'a Option<FnVariable<'a>> {
if ockam_ctx.is_none() {
let msg = "the function has no `Context` argument";
ctx.error_spanned_by(&input_fn.sig.inputs, msg);
}
ockam_ctx
}
pub(crate) fn ockam_ctx_is_mut_ref(ctx: &Context, ockam_ctx: &Option<FnVariable>) {
if let Some(ockam_ctx) = ockam_ctx {
if ockam_ctx.and_token.is_none() {
let msg = "the `Context` argument must be passed as reference";
ctx.error_spanned_by(ockam_ctx.arg, msg);
}
if ockam_ctx.mutability.is_none() {
let msg = "the `Context` argument must be mutable";
ctx.error_spanned_by(ockam_ctx.arg, msg);
}
}
}
pub(crate) fn returns_result(ctx: &Context, input_fn: &ItemFn) {
let msg = "the function must have a return type";
match &input_fn.sig.output {
ReturnType::Default => {
ctx.error_spanned_by(&input_fn.sig, msg);
}
ReturnType::Type(_, ret_ty) => match ret_ty.as_ref() {
Type::Path(ty_p) => {
if !ty_p
.path
.segments
.iter()
.any(|s| s.ident.to_string().contains("Result"))
{
ctx.error_spanned_by(ret_ty, msg);
}
}
_ => {
ctx.error_spanned_by(ret_ty, msg);
}
},
}
}
}