ferment-sys 0.2.14

Syntax tree morphing of FFI-compatible stuff
Documentation
use std::fmt::{Debug, Formatter};
use proc_macro2::Ident;
use syn::{ItemFn, Signature, Type, TypeBareFn};
use quote::ToTokens;

#[derive(Clone)]
pub enum FnSignatureContext {
    ModFn(ItemFn),
    Impl(Signature, Type),
    TraitImpl(Signature, Type, Type),
    TraitAsType(Signature, Type, Type),
    Bare(Ident, TypeBareFn),
    TraitInner(Signature, Type, Type)
}

impl Debug for FnSignatureContext {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        match self {
            FnSignatureContext::Bare(ident, type_bare_fn) =>
                f.write_fmt(format_args!("Bare({}, {})", ident.to_token_stream(), type_bare_fn.to_token_stream())),
            FnSignatureContext::ModFn(sig) =>
                f.write_fmt(format_args!("ModFn({})", sig.to_token_stream())),
            FnSignatureContext::Impl(sig, self_ty) =>
                f.write_fmt(format_args!("Impl(self: {}, sig: {})", self_ty.to_token_stream(), sig.to_token_stream())),
            FnSignatureContext::TraitImpl(sig, self_ty, trait_ty) =>
                f.write_fmt(format_args!("TraitImpl(self: {}, trait: {}, sig: {})", self_ty.to_token_stream(), trait_ty.to_token_stream(), sig.to_token_stream())),
            FnSignatureContext::TraitAsType(sig, self_ty, trait_ty) =>
                f.write_fmt(format_args!("TraitAsType(self: {}, trait: {}, sig: {})", self_ty.to_token_stream(), trait_ty.to_token_stream(), sig.to_token_stream())),
            FnSignatureContext::TraitInner(sig, self_ty, trait_ty) =>
                f.write_fmt(format_args!("TraitInner(self: {}, trait: {}, sig: {})", self_ty.to_token_stream(), trait_ty.to_token_stream(), sig.to_token_stream())),
        }
    }
}

impl FnSignatureContext {
    #[allow(unused)]
    pub fn is_trait_fn(&self) -> bool {
        matches!(self, FnSignatureContext::TraitImpl(..) | FnSignatureContext::TraitAsType(..))
    }

    pub fn maybe_signature(&self) -> Option<&Signature> {
        match self {
            FnSignatureContext::ModFn(ItemFn { sig, .. }) |
            FnSignatureContext::Impl(sig, ..) |
            FnSignatureContext::TraitImpl(sig, ..) |
            FnSignatureContext::TraitAsType(sig, ..) |
            FnSignatureContext::TraitInner(sig, ..) => Some(sig),
            FnSignatureContext::Bare(..) => None
        }
    }

    pub fn receiver_ty(&self) -> &Type {
        match self {
            FnSignatureContext::TraitAsType(.., trait_ty) |
            FnSignatureContext::TraitImpl(.., trait_ty) |
            FnSignatureContext::TraitInner(.., trait_ty) => trait_ty,
            FnSignatureContext::Impl(.., self_ty) => self_ty,
            _ => panic!("Receiver in mod fn")
        }
    }

    pub fn ident(&self) -> &Ident {
        match self {
            FnSignatureContext::ModFn(ItemFn { sig, .. }) |
            FnSignatureContext::Impl(sig, ..) |
            FnSignatureContext::TraitImpl(sig, ..) |
            FnSignatureContext::TraitAsType(sig, ..) |
            FnSignatureContext::TraitInner(sig, ..) => &sig.ident,
            FnSignatureContext::Bare(ident, ..) => ident,
        }
    }
}