Skip to content

Commit

Permalink
Test : iso-less speed
Browse files Browse the repository at this point in the history
  • Loading branch information
veewee committed Jun 5, 2024
1 parent 52240d2 commit f25759d
Show file tree
Hide file tree
Showing 27 changed files with 357 additions and 64 deletions.
10 changes: 8 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"php-soap/wsdl": "^1.6",
"php-soap/xml": "^1.6",
"php-soap/wsdl-reader": "0.14.0",
"goetas-webservices/xsd-reader": "^0.4.5"
"goetas-webservices/xsd-reader": "dev-merged-prs as 0.4.5"
},
"require-dev": {
"vimeo/psalm": "^5.16",
Expand All @@ -43,5 +43,11 @@
"allow-plugins": {
"php-http/discovery": true
}
}
},
"repositories": [
{
"type": "path",
"url": "../xsd-reader"
}
]
}
4 changes: 2 additions & 2 deletions src/Decoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ public function decode(string $method, SoapResponse $response): mixed

return match(count($parts)) {
0 => null,
1 => $decoder->iso($context)->from($parts[0]),
default => map($parts, $decoder->iso($context)->from(...)),
1 => $decoder->from($context, $parts[0]),
default => map($parts, static fn (string $part) => $decoder->from($context, $part)),
};
}
}
2 changes: 1 addition & 1 deletion src/Encoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public function encode(string $method, array $arguments): SoapRequest
$context = new Context($type, $this->metadata, $this->registry, $this->namespaces, $bindingUse);
$argument = index($index)->get($arguments);

$request[] = $this->registry->detectEncoderForContext($context)->iso($context)->to($argument);
$request[] = $this->registry->detectEncoderForContext($context)->to($context, $argument);
}

$operation = new OperationBuilder($meta, $this->namespaces, $request);
Expand Down
17 changes: 17 additions & 0 deletions src/Encoder/ElementEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,21 @@ public function iso(Context $context): Iso
)
);
}

public function to(Context $context, mixed $value)
{
return (new XsdTypeXmlElementWriter())(
$context,
(new ElementValueBuilder($context, $this->typeEncoder, $value))
);
}

public function from(Context $context, mixed $value)
{
return (new ElementValueReader())(
$context,
$this->typeEncoder,
Document::fromXmlString($value)->locateDocumentElement(),
);
}
}
30 changes: 16 additions & 14 deletions src/Encoder/ObjectEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ function (string $value) use ($context, $properties) : object {
);
}

/**
* @param array<string, Property> $properties
*/
private function to(Context $context, array $properties, object|array $data): string
public function to(Context $context, mixed $data): string
{
invariant((bool)$context->type->getXmlNamespace(), 'TODO : Expecting a namespace for now');
$properties = $this->detectProperties($context);

if (is_array($data)) {
$data = (object) $data;
}
Expand Down Expand Up @@ -95,12 +95,12 @@ function (Property $property) use ($context, $data, $defaultAction) : Closure {
onAttribute: fn (): Closure => $value ? (new AttributeBuilder(
$context,
$type,
$this->grabIsoForProperty($context, $property)->to($value)
$this->grabEncoderForProperty($context, $property)->to($context->withType($property->getType()), $value)
))(...) : $defaultAction,
onValue: fn (): Closure => $value
? buildValue($this->grabIsoForProperty($context, $property)->to($value))
? buildValue($this->grabEncoderForProperty($context, $property)->to($context->withType($property->getType()), $value))
: (new NilAttributeBuilder())(...),
onElements: fn (): Closure => $value ? raw($this->grabIsoForProperty($context, $property)->to($value)) : $defaultAction,
onElements: fn (): Closure => $value ? raw($this->grabEncoderForProperty($context, $property)->to($context->withType($property->getType()), $value)) : $defaultAction,
);
}
)
Expand All @@ -112,8 +112,11 @@ function (Property $property) use ($context, $data, $defaultAction) : Closure {
/**
* @param array<string, Property> $properties
*/
private function from(Context $context, array $properties, string $data): object
public function from(Context $context, mixed $data): object
{
invariant((bool)$context->type->getXmlNamespace(), 'TODO : Expecting a namespace for now');
$properties = $this->detectProperties($context);

$nodes = (new DocumentToLookupArrayReader())($data);

return object_data($this->className)->from(
Expand All @@ -134,21 +137,20 @@ function (Property $property) use ($context, $nodes): mixed {

return $this->handleProperty(
$property,
onAttribute: fn (): mixed => $this->grabIsoForProperty($context, $property)->from($value),
onValue: fn (): mixed => $value !== null ? $this->grabIsoForProperty($context, $property)->from($value) : $defaultValue,
onElements: fn (): mixed => $value !== null ? $this->grabIsoForProperty($context, $property)->from($value) : $defaultValue,
onAttribute: fn (): mixed => $this->grabEncoderForProperty($context, $property)->from($context->withType($property->getType()), $value),
onValue: fn (): mixed => $value !== null ? $this->grabEncoderForProperty($context, $property)->from($context->withType($property->getType()), $value) : $defaultValue,
onElements: fn (): mixed => $value !== null ? $this->grabEncoderForProperty($context, $property)->from($context->withType($property->getType()), $value) : $defaultValue,
);
}
)
);
}

