@@ -9,7 +9,7 @@ use crate::{
99 exception:: PhpException ,
1010 ffi:: {
1111 zend_declare_class_constant, zend_declare_property, zend_do_implement_interface,
12- zend_register_internal_class_ex,
12+ zend_register_internal_class_ex, zend_register_internal_interface ,
1313 } ,
1414 flags:: { ClassFlags , MethodFlags , PropertyFlags } ,
1515 types:: { ZendClassObject , ZendObject , ZendStr , Zval } ,
@@ -293,16 +293,24 @@ impl ClassBuilder {
293293 let func = Box :: into_raw ( methods. into_boxed_slice ( ) ) as * const FunctionEntry ;
294294 self . ce . info . internal . builtin_functions = func;
295295
296- let class = unsafe {
297- zend_register_internal_class_ex (
298- & mut self . ce ,
299- match self . extends {
300- Some ( ptr) => ( ptr as * const _ ) as * mut _ ,
301- None => std:: ptr:: null_mut ( ) ,
302- } ,
303- )
304- . as_mut ( )
305- . ok_or ( Error :: InvalidPointer ) ?
296+ let class = if self . ce . flags ( ) . contains ( ClassFlags :: Interface ) {
297+ unsafe {
298+ zend_register_internal_interface ( & mut self . ce )
299+ . as_mut ( )
300+ . ok_or ( Error :: InvalidPointer ) ?
301+ }
302+ } else {
303+ unsafe {
304+ zend_register_internal_class_ex (
305+ & mut self . ce ,
306+ match self . extends {
307+ Some ( ptr) => ( ptr as * const _ ) as * mut _ ,
308+ None => std:: ptr:: null_mut ( ) ,
309+ } ,
310+ )
311+ . as_mut ( )
312+ . ok_or ( Error :: InvalidPointer ) ?
313+ }
306314 } ;
307315
308316 // disable serialization if the class has an associated object
@@ -364,3 +372,77 @@ impl ClassBuilder {
364372 Ok ( ( ) )
365373 }
366374}
375+
376+ pub struct InterfaceBuilder {
377+ class_builder : ClassBuilder ,
378+ }
379+
380+ impl InterfaceBuilder {
381+ pub fn new < T : Into < String > > ( name : T ) -> Self {
382+ Self {
383+ class_builder : ClassBuilder :: new ( name) ,
384+ }
385+ }
386+
387+ pub fn implements ( mut self , interface : & ' static ClassEntry ) -> Self {
388+ self . class_builder = self . class_builder . implements ( interface) ;
389+
390+ self
391+ }
392+
393+ pub fn method ( mut self , func : FunctionBuilder < ' static > , flags : MethodFlags ) -> Self {
394+ self . class_builder = self . class_builder . method ( func, flags) ;
395+
396+ self
397+ }
398+
399+ pub fn constant < T : Into < String > > (
400+ mut self ,
401+ name : T ,
402+ value : impl IntoZval + ' static ,
403+ docs : DocComments ,
404+ ) -> Result < Self > {
405+ self . class_builder = self . class_builder . constant ( name, value, docs) ?;
406+
407+ Ok ( self )
408+ }
409+
410+ pub fn dyn_constant < T : Into < String > > (
411+ mut self ,
412+ name : T ,
413+ value : & ' static dyn IntoZvalDyn ,
414+ docs : DocComments ,
415+ ) -> Result < Self > {
416+ self . class_builder = self . class_builder . dyn_constant ( name, value, docs) ?;
417+
418+ Ok ( self )
419+ }
420+
421+ pub fn flags ( mut self , flags : ClassFlags ) -> Self {
422+ self . class_builder = self . class_builder . flags ( flags) ;
423+ self
424+ }
425+
426+ pub fn object_override < T : RegisteredClass > ( mut self ) -> Self {
427+ self . class_builder = self . class_builder . object_override :: < T > ( ) ;
428+
429+ self
430+ }
431+
432+ pub fn registration ( mut self , register : fn ( & ' static mut ClassEntry ) ) -> Self {
433+ self . class_builder = self . class_builder . registration ( register) ;
434+
435+ self
436+ }
437+
438+ pub fn docs ( mut self , docs : DocComments ) -> Self {
439+ self . class_builder = self . class_builder . docs ( docs) ;
440+ self
441+ }
442+
443+ pub fn builder ( mut self ) -> ClassBuilder {
444+ self . class_builder = self . class_builder . flags ( ClassFlags :: Interface ) ;
445+ dbg ! ( self . class_builder. ce. ce_flags) ;
446+ self . class_builder
447+ }
448+ }
0 commit comments