Skip to content

Commit 8b51437

Browse files
committed
feat: Rewrite attribute parse
1 parent 4d782e1 commit 8b51437

File tree

1 file changed

+54
-4
lines changed

1 file changed

+54
-4
lines changed

crates/macros/src/interface.rs

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ use crate::helpers::{get_docs, CleanPhpAttr};
77
use darling::util::Flag;
88
use darling::FromAttributes;
99
use proc_macro2::TokenStream;
10-
use quote::{format_ident, quote};
10+
use quote::{format_ident, quote, ToTokens};
1111
use syn::{Expr, Ident, ItemTrait, Path, TraitItem, TraitItemConst, TraitItemFn};
1212

13-
use crate::impl_::{Constant, FnBuilder, MethodModifier};
13+
use crate::impl_::{FnBuilder, MethodModifier};
1414
use crate::parsing::{PhpRename, RenameRule, Visibility};
1515
use crate::prelude::*;
1616

@@ -110,7 +110,7 @@ pub fn parser(mut input: ItemTrait) -> Result<TokenStream> {
110110
}
111111

112112
fn get_constants(self) -> &'static [(&'static str, &'static dyn ::ext_php_rs::convert::IntoZvalDyn, &'static [&'static str])] {
113-
&[]
113+
&[#(#constants),*]
114114
}
115115
}
116116

@@ -195,10 +195,32 @@ pub struct PhpFunctionInterfaceAttribute {
195195
constructor: Flag,
196196
}
197197

198+
#[derive(Default)]
199+
struct InterfaceData<'a> {
200+
attrs: StructAttributes,
201+
methods: Vec<FnBuilder>,
202+
constants: Vec<Constant<'a>>
203+
}
204+
198205
trait Parse<'a, T> {
199206
fn parse(&'a mut self) -> Result<T>;
200207
}
201208

209+
impl<'a> Parse<'a, InterfaceData<'a>> for ItemTrait {
210+
fn parse(&'a mut self) -> Result<InterfaceData<'a>> {
211+
let mut data = InterfaceData::default();
212+
for item in self.items.iter_mut() {
213+
match item {
214+
TraitItem::Fn(f) => data.methods.push(f.parse()?),
215+
TraitItem::Const(c) => data.constants.push(c.parse()?),
216+
_ => {}
217+
}
218+
}
219+
220+
Ok(data)
221+
}
222+
}
223+
202224
impl<'a> Parse<'a, Vec<FnBuilder>> for ItemTrait {
203225
fn parse(&'a mut self) -> Result<Vec<FnBuilder>> {
204226
Ok(self
@@ -226,14 +248,42 @@ impl<'a> Parse<'a, Vec<Constant<'a>>> for ItemTrait {
226248
}
227249
}
228250

251+
struct Constant<'a> {
252+
name: String,
253+
expr: &'a Expr,
254+
docs: Vec<String>,
255+
}
256+
257+
impl ToTokens for Constant<'_> {
258+
fn to_tokens(&self, tokens: &mut TokenStream) {
259+
let name = &self.name;
260+
let expr = &self.expr;
261+
let docs = &self.docs;
262+
quote! {
263+
(#name, #expr, &[#(#docs),*])
264+
}.to_tokens(tokens);
265+
}
266+
}
267+
268+
impl<'a> Constant<'a> {
269+
fn new(name: String, expr: &'a Expr, docs: Vec<String>) -> Self {
270+
Self {name, expr, docs}
271+
}
272+
}
273+
229274
impl<'a> Parse<'a, Constant<'a>> for TraitItemConst {
230275
fn parse(&'a mut self) -> Result<Constant<'a>> {
276+
if self.default.is_none() {
277+
bail!("Interface const could not be empty");
278+
}
279+
231280
let attr = PhpConstAttribute::from_attributes(&self.attrs)?;
232281
let name = self.ident.to_string();
233282
let docs = get_docs(&attr.attrs)?;
234283
self.attrs.clean_php();
235284

236-
Ok(Constant::new(name, &self.ident, docs))
285+
let (_, expr) = self.default.as_ref().unwrap();
286+
Ok(Constant::new(name, expr, docs))
237287
}
238288
}
239289

0 commit comments

Comments
 (0)