private function grabIsoForProperty(Context $context, Property $property): Iso
private function grabEncoderForProperty(Context $context, Property $property): XmlEncoder
{
$propertyContext = $context->withType($property->getType());
$encoder = $context->registry->detectEncoderForContext($propertyContext);

return $encoder->iso($propertyContext);
return $context->registry->detectEncoderForContext($propertyContext);
}

/**
Expand Down
42 changes: 42 additions & 0 deletions src/Encoder/OptionalElementEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,46 @@ static function (string $xml) use ($elementIso) : mixed {
}
);
}

public function to(Context $context, mixed $value)
{
$type = $context->type;
$meta = $type->getMeta();

$isNullable = $meta->isNullable()->unwrapOr(false);
if (!$isNullable) {
return $this->elementEncoder->to($context, $value);
}

$isNillable = $meta->isNil()->unwrapOr(false);

return match (true) {
$value === null && $isNillable => (new XsdTypeXmlElementWriter())($context, new NilAttributeBuilder()),
$value === null => '',
default => $this->elementEncoder->to($context, $value),
};
}

public function from(Context $context, mixed $value)
{
$type = $context->type;
$meta = $type->getMeta();

$isNullable = $meta->isNullable()->unwrapOr(false);
if (!$isNullable) {
return $this->elementEncoder->from($context, $value);
}


if ($value === '') {
return null;
}

$documentElement = Document::fromXmlString($value)->locateDocumentElement();
if ($documentElement->getAttributeNS(Xmlns::xsi()->value(), 'nil') === 'true') {
return null;
}

return $this->elementEncoder->from($context, $value);
}
}
34 changes: 34 additions & 0 deletions src/Encoder/RepeatingElementEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,38 @@ static function (string $xml) use ($innerIso): iterable {
}
);
}

public function to(Context $context, mixed $raw)
{
$type = $context->type;

return join(
map(
$raw,
fn (mixed $item): string => $this->typeEncoder->to(
$context->withType(
$type->withMeta(static fn (TypeMeta $meta): TypeMeta => $meta->withIsList(false))
),
$item
)
),
''
);
}

public function from(Context $context, mixed $xml)
{
$type = $context->type;

$doc = Document::fromXmlString('<list>'.$xml.'</list>');

return readChildren($doc->locateDocumentElement())->map(
fn (DOMElement $element): mixed => $this->typeEncoder->from(
$context->withType(
$type->withMeta(static fn (TypeMeta $meta): TypeMeta => $meta->withIsList(false))
),
$doc->stringifyNode($element)
)
);
}
}
23 changes: 6 additions & 17 deletions src/Encoder/SimpleType/AttributeValueEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
use RuntimeException;
use Soap\Encoding\Encoder\Context;
use Soap\Encoding\Encoder\XmlEncoder;
use VeeWee\Reflecta\Iso\Iso;

/**
* @implements XmlEncoder<string|null, mixed>
Expand All @@ -21,41 +20,31 @@ public function __construct(
) {
}

/**
* @return Iso<string, mixed>
*/
public function iso(Context $context): Iso
{
return (new Iso(
fn (mixed $value): ?string => $this->to($context, $value),
fn (?string $value): mixed => $this->from($context, $value),
));
}

