• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

davidcole1340 / ext-php-rs / 16274060216

14 Jul 2025 05:51PM UTC coverage: 22.552%. Remained the same
16274060216

Pull #514

github

web-flow
Merge 7ee17f41f into 31c9d9968
Pull Request #514: feat(stubs)!: add stubs for `RustClosure`

13 of 15 new or added lines in 3 files covered. (86.67%)

58 existing lines in 3 files now uncovered.

882 of 3911 relevant lines covered (22.55%)

3.69 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/crates/macros/src/extern_.rs
1
use proc_macro2::TokenStream;
2
use quote::quote;
3
use syn::{
4
    punctuated::Punctuated, spanned::Spanned as _, token::Unsafe, ForeignItemFn, ItemForeignMod,
5
    ReturnType, Signature, Token,
6
};
7

8
use crate::prelude::*;
9

10
pub fn parser(input: ItemForeignMod) -> Result<TokenStream> {
×
11
    input
×
12
        .items
×
13
        .into_iter()
14
        .map(|item| match item {
×
15
            syn::ForeignItem::Fn(func) => parse_function(func),
×
16
            _ => bail!(item => "Only `extern` functions are supported by PHP."),
×
17
        })
18
        .collect::<Result<Vec<_>>>()
19
        .map(|vec| quote! { #(#vec)* })
×
20
}
21

22
fn parse_function(mut func: ForeignItemFn) -> Result<TokenStream> {
×
23
    let ForeignItemFn {
24
        attrs, vis, sig, ..
×
25
    } = &mut func;
×
26
    sig.unsafety = Some(Unsafe::default()); // Function must be unsafe.
×
27

28
    let Signature { ident, .. } = &sig;
×
29

30
    let name = ident.to_string();
×
31
    let params = sig
×
32
        .inputs
×
33
        .iter()
34
        .map(|input| match input {
×
35
            syn::FnArg::Typed(arg) => {
×
36
                let pat = &arg.pat;
×
37
                Some(quote! { &#pat })
×
38
            }
39
            syn::FnArg::Receiver(_) => None,
×
40
        })
41
        .collect::<Option<Punctuated<_, Token![,]>>>()
42
        .ok_or_else(|| {
×
43
            err!(sig.span() => "`self` parameters are not permitted inside `#[php_extern]` blocks.")
×
44
        })?;
45
    let ret = build_return(&name, &sig.output, &params);
×
46

47
    Ok(quote! {
×
48
        #(#attrs)* #vis #sig {
49
            use ::std::convert::TryInto;
50

51
            let callable = ::ext_php_rs::types::ZendCallable::try_from_name(
52
                #name
53
            ).expect(concat!("Unable to find callable function `", #name, "`."));
54

55
            #ret
56
        }
57
    })
58
}
59

60
fn build_return(
×
61
    name: &str,
62
    return_type: &ReturnType,
63
    params: &Punctuated<TokenStream, Token![,]>,
64
) -> TokenStream {
65
    match return_type {
×
66
        ReturnType::Default => quote! {
×
67
            callable.try_call(vec![ #params ]);
68
        },
69
        ReturnType::Type(_, _) => quote! {
×
70
            callable
71
                .try_call(vec![ #params ])
72
                .ok()
73
                .and_then(|zv| zv.try_into().ok())
74
                .expect(concat!("Failed to call function `", #name, "`."))
75
        },
76
    }
77
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc