Skip to content

Commit 62027a5

Browse files
committed
Migrate to STAB optics (Iso<S,T,A,B> / Lens<S,T,A,B>)
1 parent a968f3b commit 62027a5

45 files changed

Lines changed: 214 additions & 181 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
"php-standard-library/str": "^6.1",
3535
"php-standard-library/type": "^6.1",
3636
"php-standard-library/vec": "^6.1",
37-
"veewee/reflecta": "~0.16",
37+
"veewee/reflecta": "dev-feature/stab-optics as 0.19.0",
3838
"veewee/xml": "^4.10",
3939
"php-soap/engine": "^2.20",
4040
"php-soap/wsdl": "^1.19",

src/Encoder/AnyElementEncoder.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@
1919
use function Psl\Type\vec;
2020

2121
/**
22-
* @implements XmlEncoder<array|string|null, string>
22+
* @implements XmlEncoder<array|string|null, array<array-key, string>|string|null, string, ElementList|string>
2323
*
2424
* @psalm-import-type LookupArray from DocumentToLookupArrayReader
2525
*
26-
* @template-implements Feature\ProvidesObjectDecoderLens<LookupArray, ElementList>
26+
* @template-implements Feature\ProvidesObjectDecoderLens<LookupArray, LookupArray, ElementList, ElementList>
2727
*/
2828
final class AnyElementEncoder implements Feature\ListAware, Feature\OptionalAware, Feature\ProvidesObjectDecoderLens, XmlEncoder
2929
{
@@ -32,7 +32,7 @@ final class AnyElementEncoder implements Feature\ListAware, Feature\OptionalAwar
3232
* It will contain all the XML tags available in the object that is surrounding the 'any' property.
3333
* Properties that are already known by the object, will be omitted.
3434
*
35-
* @return Lens<LookupArray, ElementList>
35+
* @return Lens<LookupArray, LookupArray, ElementList, ElementList>
3636
*/
3737
public static function createObjectDecoderLens(Type $parentType, Property $currentProperty): Lens
3838
{
@@ -51,7 +51,7 @@ public static function createObjectDecoderLens(Type $parentType, Property $curre
5151
*/
5252
$omit = static fn (array $data): array => diff_by_key($data, array_flip($omittedKeys));
5353

54-
/** @var Lens<LookupArray, ElementList> */
54+
/** @var Lens<LookupArray, LookupArray, ElementList, ElementList> */
5555
return Lens::readonly(
5656
/**
5757
* @psalm-suppress MixedArgumentTypeCoercion - Psalm gets confused about the result of omit.
@@ -62,7 +62,7 @@ public static function createObjectDecoderLens(Type $parentType, Property $curre
6262
}
6363

6464
/**
65-
* @return Iso<array|string|null, string>
65+
* @return Iso<array|string|null, array<array-key, string>|string|null, string, ElementList|string>
6666
*/
6767
public function iso(Context $context): Iso
6868
{

src/Encoder/ElementEncoder.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,20 @@
1010
use VeeWee\Reflecta\Iso\Iso;
1111

1212
/**
13-
* @implements XmlEncoder<mixed, string>
13+
* @implements XmlEncoder<mixed, mixed, non-empty-string, Element|non-empty-string>
1414
*/
1515
final class ElementEncoder implements Feature\ElementAware, XmlEncoder
1616
{
1717
/**
18-
* @param XmlEncoder<mixed, string> $typeEncoder
18+
* @param XmlEncoder<mixed, mixed, string, string> $typeEncoder
1919
*/
2020
public function __construct(
2121
private readonly XmlEncoder $typeEncoder
2222
) {
2323
}
2424

2525
/**
26-
* @return Iso<mixed, string>
26+
* @return Iso<mixed, mixed, non-empty-string, Element|non-empty-string>
2727
*/
2828
public function iso(Context $context): Iso
2929
{

src/Encoder/EncoderDetector.php

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
namespace Soap\Encoding\Encoder;
55

66
use Soap\Encoding\Cache\ScopedCache;
7+
use Soap\Encoding\Xml\Node\Element;
8+
use Soap\Encoding\Xml\Node\ElementList;
79
use Soap\Engine\Metadata\Model\XsdType;
810
use stdClass;
911

@@ -18,7 +20,7 @@ public static function default(): self
1820
}
1921

2022
/**
21-
* @return ScopedCache<XsdType, XmlEncoder<mixed, string>>
23+
* @return ScopedCache<XsdType, XmlEncoder<mixed, mixed, string|null, Element|ElementList|string|null>>
2224
*
2325
* @psalm-suppress LessSpecificReturnStatement, MoreSpecificReturnType, MixedReturnStatement
2426
*/
@@ -30,9 +32,7 @@ private static function cache(): ScopedCache
3032
}
3133

3234
/**
33-
* @return XmlEncoder<mixed, string>
34-
*
35-
* @psalm-suppress InvalidArgument, InvalidReturnType, PossiblyInvalidArgument, InvalidReturnStatement - The simple type detector could return string|null, but should not be an issue here.
35+
* @return XmlEncoder<mixed, mixed, string|null, Element|ElementList|string|null>
3636
*/
3737
public function __invoke(Context $context): XmlEncoder
3838
{
@@ -44,9 +44,7 @@ public function __invoke(Context $context): XmlEncoder
4444
}
4545

4646
/**
47-
* @return XmlEncoder<mixed, string>
48-
*
49-
* @psalm-suppress PossiblyInvalidArgument - The simple type detector could return string|null, but should not be an issue here.
47+
* @return XmlEncoder<mixed, mixed, string|null, Element|ElementList|string|null>
5048
*/
5149
private function detect(Context $context): XmlEncoder
5250
{
@@ -62,8 +60,8 @@ private function detect(Context $context): XmlEncoder
6260
}
6361

6462
/**
65-
* @param XmlEncoder<mixed, string> $encoder
66-
* @return XmlEncoder<mixed, string>
63+
* @param XmlEncoder<mixed, mixed, string|null, Element|ElementList|string|null> $encoder
64+
* @return XmlEncoder<mixed, mixed, string|null, Element|ElementList|string|null>
6765
*/
6866
private function enhanceEncoder(Context $context, XmlEncoder $encoder): XmlEncoder
6967
{
@@ -86,7 +84,7 @@ private function enhanceEncoder(Context $context, XmlEncoder $encoder): XmlEncod
8684
}
8785

8886
/**
89-
* @return XmlEncoder<mixed, string>
87+
* @return XmlEncoder<mixed, mixed, string, Element|ElementList|string>
9088
*/
9189
private function detectComplexTypeEncoder(XsdType $type, Context $context): XmlEncoder
9290
{

src/Encoder/ErrorHandlingEncoder.php

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,41 +8,43 @@
88
use VeeWee\Reflecta\Iso\Iso;
99

1010
/**
11-
* @template-covariant TData
12-
* @template-covariant TXml
11+
* @template TDataIn
12+
* @template TDataOut
13+
* @template TXmlOut
14+
* @template TXmlIn
1315
*
14-
* @implements XmlEncoder<TData, TXml>
15-
* @implements Feature\DecoratingEncoder<TData, TXml>
16+
* @implements XmlEncoder<TDataIn, TDataOut, TXmlOut, TXmlIn>
17+
* @implements Feature\DecoratingEncoder<TDataIn, TDataOut, TXmlOut, TXmlIn>
1618
*/
1719
final class ErrorHandlingEncoder implements Feature\DecoratingEncoder, XmlEncoder
1820
{
1921
/**
20-
* @param XmlEncoder<TData, TXml> $encoder
22+
* @param XmlEncoder<TDataIn, TDataOut, TXmlOut, TXmlIn> $encoder
2123
*/
2224
public function __construct(
2325
private readonly XmlEncoder $encoder
2426
) {
2527
}
2628

2729
/**
28-
* @return XmlEncoder<TData, TXml>
30+
* @return XmlEncoder<TDataIn, TDataOut, TXmlOut, TXmlIn>
2931
*/
3032
public function decoratedEncoder(): XmlEncoder
3133
{
3234
return $this->encoder;
3335
}
3436

3537
/**
36-
* @return Iso<TData, TXml>
38+
* @return Iso<TDataIn, TDataOut, TXmlOut, TXmlIn>
3739
*/
3840
public function iso(Context $context): Iso
3941
{
4042
$innerIso = $this->encoder->iso($context);
4143

4244
return new Iso(
4345
/**
44-
* @psalm-param TData $value
45-
* @psalm-return TXml
46+
* @psalm-param TDataIn $value
47+
* @psalm-return TXmlOut
4648
*/
4749
static function (mixed $value) use ($innerIso, $context): mixed {
4850
try {
@@ -52,8 +54,8 @@ static function (mixed $value) use ($innerIso, $context): mixed {
5254
}
5355
},
5456
/**
55-
* @psalm-param TXml $value
56-
* @psalm-return TData
57+
* @psalm-param TXmlIn $value
58+
* @psalm-return TDataOut
5759
*/
5860
static function (mixed $value) use ($innerIso, $context): mixed {
5961
try {

src/Encoder/Feature/DecoratingEncoder.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@
55
use Soap\Encoding\Encoder\XmlEncoder;
66

77
/**
8-
* @template-covariant TData
9-
* @template-covariant TXml
8+
* @template-covariant TDataIn
9+
* @template-covariant TDataOut
10+
* @template-covariant TXmlOut
11+
* @template-covariant TXmlIn
1012
*/
1113
interface DecoratingEncoder
1214
{
1315
/**
14-
* @return XmlEncoder<TData, TXml>
16+
* @return XmlEncoder<TDataIn, TDataOut, TXmlOut, TXmlIn>
1517
*/
1618
public function decoratedEncoder(): XmlEncoder;
1719
}

src/Encoder/Feature/ProvidesObjectDecoderLens.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,20 @@
44

55
use Soap\Engine\Metadata\Model\Property;
66
use Soap\Engine\Metadata\Model\Type;
7-
use VeeWee\Reflecta\Lens\Lens;
7+
use VeeWee\Reflecta\Lens\LensInterface;
88

99
/**
1010
* When an encoder implements this feature interface, it knows how to create a lens that will be applied on the parent data that is being decoded.
1111
*
12-
* @template-covariant S
12+
* @template-covariant S of array<array-key, mixed>
13+
* @template-covariant T of array<array-key, mixed>
1314
* @template-covariant A
15+
* @template-covariant B
1416
*/
1517
interface ProvidesObjectDecoderLens
1618
{
1719
/**
18-
* @return Lens<S, A>
20+
* @return LensInterface<S, T, A, B>
1921
*/
20-
public static function createObjectDecoderLens(Type $parentType, Property $currentProperty): Lens;
22+
public static function createObjectDecoderLens(Type $parentType, Property $currentProperty): LensInterface;
2123
}

src/Encoder/Feature/ProvidesObjectEncoderLens.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,20 @@
44

55
use Soap\Engine\Metadata\Model\Property;
66
use Soap\Engine\Metadata\Model\Type;
7-
use VeeWee\Reflecta\Lens\Lens;
7+
use VeeWee\Reflecta\Lens\LensInterface;
88

99
/**
1010
* When an encoder implements this feature interface, it knows how to create a lens that will be applied on the parent data that is being encoded.
1111
*
12-
* @template-covariant S
12+
* @template-covariant S of object
13+
* @template-covariant T of object
1314
* @template-covariant A
15+
* @template-covariant B
1416
*/
1517
interface ProvidesObjectEncoderLens
1618
{
1719
/**
18-
* @return Lens<S, A>
20+
* @return LensInterface<S, T, A, B>
1921
*/
20-
public static function createObjectEncoderLens(Type $parentType, Property $currentProperty): Lens;
22+
public static function createObjectEncoderLens(Type $parentType, Property $currentProperty): LensInterface;
2123
}

src/Encoder/FixedIsoEncoder.php

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,29 @@
22

33
namespace Soap\Encoding\Encoder;
44

5-
use VeeWee\Reflecta\Iso\Iso;
5+
use VeeWee\Reflecta\Iso\IsoInterface;
66

77
/**
88
* @template S
9+
* @template T
910
* @template A
10-
* @implements XmlEncoder<S, A>
11+
* @template B
12+
* @implements XmlEncoder<S, T, A, B>
1113
*/
1214
final readonly class FixedIsoEncoder implements XmlEncoder
1315
{
1416
/**
15-
* @param Iso<S, A> $iso
17+
* @param IsoInterface<S, T, A, B> $iso
1618
*/
1719
public function __construct(
18-
private Iso $iso,
20+
private IsoInterface $iso,
1921
) {
2022
}
2123

2224
/**
23-
* @return Iso<S, A>
25+
* @return IsoInterface<S, T, A, B>
2426
*/
25-
public function iso(Context $context): Iso
27+
public function iso(Context $context): IsoInterface
2628
{
2729
return $this->iso;
2830
}

src/Encoder/MatchingValueEncoder.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,18 @@
1111
* This encoder can be used to select an encoder based on the value being encoded.
1212
* For decoding, it will always use the default encoder.
1313
*
14-
* @psalm-type MatchedEncoderInfo = Context | array{0: Context, 1 ?: XmlEncoder<mixed, string>|null}
14+
* @psalm-type MatchedEncoderInfo = Context | array{0: Context, 1 ?: XmlEncoder<mixed, mixed, string, Element|string>|null}
1515
* @psalm-type MatchingEncoderDetector = \Closure(Context, mixed): MatchedEncoderInfo
1616
*
1717
* @psalm-suppress UnusedClass
1818
*
19-
* @implements XmlEncoder<mixed, string>
19+
* @implements XmlEncoder<mixed, mixed, string, Element|string>
2020
*/
2121
final readonly class MatchingValueEncoder implements XmlEncoder
2222
{
2323
/**
2424
* @param MatchingEncoderDetector $encoderDetector
25-
* @param XmlEncoder<mixed, string> $defaultEncoder
25+
* @param XmlEncoder<mixed, mixed, string, Element|string> $defaultEncoder
2626
*/
2727
public function __construct(
2828
private Closure $encoderDetector,
@@ -32,7 +32,6 @@ public function __construct(
3232

3333
public function iso(Context $context): Iso
3434
{
35-
/** @var Iso<string, mixed> $defaultIso */
3635
$defaultIso = $this->defaultEncoder->iso($context);
3736

3837
return new Iso(

0 commit comments

Comments
 (0)