Skip to content

Commit bc9d10b

Browse files
authored
Merge pull request #53 from veewee/feature/element-encoder-iso-cache
Cache type iso in ElementEncoder, refactor value builder/reader
2 parents 6dbd9be + fe5b6a8 commit bc9d10b

File tree

5 files changed

+61
-43
lines changed

5 files changed

+61
-43
lines changed

src/Encoder/ElementEncoder.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,21 +32,22 @@ public function iso(Context $context): Iso
3232
? $this->typeEncoder->enhanceElementContext($context)
3333
: $context;
3434

35+
$typeIso = $typeEncoder->iso($context);
36+
3537
return new Iso(
3638
/**
3739
* @psalm-param mixed $raw
3840
*/
3941
static fn (mixed $raw): string => (new XsdTypeXmlElementWriter())(
4042
$context,
41-
(new ElementValueBuilder($context, $typeEncoder, $raw))
43+
ElementValueBuilder::fromIso($context, $typeEncoder, $typeIso, $raw)
4244
),
4345
/**
4446
* @psalm-param non-empty-string|Element $xml
4547
* @psalm-return mixed
4648
*/
47-
static fn (Element|string $xml): mixed => (new ElementValueReader())(
48-
$context,
49-
$typeEncoder,
49+
static fn (Element|string $xml): mixed => ElementValueReader::forIso(
50+
$typeIso,
5051
($xml instanceof Element ? $xml : Element::fromString($xml))->element()
5152
)
5253
);

src/Encoder/SoapEnc/ApacheMapEncoder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ private function decodeArray(Context $context, Element $value): array
8787
static function (array $map, DOMElement $item) use ($context, $xpath): array {
8888
$key = $xpath->evaluate('string(./key)', string(), $item);
8989
/** @psalm-var mixed $value */
90-
$value = (new ElementValueReader())(
90+
$value = ElementValueReader::forEncoder(
9191
$context->withType(XsdType::any()),
9292
ScalarTypeEncoder::default(),
9393
assert_element($xpath->querySingle('./value', $item))

src/Encoder/SoapEnc/SoapObjectEncoder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ private function decodeArray(Context $context, Element $value): object
7878
static function (array $map, DOMElement $item) use ($context): array {
7979
$key = $item->localName ?? 'unkown';
8080
/** @psalm-var mixed $value */
81-
$value = (new ElementValueReader())(
81+
$value = ElementValueReader::forEncoder(
8282
$context->withType(XsdType::any()),
8383
ScalarTypeEncoder::default(),
8484
$item

src/Xml/Reader/ElementValueReader.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use DOMElement;
77
use Soap\Encoding\Encoder\Context;
88
use Soap\Encoding\Encoder\XmlEncoder;
9+
use VeeWee\Reflecta\Iso\Iso;
910
use function Psl\Type\string;
1011
use function VeeWee\Xml\Dom\Locator\Node\value as readValue;
1112

@@ -20,8 +21,28 @@ public function __invoke(
2021
XmlEncoder $encoder,
2122
DOMElement $element
2223
): mixed {
24+
return self::forEncoder($context, $encoder, $element);
25+
}
26+
27+
/**
28+
* @param XmlEncoder<mixed, string> $encoder
29+
* @psalm-return mixed
30+
*/
31+
public static function forEncoder(Context $context, XmlEncoder $encoder, DOMElement $element): mixed
32+
{
2333
return $encoder->iso($context)->from(
2434
readValue($element, string())
2535
);
2636
}
37+
38+
/**
39+
* @param Iso<mixed, string> $iso
40+
* @psalm-return mixed
41+
*/
42+
public static function forIso(Iso $iso, DOMElement $element): mixed
43+
{
44+
return $iso->from(
45+
readValue($element, string())
46+
);
47+
}
2748
}

src/Xml/Writer/ElementValueBuilder.php

Lines changed: 33 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33

44
namespace Soap\Encoding\Xml\Writer;
55

6+
use Closure;
67
use Generator;
78
use Soap\Encoding\Encoder\Context;
89
use Soap\Encoding\Encoder\Feature;
910
use Soap\Encoding\Encoder\XmlEncoder;
11+
use VeeWee\Reflecta\Iso\Iso;
1012
use XMLWriter;
1113
use function VeeWee\Xml\Writer\Builder\cdata;
1214
use function VeeWee\Xml\Writer\Builder\children;
@@ -15,67 +17,61 @@
1517
final class ElementValueBuilder
1618
{
1719
/**
18-
* @param XmlEncoder<mixed, string> $encoder
19-
* @psalm-param mixed $value
20+
* @param list<Closure(XMLWriter): Generator<bool>> $builders
2021
*/
21-
public function __construct(
22-
private readonly Context $context,
23-
private readonly XmlEncoder $encoder,
24-
private readonly mixed $value
22+
private function __construct(
23+
private readonly array $builders,
2524
) {
2625
}
2726

2827
/**
29-
* @return Generator<bool>
28+
* @param XmlEncoder<mixed, string> $encoder
29+
* @psalm-param mixed $value
3030
*/
31-
public function __invoke(XMLWriter $writer): Generator
31+
public static function fromEncoder(Context $context, XmlEncoder $encoder, mixed $value): self
3232
{
33-
yield from children([
34-
$this->buildXsiType(...),
35-
$this->buildValue(...),
36-
])($writer);
33+
return new self([
34+
XsiAttributeBuilder::forEncodedValue($context, $encoder, $value),
35+
self::valueWriter($encoder, static fn (): string => $encoder->iso($context)->to($value)),
36+
]);
3737
}
3838

3939
/**
40-
* @return Generator<bool>
40+
* @param XmlEncoder<mixed, string> $encoder
41+
* @param Iso<mixed, string> $iso
42+
* @psalm-param mixed $value
4143
*/
42-
private function buildXsiType(XMLWriter $writer): Generator
44+
public static function fromIso(Context $context, XmlEncoder $encoder, Iso $iso, mixed $value): self
4345
{
44-
yield from XsiAttributeBuilder::forEncodedValue(
45-
$this->context,
46-
$this->encoder,
47-
$this->value,
48-
)($writer);
46+
return new self([
47+
XsiAttributeBuilder::forEncodedValue($context, $encoder, $value),
48+
self::valueWriter($encoder, static fn (): string => $iso->to($value)),
49+
]);
4950
}
5051

5152
/**
52-
* @deprecated Use XsiAttributeBuilder::resolveXsiTypeForValue() instead. Will be removed in 1.0.0.
53+
* @return Generator<bool>
5354
*/
54-
public static function resolveXsiTypeForValue(Context $context, mixed $value): string
55+
public function __invoke(XMLWriter $writer): Generator
5556
{
56-
return XsiAttributeBuilder::resolveXsiTypeForValue($context, $value);
57+
yield from children($this->builders)($writer);
5758
}
5859

5960
/**
60-
* @deprecated Use XsiAttributeBuilder::shouldIncludeXsiTargetNamespace() instead. Will be removed in 1.0.0.
61+
* @param XmlEncoder<mixed, string> $encoder
62+
* @param Closure(): string $valueProvider
63+
*
64+
* @return Closure(XMLWriter): Generator<bool>
6165
*/
62-
public static function shouldIncludeXsiTargetNamespace(Context $context): bool
66+
private static function valueWriter(XmlEncoder $encoder, Closure $valueProvider): Closure
6367
{
64-
return XsiAttributeBuilder::shouldIncludeXsiTargetNamespace($context);
65-
}
68+
$isCData = $encoder instanceof Feature\CData;
6669

67-
/**
68-
* @return Generator<bool>
69-
*/
70-
private function buildValue(XMLWriter $writer): Generator
71-
{
72-
$encoded = $this->encoder->iso($this->context)->to($this->value);
70+
return static function (XMLWriter $writer) use ($isCData, $valueProvider): Generator {
71+
$encoded = $valueProvider();
72+
$builder = $isCData ? cdata(value($encoded)) : value($encoded);
7373

74-
$builder = match (true) {
75-
$this->encoder instanceof Feature\CData => cdata(value($encoded)),
76-
default => value($encoded)
74+
yield from $builder($writer);
7775
};
78-
79-
yield from $builder($writer);
8076
}
8177
}

0 commit comments

Comments
 (0)