Skip to content

Commit b847dfd

Browse files
committed
perf: use type guards to avoid descending into nodes
Signed-off-by: Dmitry Dygalo <dmitry@dygalo.dev>
1 parent 5f2e617 commit b847dfd

21 files changed

+321
-20
lines changed

crates/jsonschema/src/keywords/boolean.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use crate::paths::{LazyLocation, Location};
22

3-
use crate::{error::ValidationError, keywords::CompilationResult, validator::Validate};
3+
use crate::{
4+
error::ValidationError, keywords::CompilationResult, types::JsonTypeSet, validator::Validate,
5+
};
46
use serde_json::Value;
57

68
pub(crate) struct FalseValidator {
@@ -28,6 +30,10 @@ impl Validate for FalseValidator {
2830
instance,
2931
))
3032
}
33+
34+
fn applicable_types(&self) -> JsonTypeSet {
35+
JsonTypeSet::empty()
36+
}
3137
}
3238

3339
#[cfg(test)]

crates/jsonschema/src/keywords/const_.rs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
use crate::{
2-
compiler, error::ValidationError, ext::cmp, keywords::CompilationResult, paths::Location,
2+
compiler,
3+
error::ValidationError,
4+
ext::cmp,
5+
keywords::CompilationResult,
6+
paths::Location,
7+
types::{JsonType, JsonTypeSet},
38
validator::Validate,
49
};
510
use serde_json::{Map, Number, Value};
@@ -45,6 +50,10 @@ impl Validate for ConstArrayValidator {
4550
false
4651
}
4752
}
53+
54+
fn applicable_types(&self) -> JsonTypeSet {
55+
JsonTypeSet::empty().insert(JsonType::Array)
56+
}
4857
}
4958

5059
struct ConstBooleanValidator {
@@ -83,6 +92,10 @@ impl Validate for ConstBooleanValidator {
8392
false
8493
}
8594
}
95+
96+
fn applicable_types(&self) -> JsonTypeSet {
97+
JsonTypeSet::empty().insert(JsonType::Boolean)
98+
}
8699
}
87100

88101
struct ConstNullValidator {
@@ -114,6 +127,10 @@ impl Validate for ConstNullValidator {
114127
fn is_valid(&self, instance: &Value) -> bool {
115128
instance.is_null()
116129
}
130+
131+
fn applicable_types(&self) -> JsonTypeSet {
132+
JsonTypeSet::empty().insert(JsonType::Null)
133+
}
117134
}
118135

119136
struct ConstNumberValidator {
@@ -157,6 +174,14 @@ impl Validate for ConstNumberValidator {
157174
false
158175
}
159176
}
177+
178+
fn applicable_types(&self) -> JsonTypeSet {
179+
let mut set = JsonTypeSet::empty().insert(JsonType::Number);
180+
if self.original_value.is_i64() || self.original_value.is_u64() {
181+
set = set.insert(JsonType::Integer);
182+
}
183+
set
184+
}
160185
}
161186

162187
pub(crate) struct ConstObjectValidator {
@@ -198,6 +223,10 @@ impl Validate for ConstObjectValidator {
198223
false
199224
}
200225
}
226+
227+
fn applicable_types(&self) -> JsonTypeSet {
228+
JsonTypeSet::empty().insert(JsonType::Object)
229+
}
201230
}
202231

203232
pub(crate) struct ConstStringValidator {
@@ -239,6 +268,10 @@ impl Validate for ConstStringValidator {
239268
false
240269
}
241270
}
271+
272+
fn applicable_types(&self) -> JsonTypeSet {
273+
JsonTypeSet::empty().insert(JsonType::String)
274+
}
242275
}
243276

244277
#[inline]

crates/jsonschema/src/keywords/contains.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::{
44
keywords::CompilationResult,
55
node::SchemaNode,
66
paths::LazyLocation,
7+
types::JsonTypeSet,
78
validator::{PartialApplication, Validate},
89
Draft,
910
};
@@ -85,6 +86,10 @@ impl Validate for ContainsValidator {
8586
result
8687
}
8788
}
89+
90+
fn applicable_types(&self) -> JsonTypeSet {
91+
JsonTypeSet::arrays()
92+
}
8893
}
8994

9095
/// `minContains` validation. Used only if there is no `maxContains` present.
@@ -164,6 +169,10 @@ impl Validate for MinContainsValidator {
164169
true
165170
}
166171
}
172+
173+
fn applicable_types(&self) -> JsonTypeSet {
174+
JsonTypeSet::arrays()
175+
}
167176
}
168177

169178
/// `maxContains` validation. Used only if there is no `minContains` present.
@@ -247,6 +256,10 @@ impl Validate for MaxContainsValidator {
247256
true
248257
}
249258
}
259+
260+
fn applicable_types(&self) -> JsonTypeSet {
261+
JsonTypeSet::arrays()
262+
}
250263
}
251264

252265
/// `maxContains` & `minContains` validation combined.
@@ -333,6 +346,10 @@ impl Validate for MinMaxContainsValidator {
333346
true
334347
}
335348
}
349+
350+
fn applicable_types(&self) -> JsonTypeSet {
351+
JsonTypeSet::arrays()
352+
}
336353
}
337354

338355
#[inline]

crates/jsonschema/src/keywords/content.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::{
66
error::ValidationError,
77
keywords::CompilationResult,
88
paths::{LazyLocation, Location},
9-
types::JsonType,
9+
types::{JsonType, JsonTypeSet},
1010
validator::Validate,
1111
};
1212
use serde_json::{Map, Value};
@@ -63,6 +63,10 @@ impl Validate for ContentMediaTypeValidator {
6363
Ok(())
6464
}
6565
}
66+
67+
fn applicable_types(&self) -> JsonTypeSet {
68+
JsonTypeSet::strings()
69+
}
6670
}
6771

