Skip to content

Contracts: extract experimental capability interfaces#120

Merged
zanbaldwin merged 1 commit into
6.xfrom
z/interface-vision
Jun 16, 2026
Merged

Contracts: extract experimental capability interfaces#120
zanbaldwin merged 1 commit into
6.xfrom
z/interface-vision

Conversation

@zanbaldwin

Copy link
Copy Markdown
Member
  • Introduce composable capability interfaces under Darsyn\IP\Contracts\.
  • Tagged @experimental ahead of the 7.0 interface decomposition.

Introduce composable capability interfaces under `Darsyn\IP\Contracts\`.
Tagged `@experimental` ahead of the 7.0 interface decomposition.
@zanbaldwin zanbaldwin self-assigned this Jun 15, 2026
@greptile-apps

greptile-apps Bot commented Jun 15, 2026

Copy link
Copy Markdown

Greptile Summary

This PR extracts capability-specific interfaces from the monolithic IpInterface into a new Darsyn\IP\Contracts\ namespace, tagged @experimental ahead of the planned 7.0 decomposition. IpInterface and the Version4/6Interface types are refactored to compose these granular interfaces rather than redeclare every method inline.

  • Eight new composable interfaces (ArithmeticInterface, ClassificationInterface, Classification4Interface, Classification6Interface, ComparisonInterface, OutputInterface, Output4Interface, Output6Interface, VersionIdentityInterface) are introduced with no behavioural changes.
  • Version4Interface and Version6Interface become empty proxy interfaces that extend the matching capability contracts; MULTICAST_* constants move to Classification6Interface but remain accessible as Version6Interface::MULTICAST_* through PHP's normal interface inheritance, preserving backward compatibility.
  • Tests are extended to assert that concrete IP classes satisfy each new capability interface.

Confidence Score: 4/5

Safe to merge for 6.x — all changes are purely additive interface extractions with no behavioural modifications and backward-compatible constant access.

The refactoring is structurally sound and introduces no breaking changes for 6.x consumers. The one concern worth tracking before 7.0 stabilises is that ComparisonInterface references IpInterface in all three method signatures, creating a circular coupling that prevents the interface from being implemented independently — which could limit the composability story the PR is preparing for.

src/Contracts/ComparisonInterface.php — the IpInterface parameter types on equals, inRange, and getCommonCidr should be revisited before the interfaces graduate out of @experimental.

Important Files Changed

Filename Overview
src/Contracts/ComparisonInterface.php New composable interface for comparison methods, but its parameter types (IpInterface) create a circular dependency with IpInterface that limits standalone composability.
src/IpInterface.php Refactored to extend the five new capability interfaces; remaining methods (isMapped, isDerived, isCompatible, isEmbedded, deprecated isPublicUse) stay in place — no breaking changes.
src/Version/Version4Interface.php Reduced to a clean empty-body proxy extending IpInterface, Classification4Interface, and Output4Interface; all prior methods and constants are still accessible via the inheritance chain.
src/Version/Version6Interface.php Reduced to an empty-body proxy; MULTICAST_* constants moved to Classification6Interface but remain accessible as Version6Interface::MULTICAST_* through inheritance — backward compatible.
src/Contracts/ClassificationInterface.php New base classification interface extracting common isLinkLocal, isLoopback, isMulticast, etc. methods; clean with no dependencies on other library types.
src/Contracts/Classification4Interface.php New IPv4-specific classification interface extending ClassificationInterface; adds isBroadcast, isShared, isFutureReserved.
src/Contracts/Classification6Interface.php New IPv6-specific classification interface; hosts the MULTICAST_* constants and adds getMulticastScope, isUniqueLocal, isUnicast, isUnicastGlobal.
src/Contracts/ArithmeticInterface.php Extracts getNetworkIp and getBroadcastIp into a standalone interface with no external dependencies.
src/Contracts/OutputInterface.php Extracts getBinary and __toString into a standalone output interface; clean, no dependencies.
src/Contracts/Output4Interface.php Adds getDotAddress() on top of OutputInterface; signature matches existing implementation.
src/Contracts/Output6Interface.php Adds getCompactedAddress and getExpandedAddress on top of OutputInterface; clean extraction.
src/Contracts/VersionIdentityInterface.php Extracts getVersion, isVersion, isVersion4, isVersion6 into a standalone identity interface; no dependencies.
tests/Version/IPv4Test.php Adds interface-check test for IPv4; new method uses both /** @test */ and #[PHPUnit\Test] simultaneously (redundant).
tests/Version/IPv6Test.php Adds interface-check test for IPv6; same duplicate-annotation pattern as IPv4Test.
tests/Version/MultiTest.php Adds interface-check test for Multi (including both IPv4 and IPv6 capability interfaces); same duplicate-annotation pattern.

Class Diagram

%%{init: {'theme': 'neutral'}}%%
classDiagram
    class OutputInterface {
        +getBinary() string
        +__toString() string
    }
    class Output4Interface {
        +getDotAddress() string
    }
    class Output6Interface {
        +getCompactedAddress() string
        +getExpandedAddress() string
    }
    class VersionIdentityInterface {
        +getVersion() int
        +isVersion(int) bool
        +isVersion4() bool
        +isVersion6() bool
    }
    class ArithmeticInterface {
        +getNetworkIp(int) static
        +getBroadcastIp(int) static
    }
    class ComparisonInterface {
        +equals(IpInterface) bool
        +inRange(IpInterface, int) bool
        +getCommonCidr(IpInterface) int
    }
    class ClassificationInterface {
        +isLinkLocal() bool
        +isLoopback() bool
        +isMulticast() bool
        +isPrivateUse() bool
        +isUnspecified() bool
        +isBenchmarking() bool
        +isDocumentation() bool
        +isGloballyReachable() bool
    }
    class Classification4Interface {
        +isBroadcast() bool
        +isShared() bool
        +isFutureReserved() bool
    }
    class Classification6Interface {
        +MULTICAST_* constants
        +getMulticastScope() ?int
        +isUniqueLocal() bool
        +isUnicast() bool
        +isUnicastGlobal() bool
    }
    class IpInterface {
        +factory(string) static
        +isMapped() bool
        +isDerived() bool
        +isCompatible() bool
        +isEmbedded() bool
        +isPublicUse() bool
    }
    class Version4Interface
    class Version6Interface

    Output4Interface --|> OutputInterface
    Output6Interface --|> OutputInterface
    Classification4Interface --|> ClassificationInterface
    Classification6Interface --|> ClassificationInterface
    IpInterface --|> ArithmeticInterface
    IpInterface --|> ClassificationInterface
    IpInterface --|> ComparisonInterface
    IpInterface --|> OutputInterface
    IpInterface --|> VersionIdentityInterface
    Version4Interface --|> IpInterface
    Version4Interface --|> Classification4Interface
    Version4Interface --|> Output4Interface
    Version6Interface --|> IpInterface
    Version6Interface --|> Classification6Interface
    Version6Interface --|> Output6Interface
Loading

Reviews (1): Last reviewed commit: "feature(contracts): ✨ extract experiment..." | Re-trigger Greptile

Comment thread src/Contracts/ComparisonInterface.php
Comment thread tests/Version/IPv4Test.php
@zanbaldwin zanbaldwin merged commit f145db7 into 6.x Jun 16, 2026
24 checks passed
@zanbaldwin zanbaldwin deleted the z/interface-vision branch June 16, 2026 09:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant