@@ -211,6 +211,125 @@ impl VecIterator {
211211// You can use `#[php_impl_interface]` to implement interfaces defined in other crates.
212212// See the `php_interface` and `php_impl_interface` macros for more details.
213213
214+ // ============================================================================
215+ // Test Feature 5: Short form implements syntax
216+ // Using #[php(implements("\\InterfaceName"))] instead of the verbose
217+ // #[php(implements(ce = ce::interface, stub = "\\InterfaceName"))]
218+ // ============================================================================
219+
220+ /// Test class implementing `ArrayAccess` using short form syntax.
221+ /// This tests runtime class entry lookup via `ClassEntry::try_find_no_autoload()`.
222+ #[ php_class]
223+ #[ php( name = "ExtPhpRs\\ Interface\\ ShortFormArrayAccess" ) ]
224+ #[ php( implements( "\\ ArrayAccess" ) ) ]
225+ pub struct ShortFormArrayAccess {
226+ data : Vec < i64 > ,
227+ }
228+
229+ #[ php_impl]
230+ #[ allow( clippy:: cast_possible_truncation, clippy:: cast_sign_loss) ]
231+ impl ShortFormArrayAccess {
232+ pub fn __construct ( ) -> Self {
233+ Self {
234+ data : vec ! [ 10 , 20 , 30 , 40 , 50 ] ,
235+ }
236+ }
237+
238+ pub fn offset_exists ( & self , offset : i64 ) -> bool {
239+ offset >= 0 && ( offset as usize ) < self . data . len ( )
240+ }
241+
242+ pub fn offset_get ( & self , offset : i64 ) -> Option < i64 > {
243+ self . data . get ( offset as usize ) . copied ( )
244+ }
245+
246+ pub fn offset_set ( & mut self , offset : i64 , value : i64 ) {
247+ if offset >= 0 && ( offset as usize ) < self . data . len ( ) {
248+ self . data [ offset as usize ] = value;
249+ }
250+ }
251+
252+ pub fn offset_unset ( & mut self , offset : i64 ) {
253+ if offset >= 0 && ( offset as usize ) < self . data . len ( ) {
254+ self . data . remove ( offset as usize ) ;
255+ }
256+ }
257+ }
258+
259+ /// Test class implementing `Countable` using short form syntax.
260+ /// `Countable` is defined in SPL which is always available.
261+ #[ php_class]
262+ #[ php( name = "ExtPhpRs\\ Interface\\ CountableTest" ) ]
263+ #[ php( implements( "\\ Countable" ) ) ]
264+ pub struct CountableTest {
265+ items : Vec < String > ,
266+ }
267+
268+ #[ php_impl]
269+ #[ allow( clippy:: cast_possible_wrap) ]
270+ impl CountableTest {
271+ pub fn __construct ( ) -> Self {
272+ Self { items : Vec :: new ( ) }
273+ }
274+
275+ pub fn add ( & mut self , item : String ) {
276+ self . items . push ( item) ;
277+ }
278+
279+ /// Returns the count for `count()`.
280+ pub fn count ( & self ) -> i64 {
281+ self . items . len ( ) as i64
282+ }
283+ }
284+
285+ /// Test class implementing multiple interfaces using mixed syntax
286+ /// (both short form and explicit form).
287+ #[ php_class]
288+ #[ php( name = "ExtPhpRs\\ Interface\\ MixedImplementsTest" ) ]
289+ #[ php( implements( ce = ce:: iterator, stub = "\\ Iterator" ) ) ]
290+ #[ php( implements( "\\ Countable" ) ) ]
291+ pub struct MixedImplementsTest {
292+ items : Vec < i64 > ,
293+ index : usize ,
294+ }
295+
296+ #[ php_impl]
297+ impl MixedImplementsTest {
298+ pub fn __construct ( ) -> Self {
299+ Self {
300+ items : vec ! [ 10 , 20 , 30 ] ,
301+ index : 0 ,
302+ }
303+ }
304+
305+ // Iterator methods
306+ pub fn current ( & self ) -> Option < i64 > {
307+ self . items . get ( self . index ) . copied ( )
308+ }
309+
310+ pub fn key ( & self ) -> usize {
311+ self . index
312+ }
313+
314+ pub fn next ( & mut self ) {
315+ self . index += 1 ;
316+ }
317+
318+ pub fn rewind ( & mut self ) {
319+ self . index = 0 ;
320+ }
321+
322+ pub fn valid ( & self ) -> bool {
323+ self . index < self . items . len ( )
324+ }
325+
326+ #[ allow( clippy:: cast_possible_wrap) ]
327+ // Countable method
328+ pub fn count ( & self ) -> i64 {
329+ self . items . len ( ) as i64
330+ }
331+ }
332+
214333// Test Feature 2: Interface inheritance via trait bounds
215334// Define a parent interface
216335#[ php_interface]
@@ -270,6 +389,10 @@ pub fn build_module(builder: ModuleBuilder) -> ModuleBuilder {
270389 . class :: < VecIterator > ( )
271390 // Greeter with #[php_impl_interface]
272391 . class :: < Greeter > ( )
392+ // Short form implements syntax tests
393+ . class :: < ShortFormArrayAccess > ( )
394+ . class :: < CountableTest > ( )
395+ . class :: < MixedImplementsTest > ( )
273396}
274397
275398#[ cfg( test) ]
0 commit comments