6872
/// Validator for `contentEncoding` keyword.
@@ -116,6 +120,10 @@ impl Validate for ContentEncodingValidator {
116120
Ok(())
117121
}
118122
}
123+
124+
fn applicable_types(&self) -> JsonTypeSet {
125+
JsonTypeSet::strings()
126+
}
119127
}
120128

121129
/// Combined validator for both `contentEncoding` and `contentMediaType` keywords.
@@ -190,6 +198,10 @@ impl Validate for ContentMediaTypeAndEncodingValidator {
190198
Ok(())
191199
}
192200
}
201+
202+
fn applicable_types(&self) -> JsonTypeSet {
203+
JsonTypeSet::strings()
204+
}
193205
}
194206

195207
#[inline]

crates/jsonschema/src/keywords/enum_.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ impl EnumValidator {
2727
) -> CompilationResult<'a> {
2828
let mut types = JsonTypeSet::empty();
2929
for item in items {
30-
types = types.insert(JsonType::from(item));
30+
types = types.union(JsonTypeSet::from_value(item));
3131
}
3232
Ok(Box::new(EnumValidator {
3333
options: schema.clone(),
@@ -66,13 +66,18 @@ impl Validate for EnumValidator {
6666
false
6767
}
6868
}
69+
70+
fn applicable_types(&self) -> JsonTypeSet {
71+
self.types
72+
}
6973
}
7074

7175
#[derive(Debug)]
7276
pub(crate) struct SingleValueEnumValidator {
7377
value: Value,
7478
options: Value,
7579
location: Location,
80+
types: JsonTypeSet,
7681
}
7782

7883
impl SingleValueEnumValidator {
@@ -86,6 +91,7 @@ impl SingleValueEnumValidator {
8691
options: schema.clone(),
8792
value: value.clone(),
8893
location,
94+
types: JsonTypeSet::from_value(value),
8995
}))
9096
}
9197
}
@@ -111,6 +117,10 @@ impl Validate for SingleValueEnumValidator {
111117
fn is_valid(&self, instance: &Value) -> bool {
112118
cmp::equal(&self.value, instance)
113119
}
120+
121+
fn applicable_types(&self) -> JsonTypeSet {
122+
self.types
123+
}
114124
}
115125

116126
#[inline]

crates/jsonschema/src/keywords/legacy/type_draft_4.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ impl Validate for MultipleTypesValidator {
6868
))
6969
}
7070
}
71+
72+
fn applicable_types(&self) -> JsonTypeSet {
73+
self.types
74+
}
7175
}
7276

7377
pub(crate) struct IntegerTypeValidator {
@@ -105,6 +109,10 @@ impl Validate for IntegerTypeValidator {
105109
))
106110
}
107111
}
112+
113+
fn applicable_types(&self) -> JsonTypeSet {
114+
JsonTypeSet::empty().insert(JsonType::Integer)
115+
}
108116
}
109117

110118
fn is_integer(num: &Number) -> bool {

crates/jsonschema/src/keywords/max_items.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::{
33
error::ValidationError,
44
keywords::{helpers::fail_on_non_positive_integer, CompilationResult},
55
paths::{LazyLocation, Location},
6+
types::JsonTypeSet,
67
validator::Validate,
78
};
89
use serde_json::{Map, Value};
@@ -65,6 +66,10 @@ impl Validate for MaxItemsValidator {
6566
}
6667
Ok(())
6768
}
69+
70+
fn applicable_types(&self) -> JsonTypeSet {
71+
JsonTypeSet::arrays()
72+
}
6873
}
6974

7075
#[inline]

crates/jsonschema/src/keywords/max_length.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::{
33
error::ValidationError,
44
keywords::{helpers::fail_on_non_positive_integer, CompilationResult},
55
paths::{LazyLocation, Location},
6+
types::JsonTypeSet,
67
validator::Validate,
78
};
89
use serde_json::{Map, Value};
@@ -65,6 +66,10 @@ impl Validate for MaxLengthValidator {
6566
}
6667
Ok(())
6768
}
69+
70+
fn applicable_types(&self) -> JsonTypeSet {
71+
JsonTypeSet::strings()
72+
}
6873
}
6974

7075
#[inline]

crates/jsonschema/src/keywords/max_properties.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::{
33
error::ValidationError,
44
keywords::{helpers::fail_on_non_positive_integer, CompilationResult},
55
paths::{LazyLocation, Location},
6+
types::JsonTypeSet,
67
validator::Validate,
78
};
89
use serde_json::{Map, Value};
@@ -65,6 +66,10 @@ impl Validate for MaxPropertiesValidator {
6566
}
6667
Ok(())
6768
}
69+
70+
fn applicable_types(&self) -> JsonTypeSet {
71+
JsonTypeSet::objects()
72+
}
6873
}
6974

7075
#[inline]

crates/jsonschema/src/keywords/min_items.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::{
33
error::ValidationError,
44
keywords::{helpers::fail_on_non_positive_integer, CompilationResult},
55
paths::{LazyLocation, Location},
6+
types::JsonTypeSet,
67
validator::Validate,
78
};
89
use serde_json::{Map, Value};
@@ -65,6 +66,10 @@ impl Validate for MinItemsValidator {
6566
}
6667
Ok(())
6768
}
69+
70+
fn applicable_types(&self) -> JsonTypeSet {
71+
JsonTypeSet::arrays()
72+
}
6873
}
6974

7075
#[inline]

0 commit comments

Comments
 (0)