public function to(Context $context, mixed $value): ?string
{
$meta = $context->type->getMeta();
$fixed = $meta->fixed()
->map(fn (string $fixed): mixed => $this->typeEncoder->iso($context)->from($fixed))
->map(fn (string $fixed): mixed => $this->typeEncoder->from($context, $fixed))
->unwrapOr(null);

if ($fixed !== null && $value !== $fixed) {
// TODO custom exception
throw new RuntimeException(sprintf('Provided attribute value should be fixed to %s. Got %s', $fixed, $value));
}

return $value ? $this->typeEncoder->iso($context)->to($value) : null;
return $value ? $this->typeEncoder->to($context, $value) : null;
}

public function from(Context $context, ?string $value): mixed

public function from(Context $context, mixed $value): mixed
{
if ($value !== null) {
return $this->typeEncoder->iso($context)->from($value);
return $this->typeEncoder->from($context, $value);
}

$meta = $context->type->getMeta();
$default = $meta->fixed()->or($meta->default())->unwrapOr(null);

return $default ? $this->typeEncoder->iso($context)->from($default) : null;
return $default ? $this->typeEncoder->from($context, $default) : null;
}
}
11 changes: 11 additions & 0 deletions src/Encoder/SimpleType/BackedEnumTypeEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,17 @@ public function __construct(
) {
}

public function to(Context $context, mixed $value)
{
return $value->value;
}

public function from(Context $context, mixed $value)
{
return backed_enum($this->enumClass)->coerce($value);
}


public function iso(Context $context): Iso
{
return (new Iso(
Expand Down
12 changes: 12 additions & 0 deletions src/Encoder/SimpleType/Base64BinaryTypeEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,16 @@ public function iso(Context $context): Iso
static fn (string $value): string => WhitespaceRestriction::collapse(base64_decode($value, true)),
));
}

public function to(Context $context, mixed $value)
{
return base64_encode($value);
}

public function from(Context $context, mixed $value)
{
return WhitespaceRestriction::collapse(base64_decode($value, true));
}


}
10 changes: 10 additions & 0 deletions src/Encoder/SimpleType/BoolTypeEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,14 @@ public function iso(Context $context): Iso
static fn (string $value): bool => $value === 'true',
));
}

public function to(Context $context, mixed $value)
{
return $value ? 'true' : 'false';
}

public function from(Context $context, mixed $value)
{
return $value === 'true';
}
}
10 changes: 10 additions & 0 deletions src/Encoder/SimpleType/DateTimeTypeEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,14 @@ public function iso(Context $context): Iso
static fn (string $value): DateTimeInterface => new DateTimeImmutable($value)
));
}

public function to(Context $context, mixed $value)
{
return $value->format(self::DATE_FORMAT);
}

public function from(Context $context, mixed $value)
{
return new DateTimeImmutable($value);
}
}
12 changes: 12 additions & 0 deletions src/Encoder/SimpleType/DateTypeEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,16 @@ public function iso(Context $context): Iso
static fn (string $value): DateTimeInterface => (new DateTimeImmutable($value))->setTime(0, 0),
));
}

public function to(Context $context, mixed $value)
{
return $value->format(self::DATE_FORMAT);
}

public function from(Context $context, mixed $value)
{
return (new DateTimeImmutable($value))->setTime(0, 0);
}


}
12 changes: 12 additions & 0 deletions src/Encoder/SimpleType/FloatTypeEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,16 @@ public function iso(Context $context): Iso
static fn (string $value): float => float()->coerce($value),
));
}

public function to(Context $context, mixed $value)
{
return numeric_string()->coerce($value);
}

public function from(Context $context, mixed $value)
{
return float()->coerce($value);
}


}
12 changes: 12 additions & 0 deletions src/Encoder/SimpleType/HexBinaryTypeEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,16 @@ public function iso(Context $context): Iso
static fn (string $value): string => WhitespaceRestriction::collapse(hex2bin($value)),
));
}

public function to(Context $context, mixed $value)
{
return mb_strtoupper(bin2hex($value));
}

public function from(Context $context, mixed $value)
{
return WhitespaceRestriction::collapse(hex2bin($value));
}


}
Loading

0 comments on commit f25759d

Please sign in to comment.