Skip to content

Commit fcfdb46

Browse files
committed
* Removed RuntimeEvaluationConfig
* Feature Flags moved to Draft
1 parent 26bb980 commit fcfdb46

File tree

51 files changed

+426
-207
lines changed

Some content is hidden

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

51 files changed

+426
-207
lines changed

src/Draft/AbstractDraft.php

Lines changed: 100 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use GuzzleHttp\Psr7\UriNormalizer;
88
use GuzzleHttp\Psr7\UriResolver;
99
use Psr\Http\Message\UriInterface;
10+
use Ropi\JsonSchemaEvaluator\Draft\Exception\UnsupportedVocabularyException;
1011
use Ropi\JsonSchemaEvaluator\EvaluationContext\RuntimeEvaluationContext;
1112
use Ropi\JsonSchemaEvaluator\EvaluationContext\StaticEvaluationContext;
1213
use Ropi\JsonSchemaEvaluator\Draft\Exception\InvalidSchemaException;
@@ -15,8 +16,8 @@
1516
use Ropi\JsonSchemaEvaluator\Keyword\RuntimeKeywordInterface;
1617
use Ropi\JsonSchemaEvaluator\Keyword\StaticKeywordInterface;
1718
use Ropi\JsonSchemaEvaluator\Keyword\UnknownKeyword;
18-
use Ropi\JsonSchemaEvaluator\Type\BigNumber;
19-
use Ropi\JsonSchemaEvaluator\Type\BigNumberInterface;
19+
use Ropi\JsonSchemaEvaluator\Type\Number;
20+
use Ropi\JsonSchemaEvaluator\Type\NumberInterface;
2021

