mirror of
https://github.com/danog/ext-php-rs.git
synced 2024-11-26 20:15:22 +01:00
Support marking classes as interfaces (#155)
* Support marking classes as interfaces This allows passing flags as part of `#[php_class(flags=Interface]` etc, which allows one to mark a class as being an interface. When a class is an interface, it also shouldn't get a constructor created for it. * rustfmt
This commit is contained in:
parent
90cbbc0fca
commit
5d1fda4666
@ -22,6 +22,7 @@ pub struct Class {
|
||||
/// A function name called when creating the class entry. Given an instance
|
||||
/// of `ClassBuilder` and must return it.
|
||||
pub modifier: Option<String>,
|
||||
pub flags: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -37,6 +38,7 @@ pub enum ParsedAttribute {
|
||||
pub struct AttrArgs {
|
||||
name: Option<String>,
|
||||
modifier: Option<String>,
|
||||
flags: Option<Expr>,
|
||||
}
|
||||
|
||||
pub fn parser(args: AttributeArgs, mut input: ItemStruct) -> Result<TokenStream> {
|
||||
@ -117,6 +119,7 @@ pub fn parser(args: AttributeArgs, mut input: ItemStruct) -> Result<TokenStream>
|
||||
let ItemStruct { ident, .. } = &input;
|
||||
let class_name = args.name.unwrap_or_else(|| ident.to_string());
|
||||
let struct_path = ident.to_string();
|
||||
let flags = args.flags.map(|flags| flags.to_token_stream().to_string());
|
||||
let class = Class {
|
||||
class_name,
|
||||
struct_path,
|
||||
@ -125,6 +128,7 @@ pub fn parser(args: AttributeArgs, mut input: ItemStruct) -> Result<TokenStream>
|
||||
docs: comments,
|
||||
properties,
|
||||
modifier: args.modifier,
|
||||
flags,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
|
@ -121,6 +121,31 @@ fn build_classes(classes: &HashMap<String, Class>) -> Result<Vec<TokenStream>> {
|
||||
}
|
||||
});
|
||||
|
||||
let flags = {
|
||||
if let Some(flags) = &class.flags {
|
||||
let mut name = "::ext_php_rs::flags::ClassFlags::".to_owned();
|
||||
name.push_str(flags);
|
||||
let expr: Expr = syn::parse_str(&name).map_err(|_| {
|
||||
anyhow!("Invalid expression given for `{}` flags", class_name)
|
||||
})?;
|
||||
Some(quote! { .flags(#expr) })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
let object_override = {
|
||||
if let Some(flags) = &class.flags {
|
||||
if flags == "Interface" {
|
||||
None
|
||||
} else {
|
||||
Some(quote! { .object_override::<#ident>() })
|
||||
}
|
||||
} else {
|
||||
Some(quote! { .object_override::<#ident>() })
|
||||
}
|
||||
};
|
||||
|
||||
Ok(quote! {{
|
||||
let builder = ::ext_php_rs::builders::ClassBuilder::new(#class_name)
|
||||
#(#methods)*
|
||||
@ -128,7 +153,9 @@ fn build_classes(classes: &HashMap<String, Class>) -> Result<Vec<TokenStream>> {
|
||||
#(#interfaces)*
|
||||
// #(#properties)*
|
||||
#parent
|
||||
.object_override::<#ident>();
|
||||
#flags
|
||||
#object_override
|
||||
;
|
||||
#class_modifier
|
||||
let class = builder.build()
|
||||
.expect(concat!("Unable to build class `", #class_name, "`"));
|
||||
|
Loading…
Reference in New Issue
Block a user