Skip to content

Commit 3a1f3b5

Browse files
authored
Merge pull request #9 from veewee/perf
Performance optimizations
2 parents 1b25f2b + e87d790 commit 3a1f3b5

File tree

6 files changed

+64
-98
lines changed

6 files changed

+64
-98
lines changed

src/Encoder/ErrorHandlingEncoder.php

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -30,45 +30,47 @@ public function __construct(
3030
public function iso(Context $context): Iso
3131
{
3232
$innerIso = $this->encoder->iso($context);
33-
$buildPath = static function () use ($context): ?string {
34-
$meta = $context->type->getMeta();
35-
$isElement = $meta->isElement()->unwrapOr(false);
36-
$isAttribute = $meta->isAttribute()->unwrapOr(false);
37-
if (!$isElement && !$isAttribute) {
38-
return null;
39-
}
40-
41-
$path = $context->type->getXmlTargetNodeName();
42-
if ($isAttribute) {
43-
return '@' . $path;
44-
}
45-
46-
return $path;
47-
};
4833

4934
return new Iso(
5035
/**
5136
* @psalm-param TData $value
5237
* @psalm-return TXml
5338
*/
54-
static function (mixed $value) use ($innerIso, $context, $buildPath): mixed {
39+
static function (mixed $value) use ($innerIso, $context): mixed {
5540
try {
5641
return $innerIso->to($value);
5742
} catch (Throwable $exception) {
58-
throw EncodingException::encodingValue($value, $context->type, $exception, $buildPath());
43+
throw EncodingException::encodingValue($value, $context->type, $exception, self::buildPath($context));
5944
}
6045
},
6146
/**
6247
* @psalm-param TXml $value
6348
* @psalm-return TData
6449
*/
65-
static function (mixed $value) use ($innerIso, $context, $buildPath): mixed {
50+
static function (mixed $value) use ($innerIso, $context): mixed {
6651
try {
6752
return $innerIso->from($value);
6853
} catch (Throwable $exception) {
69-
throw EncodingException::decodingValue($value, $context->type, $exception, $buildPath());
54+
throw EncodingException::decodingValue($value, $context->type, $exception, self::buildPath($context));
7055
}
7156
}
7257
);
7358
}
59+
60+
private static function buildPath(Context $context): ?string
61+
{
62+
$meta = $context->type->getMeta();
63+
$isElement = $meta->isElement()->unwrapOr(false);
64+
$isAttribute = $meta->isAttribute()->unwrapOr(false);
65+
if (!$isElement && !$isAttribute) {
66+
return null;
67+
}
68+
69+
$path = $context->type->getXmlTargetNodeName();
70+
if ($isAttribute) {
71+
return '@' . $path;
72+
}
73+
74+
return $path;
75+
}
7476
}

src/Encoder/ObjectEncoder.php

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

66
use Closure;
7+
use Exception;
78
use Soap\Encoding\Normalizer\PhpPropertyNameNormalizer;
89
use Soap\Encoding\TypeInference\ComplexTypeBuilder;
910
use Soap\Encoding\TypeInference\XsiTypeDetector;
@@ -13,7 +14,7 @@
1314
use Soap\Encoding\Xml\Writer\XsdTypeXmlElementWriter;
1415
use Soap\Encoding\Xml\Writer\XsiAttributeBuilder;
1516
use Soap\Engine\Metadata\Model\Property;
16-
use Soap\Engine\Metadata\Model\XsdType;
17+
use Soap\Engine\Metadata\Model\TypeMeta;
1718
use VeeWee\Reflecta\Iso\Iso;
1819
use VeeWee\Reflecta\Lens\Lens;
1920
use function is_array;
@@ -100,30 +101,27 @@ private function to(Context $context, array $properties, object|array $data): st
100101
$properties,
101102
function (Property $property) use ($context, $data, $defaultAction) : Closure {
102103
$type = $property->getType();
103-
$lens = $this->decorateLensForType(
104+
$meta = $type->getMeta();
105+
$isAttribute = $meta->isAttribute()->unwrapOr(false);
106+
107+
/** @var mixed $value */
108+
$value = $this->runLens(
104109
property(PhpPropertyNameNormalizer::normalize($property->getName())),
105-
$type
110+
$meta,
111+
$data,
112+
null
106113
);
107-
/**
108-
* @psalm-var mixed $value
109-
* @psalm-suppress PossiblyInvalidArgument - Psalm gets lost in the lens.
110-
*/
111-
$value = $lens
112-
->tryGet($data)
113-
->catch(static fn () => null)
114-
->getResult();
115-
116-
return $this->handleProperty(
117-
$property,
118-
onAttribute: fn (): Closure => $value ? (new AttributeBuilder(
114+
115+
return match(true) {
116+
$isAttribute => $value ? (new AttributeBuilder(
119117
$type,
120118
$this->grabIsoForProperty($context, $property)->to($value)
121119
))(...) : $defaultAction,
122-
onValue: fn (): Closure => $value
120+
$property->getName() === '_' => $value
123121
? buildValue($this->grabIsoForProperty($context, $property)->to($value))
124122
: (new NilAttributeBuilder())(...),
125-
onElements: fn (): Closure => $value ? raw($this->grabIsoForProperty($context, $property)->to($value)) : $defaultAction,
126-
);
123+
default => $value ? raw($this->grabIsoForProperty($context, $property)->to($value)) : $defaultAction
124+
};
127125
}
128126
)
129127
]
@@ -149,23 +147,21 @@ private function from(Context $context, array $properties, string $data): object
149147
function (Property $property) use ($context, $nodes): mixed {
150148
$type = $property->getType();
151149
$meta = $type->getMeta();
152-
$isList = $meta->isList()->unwrapOr(false);
153-
/** @psalm-var string|null $value */
154-
$value = $this->decorateLensForType(
150+
151+
/** @var string|null $value */
152+
$value = $this->runLens(
155153
index($property->getName()),
156-
$type
157-
)
158-
->tryGet($nodes)
159-
->catch(static fn () => null)
160-
->getResult();
161-
$defaultValue = $isList ? [] : null;
162-
163-
return $this->handleProperty(
164-
$property,
165-
onAttribute: fn (): mixed => /** @psalm-suppress PossiblyNullArgument */$this->grabIsoForProperty($context, $property)->from($value),
166-
onValue: fn (): mixed => $value !== null ? $this->grabIsoForProperty($context, $property)->from($value) : $defaultValue,
167-
onElements: fn (): mixed => $value !== null ? $this->grabIsoForProperty($context, $property)->from($value) : $defaultValue,
154+
$meta,
155+
$nodes,
156+
null
168157
);
158+
$defaultValue = $meta->isList()->unwrapOr(false) ? [] : null;
159+
160+
/** @psalm-suppress PossiblyNullArgument */
161+
return match(true) {
162+
$meta->isAttribute()->unwrapOr(false) => $this->grabIsoForProperty($context, $property)->from($value),
163+
default => $value !== null ? $this->grabIsoForProperty($context, $property)->from($value) : $defaultValue,
164+
};
169165
},
170166
static fn (Property $property) => PhpPropertyNameNormalizer::normalize($property->getName()),
171167
)
@@ -183,27 +179,14 @@ private function grabIsoForProperty(Context $context, Property $property): Iso
183179
return $encoder->iso($propertyContext);
184180
}
185181

186-
/**
187-
* @template X
188-
*
189-
* @param Closure(): X $onAttribute
190-
* @param Closure(): X $onValue
191-
* @param Closure(): X $onElements
192-
* @return X
193-
*/
194-
private function handleProperty(
195-
Property $property,
196-
Closure $onAttribute,
197-
Closure $onValue,
198-
Closure $onElements,
199-
) {
200-
$meta = $property->getType()->getMeta();
201-
202-
return match(true) {
203-
$meta->isAttribute()->unwrapOr(false) => $onAttribute(),
204-
$property->getName() === '_' => $onValue(),
205-
default => $onElements()
206-
};
182+
private function runLens(Lens $lens, TypeMeta $meta, mixed $data, mixed $default): mixed
183+
{
184+
try {
185+
/** @var mixed */
186+
return $this->decorateLensForType($lens, $meta)->get($data);
187+
} catch (Exception $e) {
188+
return $default;
189+
}
207190
}
208191

209192
/**
@@ -214,9 +197,8 @@ private function handleProperty(
214197
*
215198
* @return Lens<S, A>
216199
*/
217-
private function decorateLensForType(Lens $lens, XsdType $type): Lens
200+
private function decorateLensForType(Lens $lens, TypeMeta $meta): Lens
218201
{
219-
$meta = $type->getMeta();
220202
if ($meta->isNullable()->unwrapOr(false)) {
221203
return optional($lens);
222204
}
@@ -237,14 +219,13 @@ private function decorateLensForType(Lens $lens, XsdType $type): Lens
237219
private function detectProperties(Context $context): array
238220
{
239221
$type = (new ComplexTypeBuilder())($context);
240-
$properties = reindex(
222+
223+
return reindex(
241224
sort_by(
242225
$type->getProperties(),
243226
static fn (Property $property): bool => !$property->getType()->getMeta()->isAttribute()->unwrapOr(false),
244227
),
245228
static fn (Property $property): string => $property->getName(),
246229
);
247-
248-
return $properties;
249230
}
250231
}

src/Encoder/OptionalElementEncoder.php

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,16 @@ public function iso(Context $context): Iso
3232
$meta = $type->getMeta();
3333
$elementIso = $this->elementEncoder->iso($context);
3434

35-
$isNullable = $meta->isNullable()->unwrapOr(false);
36-
if (!$isNullable) {
35+
if (!$meta->isNullable()->unwrapOr(false)) {
3736
return $elementIso;
3837
}
3938

40-
$isNillable = $meta->isNil()->unwrapOr(false);
41-
$elementIso = $this->elementEncoder->iso($context);
42-
4339
return new Iso(
4440
/**
4541
* @param T|null $raw
4642
*/
4743
static fn (mixed $raw): string => match (true) {
48-
$raw === null && $isNillable => (new XsdTypeXmlElementWriter())($context, new NilAttributeBuilder()),
44+
$raw === null && $meta->isNil()->unwrapOr(false) => (new XsdTypeXmlElementWriter())($context, new NilAttributeBuilder()),
4945
$raw === null => '',
5046
default => $elementIso->to($raw),
5147
},

src/Encoder/SimpleType/EncoderDetector.php

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
use Soap\Encoding\Encoder\Feature;
99
use Soap\Encoding\Encoder\OptionalElementEncoder;
1010
use Soap\Encoding\Encoder\XmlEncoder;
11-
use Soap\Encoding\Exception\InvalidArgumentException;
1211
use Soap\Engine\Metadata\Model\XsdType;
1312
use function Psl\Iter\any;
1413

@@ -22,10 +21,6 @@ public function __invoke(Context $context): XmlEncoder
2221
$type = $context->type;
2322
$meta = $type->getMeta();
2423

25-
if (!$meta->isSimple()->unwrapOr(false)) {
26-
throw new InvalidArgumentException('Unable to detect a complex type in the simple type detector');
27-
}
28-
2924
$encoder = $this->detectSimpleTypeEncoder($type, $context);
3025
if (!$encoder instanceof Feature\ListAware && $this->detectIsListType($type)) {
3126
$encoder = new SimpleListEncoder($encoder);

src/Exception/InvalidArgumentException.php

Lines changed: 0 additions & 8 deletions
This file was deleted.

src/Restriction/WhitespaceRestriction.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public static function parseForContext(Context $context, string $value): string
2424
return match ($whitespace) {
2525
self::REPLACE => self::replace($value),
2626
self::COLLAPSE => self::collapse($value),
27-
default => self::preserve($value),
27+
default => $value,
2828
};
2929
}
3030

0 commit comments

Comments
 (0)