2122
abstract class AbstractDraft implements DraftInterface
2223
{
@@ -27,18 +28,104 @@ abstract class AbstractDraft implements DraftInterface
2728
private int $lastPriority = 0;
2829

2930
/**
30-
* @var string[]
31+
* @var bool[]
3132
*/
32-
protected const VOCABULARIES = [];
33+
protected array $vocabularies = [];
34+
35+
public function __construct(
36+
private string $uri = '',
37+
private bool $assertFormat = false,
38+
private bool $assertContentMediaTypeEncoding = false,
39+
private bool $evaluateMutations = false,
40+
private bool $acceptNumericStrings = false,
41+
private bool $shortCircuit = false
42+
) {}
43+
44+
public function getUri(): string
45+
{
46+
return $this->uri;
47+
}
48+
49+
public function assertFormat(): bool
50+
{
51+
return $this->assertFormat;
52+
}
53+
54+
public function assertContentMediaTypeEncoding(): bool
55+
{
56+
return $this->assertContentMediaTypeEncoding;
57+
}
58+
59+
public function evaluateMutations(): bool
60+
{
61+
return $this->evaluateMutations;
62+
}
63+
64+
public function acceptNumericStrings(): bool
65+
{
66+
return $this->acceptNumericStrings;
67+
}
68+
69+
public function shortCircuit(): bool
70+
{
71+
return $this->shortCircuit;
72+
}
3373

3474
public function supportsVocabulary(string $vocabulary): bool
3575
{
36-
return isset(static::VOCABULARIES[$vocabulary]) && static::VOCABULARIES[$vocabulary];
76+
return isset($this->vocabularies[$vocabulary]);
77+
}
78+
79+
public function getSupportedVocabularies(): array
80+
{
81+
return array_keys($this->vocabularies);
3782
}
3883

3984
public function getVocabularies(): array
4085
{
41-
return static::VOCABULARIES;
86+
return $this->vocabularies;
87+
}
88+
89+
public function vocabularyEnabled(string $vocabulary): bool
90+
{
91+
if (!$this->supportsVocabulary($vocabulary)) {
92+
throw new UnsupportedVocabularyException(
93+
'Can not enable vocabulary "'
94+
. $vocabulary
95+
. '", because vocabulary is not supported',
96+
1647637917
97+
);
98+
}
99+
100+
return $this->vocabularies[$vocabulary];
101+
}
102+
103+
public function enableVocabulary(string $vocabulary): void
104+
{
105+
if (!$this->supportsVocabulary($vocabulary)) {
106+
throw new UnsupportedVocabularyException(
107+
'Can not enable vocabulary "'
108+
. $vocabulary
109+
. '", because vocabulary is not supported',
110+
1647637758
111+
);
112+
}
113+
114+
$this->vocabularies[$vocabulary] = true;
115+
}
116+
117+
public function disableVocabulary(string $vocabulary): void
118+
{
119+
if (!$this->supportsVocabulary($vocabulary)) {
120+
throw new UnsupportedVocabularyException(
121+
'Can not disable vocabulary "'
122+
. $vocabulary
123+
. '", because vocabulary is not supported',
124+
1647637759
125+
);
126+
}
127+
128+
$this->vocabularies[$vocabulary] = false;
42129
}
43130

44131
public function registerKeyword(KeywordInterface $keyword): void
@@ -117,7 +204,7 @@ public function evaluate(RuntimeEvaluationContext $context, bool $mutationsOnly
117204
}
118205

119206
$lastResultNumber = $context->getLastResultNumber();
120-
$shortCircuit = $context->config->shortCircuit;
207+
$shortCircuit = $context->draft->shortCircuit();
121208
$valid = true;
122209

123210
foreach ($context->staticEvaluationContext->getPrioritizedSchemaKeywords($schema) as $keyword) {
@@ -209,14 +296,14 @@ public function dereferenceJsonPointer(object $schema, string $fragment): mixed
209296
return $currentSchemaPart;
210297
}
211298

212-
public function createBigNumber(mixed $value, bool $acceptNumericStrings = false): ?BigNumberInterface
299+
public function createNumber(mixed $value): ?NumberInterface
213300
{
214-
if ($value instanceof BigNumberInterface) {
301+
if ($value instanceof NumberInterface) {
215302
return clone $value;
216303
}
217304

218305
if (!is_int($value) && !is_float($value)) {
219-
if ($acceptNumericStrings) {
306+
if ($this->acceptNumericStrings()) {
220307
if (!is_string($value) || !is_numeric($value)) {
221308
return null;
222309
}
@@ -226,7 +313,7 @@ public function createBigNumber(mixed $value, bool $acceptNumericStrings = false
226313
}
227314

228315
try {
229-
return new BigNumber(sprintf('%f', $value));
316+
return new Number(sprintf('%f', $value));
230317
} catch (\InvalidArgumentException) {
231318
// Instance is not a number
232319
}
@@ -236,13 +323,13 @@ public function createBigNumber(mixed $value, bool $acceptNumericStrings = false
236323

237324
public function valueIsNumeric(mixed $value): bool
238325
{
239-
return is_int($value) || is_float($value) || $value instanceof BigNumberInterface;
326+
return is_int($value) || is_float($value) || $value instanceof NumberInterface;
240327
}
241328

242329
public function valuesAreEqual(mixed $value1, mixed $value2): bool
243330
{
244331
if ($this->valueIsNumeric($value1) && $this->valueIsNumeric($value2)) {
245-
return $this->createBigNumber($value1)->equals($this->createBigNumber($value2));
332+
return $this->createNumber($value1)->equals($this->createNumber($value2));
246333
}
247334

248335
if (gettype($value1) !== gettype($value2)) {

src/Draft/Draft202012.php

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -63,26 +63,39 @@
6363

6464
class Draft202012 extends AbstractDraft
6565
{
66-
protected const URI = 'https://json-schema.org/draft/2020-12/schema';
67-
68-
protected const VOCABULARIES = [
66+
protected array $vocabularies = [
6967
'https://json-schema.org/draft/2020-12/vocab/core' => true,
7068
'https://json-schema.org/draft/2020-12/vocab/applicator' => true,
7169
'https://json-schema.org/draft/2020-12/vocab/unevaluated' => true,
7270
'https://json-schema.org/draft/2020-12/vocab/validation' => true,
7371
'https://json-schema.org/draft/2020-12/vocab/meta-data' => true,
7472
'https://json-schema.org/draft/2020-12/vocab/format-annotation' => true,
75-
'https://json-schema.org/draft/2020-12/vocab/format-assertion' => true,
73+
'https://json-schema.org/draft/2020-12/vocab/format-assertion' => false,
7674
'https://json-schema.org/draft/2020-12/vocab/content' => true,
7775
];
7876

79-
public function getUri(): string
80-
{
81-
return static::URI;
82-
}
77+
public function __construct(
78+
string $uri = 'https://json-schema.org/draft/2020-12/schema',
79+
bool $assertFormat = false,
80+
bool $assertContentMediaTypeEncoding = false,
81+
bool $evaluateMutations = false,
82+
bool $acceptNumericStrings = false,
83+
bool $shortCircuit = false
84+
) {
85+
parent::__construct(
86+
$uri,
87+
$assertFormat,
88+
$assertContentMediaTypeEncoding,
89+
$evaluateMutations,
90+
$acceptNumericStrings,
91+
$shortCircuit
92+
);
93+
94+
if ($assertFormat) {
95+
/** @noinspection PhpUnhandledExceptionInspection */
96+
$this->enableVocabulary('https://json-schema.org/draft/2020-12/vocab/format-annotation');
97+
}
8398

84-
public function __construct()
85-
{
8699
// Core
87100
$this->registerKeyword(new SchemaKeyword());
88101
$this->registerKeyword(new VocabularyKeyword());
@@ -157,4 +170,10 @@ public function __construct()
157170
$this->registerKeyword(new WriteOnlyKeyword());
158171
$this->registerKeyword(new ExamplesKeyword());
159172
}
173+
174+
public function assertFormat(): bool
175+
{
176+
/** @noinspection PhpUnhandledExceptionInspection */
177+
return $this->vocabularyEnabled('https://json-schema.org/draft/2020-12/vocab/format-annotation');
178+
}
160179
}

src/Draft/DraftInterface.php

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44
namespace Ropi\JsonSchemaEvaluator\Draft;
55

66
use Psr\Http\Message\UriInterface;
7+
use Ropi\JsonSchemaEvaluator\Draft\Exception\UnsupportedVocabularyException;
78
use Ropi\JsonSchemaEvaluator\EvaluationContext\RuntimeEvaluationContext;
89
use Ropi\JsonSchemaEvaluator\EvaluationContext\StaticEvaluationContext;
910
use Ropi\JsonSchemaEvaluator\Draft\Exception\InvalidSchemaException;
1011
use Ropi\JsonSchemaEvaluator\Keyword\KeywordInterface;
11-
use Ropi\JsonSchemaEvaluator\Type\BigNumberInterface;
12+
use Ropi\JsonSchemaEvaluator\Type\NumberInterface;
1213

1314
interface DraftInterface
1415
{
@@ -17,8 +18,38 @@ function getKeywordByName(string $name): KeywordInterface;
1718
function schemaHasMutationKeywords(object|bool $schema): bool;
1819

1920
function supportsVocabulary(string $vocabulary): bool;
21+
22+
/**
23+
* @return string[]
24+
*/
25+
function getSupportedVocabularies(): array;
26+
27+
/**
28+
* @return bool[]
29+
*/
2030
function getVocabularies(): array;
2131

32+
/**
33+
* @throws UnsupportedVocabularyException
34+
*/
35+
function vocabularyEnabled(string $vocabulary): bool;
36+
37+
/**
38+
* @throws UnsupportedVocabularyException
39+
*/
40+
function enableVocabulary(string $vocabulary): void;
41+
42+
/**
43+
* @throws UnsupportedVocabularyException
44+
*/
45+
function disableVocabulary(string $vocabulary): void;
46+
47+
function assertFormat(): bool;
48+
function evaluateMutations(): bool;
49+
function assertContentMediaTypeEncoding(): bool;
50+
function shortCircuit(): bool;
51+
function acceptNumericStrings(): bool;
52+
2253
/**
2354
* @throws InvalidSchemaException
2455
* @throws \Ropi\JsonSchemaEvaluator\Keyword\Exception\StaticKeywordAnalysisException
@@ -32,7 +63,7 @@ function createUri(string $uri): ?UriInterface;
3263

3364
function dereferenceJsonPointer(object $schema, string $fragment): mixed;
3465

35-
function createBigNumber(mixed $value, bool $acceptNumericStrings = false): ?BigNumberInterface;
66+
function createNumber(mixed $value): ?NumberInterface;
3667
function valueIsNumeric(mixed $value): bool;
3768
function valuesAreEqual(mixed $value1, mixed $value2): bool;
3869
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Ropi\JsonSchemaEvaluator\Draft\Exception;
5+
6+
class UnsupportedVocabularyException extends DraftException
7+
{
8+
}

src/EvaluationConfig/RuntimeEvaluationConfig.php

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

src/EvaluationConfig/StaticEvaluationConfig.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,11 @@ class StaticEvaluationConfig
2020
* @param DraftInterface $defaultDraft
2121
* @param DraftInterface[] $supportedDrafts
2222
* @param SchemaPoolInterface|null $schemaPool
23-
* @param bool $acceptNumericStrings
2423
*/
2524
public function __construct(
2625
public /*readonly*/ DraftInterface $defaultDraft,
2726
array $supportedDrafts = [],
28-
?SchemaPoolInterface $schemaPool = null,
29-
public /*readonly*/ bool $acceptNumericStrings = false,
27+
?SchemaPoolInterface $schemaPool = null
3028
) {
3129
$this->supportedDrafts[$this->defaultDraft->getUri()] = $this->defaultDraft;
3230

src/EvaluationContext/RuntimeEvaluationContext.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
namespace Ropi\JsonSchemaEvaluator\EvaluationContext;
55

6-
use Ropi\JsonSchemaEvaluator\EvaluationConfig\RuntimeEvaluationConfig;
76
use Ropi\JsonSchemaEvaluator\Keyword\KeywordInterface;
87

98
class RuntimeEvaluationContext
@@ -25,7 +24,6 @@ class RuntimeEvaluationContext
2524
public function __construct(
2625
object|bool $schema,
2726
mixed &$instance,
28-
public /*readonly*/ RuntimeEvaluationConfig $config,
2927
public /*readonly*/ StaticEvaluationContext $staticEvaluationContext
3028
) {
3129
$this->schemaStack[0] = [

0 commit comments

Comments
 (0)