@@ -9,7 +9,7 @@ use crate::{
9
9
exception:: PhpException ,
10
10
ffi:: {
11
11
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 ,
13
13
} ,
14
14
flags:: { ClassFlags , MethodFlags , PropertyFlags } ,
15
15
types:: { ZendClassObject , ZendObject , ZendStr , Zval } ,
@@ -293,16 +293,24 @@ impl ClassBuilder {
293
293
let func = Box :: into_raw ( methods. into_boxed_slice ( ) ) as * const FunctionEntry ;
294
294
self . ce . info . internal . builtin_functions = func;
295
295
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
+ }
306
314
} ;
307
315
308
316
// disable serialization if the class has an associated object
@@ -364,3 +372,77 @@ impl ClassBuilder {
364
372
Ok ( ( ) )
365
373
}
366
374
}
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