Implemented deterministic Baseline Result Semantics (Spec 383), introducing CompareSubjectResult and CompareEvidenceResult. Replaced generic arrays with strict Data Transfer Objects for Baseline engine output. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #454
114 lines
3.1 KiB
PHP
114 lines
3.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Support\Baselines\CompareSemantics;
|
|
|
|
use Illuminate\Contracts\Support\Arrayable;
|
|
use JsonSerializable;
|
|
|
|
/**
|
|
* @implements Arrayable<string, mixed>
|
|
*/
|
|
final readonly class CompareSubjectOutcome implements Arrayable, JsonSerializable
|
|
{
|
|
/**
|
|
* @param array<string, mixed> $subject
|
|
* @param array<string, mixed> $proof
|
|
*/
|
|
public function __construct(
|
|
public CompareResultReason $reason,
|
|
public CompareResultCategory $category,
|
|
public CompareResultActionability $actionability,
|
|
public CompareResultReadinessImpact $readinessImpact,
|
|
public CompareResultIdentityStatus $identityStatus,
|
|
public CompareResultComparisonStatus $comparisonStatus,
|
|
public CompareResultCoverageStatus $coverageStatus,
|
|
public CompareResultTrustLevel $trustLevel,
|
|
public array $subject = [],
|
|
public array $proof = [],
|
|
) {}
|
|
|
|
public function isBlocking(): bool
|
|
{
|
|
return in_array($this->readinessImpact, [
|
|
CompareResultReadinessImpact::CustomerBlocker,
|
|
CompareResultReadinessImpact::InternalBlocker,
|
|
], true);
|
|
}
|
|
|
|
public function toArray(): array
|
|
{
|
|
return [
|
|
'reason' => $this->reason->value,
|
|
'category' => $this->category->value,
|
|
'actionability' => $this->actionability->value,
|
|
'readiness_impact' => $this->readinessImpact->value,
|
|
'identity_status' => $this->identityStatus->value,
|
|
'comparison_status' => $this->comparisonStatus->value,
|
|
'coverage_status' => $this->coverageStatus->value,
|
|
'trust_level' => $this->trustLevel->value,
|
|
'subject' => $this->safeArray($this->subject),
|
|
'proof' => $this->safeArray($this->proof),
|
|
];
|
|
}
|
|
|
|
public function jsonSerialize(): array
|
|
{
|
|
return $this->toArray();
|
|
}
|
|
|
|
/**
|
|
* @param array<array-key, mixed> $value
|
|
* @return array<array-key, mixed>
|
|
*/
|
|
private function safeArray(array $value, bool $topLevel = true): array
|
|
{
|
|
$safe = [];
|
|
|
|
foreach ($value as $key => $item) {
|
|
if (! $this->isSafeArrayKey($key, $topLevel)) {
|
|
continue;
|
|
}
|
|
|
|
$safe[$key] = $this->safeValue($item);
|
|
}
|
|
|
|
return $safe;
|
|
}
|
|
|
|
private function safeValue(mixed $value): mixed
|
|
{
|
|
if (is_scalar($value) || $value === null) {
|
|
return $value;
|
|
}
|
|
|
|
if (is_array($value)) {
|
|
return $this->safeArray($value, false);
|
|
}
|
|
|
|
if ($value instanceof \Stringable) {
|
|
return (string) $value;
|
|
}
|
|
|
|
if (is_object($value)) {
|
|
return get_debug_type($value);
|
|
}
|
|
|
|
if (is_resource($value)) {
|
|
return 'resource:'.get_resource_type($value);
|
|
}
|
|
|
|
return get_debug_type($value);
|
|
}
|
|
|
|
private function isSafeArrayKey(string|int $key, bool $topLevel): bool
|
|
{
|
|
if (is_string($key)) {
|
|
return $key !== '';
|
|
}
|
|
|
|
return ! $topLevel;
|
|
}
|
|
}
|