corvus_json_schema 0.1.4 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Cargo.lock +13 -2
- data/README.md +6 -4
- data/THIRD-PARTY-NOTICES.txt +15 -14
- data/VERSIONHISTORY.md +9 -0
- data/ext/corvus_json_schema/Cargo.toml +2 -2
- data/ext/corvus_json_schema/src/lib.rs +29 -2
- data/ext/corvus_json_schema/vendor/corvus-json-schema/Cargo.toml +4 -9
- data/ext/corvus_json_schema/vendor/corvus-json-schema/README.md +30 -49
- data/ext/corvus_json_schema/vendor/corvus-json-schema/src/compiler.rs +5 -3
- data/ext/corvus_json_schema/vendor/corvus-json-schema/src/formats.rs +7 -6
- data/ext/corvus_json_schema/vendor/corvus-json-schema/src/lib.rs +4 -4
- data/ext/corvus_json_schema/vendor/corvus-json-schema/src/options.rs +12 -0
- data/ext/corvus_json_schema/vendor/corvus-json-schema/src/pattern.rs +344 -974
- data/lib/corvus_json_schema/version.rb +1 -1
- data/lib/corvus_json_schema.rb +8 -3
- metadata +2 -15
- data/ext/corvus_json_schema/vendor/corvus-json-schema/THIRD-PARTY-NOTICES.txt +0 -93
- data/ext/corvus_json_schema/vendor/corvus-json-schema/src/ecmaregex/charset.rs +0 -271
- data/ext/corvus_json_schema/vendor/corvus-json-schema/src/ecmaregex/compile.rs +0 -941
- data/ext/corvus_json_schema/vendor/corvus-json-schema/src/ecmaregex/dfa.rs +0 -366
- data/ext/corvus_json_schema/vendor/corvus-json-schema/src/ecmaregex/fold.rs +0 -138
- data/ext/corvus_json_schema/vendor/corvus-json-schema/src/ecmaregex/mod.rs +0 -329
- data/ext/corvus_json_schema/vendor/corvus-json-schema/src/ecmaregex/parse.rs +0 -1128
- data/ext/corvus_json_schema/vendor/corvus-json-schema/src/ecmaregex/re2.rs +0 -129
- data/ext/corvus_json_schema/vendor/corvus-json-schema/src/ecmaregex/tables_gen.rs +0 -6685
- data/ext/corvus_json_schema/vendor/corvus-json-schema/src/ecmaregex/tests.rs +0 -1672
- data/ext/corvus_json_schema/vendor/corvus-json-schema/src/ecmaregex/ucd.rs +0 -309
- data/ext/corvus_json_schema/vendor/corvus-json-schema/src/ecmaregex/units.rs +0 -165
- data/ext/corvus_json_schema/vendor/corvus-json-schema/src/ecmaregex/vm.rs +0 -981
data/lib/corvus_json_schema.rb
CHANGED
|
@@ -39,16 +39,21 @@ module CorvusJsonSchema
|
|
|
39
39
|
# "#/$defs/item"), max_depth (of in-place recursion, default 128) and pattern_match_limit (the seconds one match of
|
|
40
40
|
# a pattern or patternProperties regular expression may take, default 1. A match that takes longer is abandoned and
|
|
41
41
|
# the validation raises PatternMatchLimitError. nil or 0 turns the limit off, for a caller who trusts both the
|
|
42
|
-
# schema and the instances)
|
|
42
|
+
# schema and the instances), regex_edition (the edition of ECMA-262 patterns are read with: :dialect, the default,
|
|
43
|
+
# which is ECMAScript 2020 for 2019-09 and 2020-12 and today's for the drafts before them, :current or :es2020) and
|
|
44
|
+
# regex_unicode_version (the version of Unicode they are read with: :default, Unicode 17 today, :latest, 13, 17 or
|
|
45
|
+
# 18).
|
|
43
46
|
#
|
|
44
47
|
# A schema that does not compile raises CompilationError, and one with a regular expression over a limit of size
|
|
45
48
|
# (1,048,576 bytes of pattern, 1,000 levels of groups) raises PatternTooLargeError, which is a CompilationError.
|
|
46
49
|
def self.compile(schema, default_dialect: :draft202012, assert_format: nil, assert_format_in_legacy_drafts: false,
|
|
47
50
|
assert_content: true, formats: nil, resolver: nil, base_uri: nil, entry_point: nil, max_depth: 128,
|
|
48
|
-
pattern_match_limit: DEFAULT_PATTERN_MATCH_LIMIT
|
|
51
|
+
pattern_match_limit: DEFAULT_PATTERN_MATCH_LIMIT, regex_edition: :dialect,
|
|
52
|
+
regex_unicode_version: :default)
|
|
49
53
|
dialect = DIALECTS.fetch(default_dialect) { raise ArgumentError, "unknown dialect #{default_dialect.inspect}" }
|
|
50
54
|
Native.compile(schema, dialect, assert_format, assert_format_in_legacy_drafts, assert_content, formats, resolver,
|
|
51
|
-
base_uri, entry_point, Integer(max_depth), pattern_match_limit&.to_f
|
|
55
|
+
base_uri, entry_point, Integer(max_depth), pattern_match_limit&.to_f, regex_edition.to_s,
|
|
56
|
+
regex_unicode_version.to_s)
|
|
52
57
|
end
|
|
53
58
|
|
|
54
59
|
# The version of the corvus-json-schema crate the extension was built from.
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: corvus_json_schema
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- endjin
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-11-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rb_sys
|
|
@@ -47,22 +47,9 @@ files:
|
|
|
47
47
|
- ext/corvus_json_schema/vendor/corvus-json-schema/Cargo.toml
|
|
48
48
|
- ext/corvus_json_schema/vendor/corvus-json-schema/LICENSE
|
|
49
49
|
- ext/corvus_json_schema/vendor/corvus-json-schema/README.md
|
|
50
|
-
- ext/corvus_json_schema/vendor/corvus-json-schema/THIRD-PARTY-NOTICES.txt
|
|
51
50
|
- ext/corvus_json_schema/vendor/corvus-json-schema/src/compiler.rs
|
|
52
51
|
- ext/corvus_json_schema/vendor/corvus-json-schema/src/dialect.rs
|
|
53
52
|
- ext/corvus_json_schema/vendor/corvus-json-schema/src/document.rs
|
|
54
|
-
- ext/corvus_json_schema/vendor/corvus-json-schema/src/ecmaregex/charset.rs
|
|
55
|
-
- ext/corvus_json_schema/vendor/corvus-json-schema/src/ecmaregex/compile.rs
|
|
56
|
-
- ext/corvus_json_schema/vendor/corvus-json-schema/src/ecmaregex/dfa.rs
|
|
57
|
-
- ext/corvus_json_schema/vendor/corvus-json-schema/src/ecmaregex/fold.rs
|
|
58
|
-
- ext/corvus_json_schema/vendor/corvus-json-schema/src/ecmaregex/mod.rs
|
|
59
|
-
- ext/corvus_json_schema/vendor/corvus-json-schema/src/ecmaregex/parse.rs
|
|
60
|
-
- ext/corvus_json_schema/vendor/corvus-json-schema/src/ecmaregex/re2.rs
|
|
61
|
-
- ext/corvus_json_schema/vendor/corvus-json-schema/src/ecmaregex/tables_gen.rs
|
|
62
|
-
- ext/corvus_json_schema/vendor/corvus-json-schema/src/ecmaregex/tests.rs
|
|
63
|
-
- ext/corvus_json_schema/vendor/corvus-json-schema/src/ecmaregex/ucd.rs
|
|
64
|
-
- ext/corvus_json_schema/vendor/corvus-json-schema/src/ecmaregex/units.rs
|
|
65
|
-
- ext/corvus_json_schema/vendor/corvus-json-schema/src/ecmaregex/vm.rs
|
|
66
53
|
- ext/corvus_json_schema/vendor/corvus-json-schema/src/eval.rs
|
|
67
54
|
- ext/corvus_json_schema/vendor/corvus-json-schema/src/eval/plan.rs
|
|
68
55
|
- ext/corvus_json_schema/vendor/corvus-json-schema/src/eval/plan/fused.rs
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
corvus-json-schema uses third-party libraries or other resources that may be
|
|
2
|
-
distributed under licenses different than the corvus-json-schema software.
|
|
3
|
-
|
|
4
|
-
In the event that we accidentally failed to list a required notice, please
|
|
5
|
-
bring it to our attention. Post an issue or email us:
|
|
6
|
-
|
|
7
|
-
licensing@endjin.com
|
|
8
|
-
|
|
9
|
-
The attached notices are provided for information only.
|
|
10
|
-
|
|
11
|
-
License notice for the Unicode Character Database
|
|
12
|
-
-------------------------------
|
|
13
|
-
|
|
14
|
-
src/ecmaregex/tables_gen.rs holds tables derived from the data files of
|
|
15
|
-
the Unicode Character Database, version 17.0.0
|
|
16
|
-
(https://www.unicode.org/Public/17.0.0/ucd/): the General_Category values,
|
|
17
|
-
the binary properties, the Script and Script_Extensions values, the simple
|
|
18
|
-
case folding and the simple uppercase mapping. The data files are
|
|
19
|
-
"© 2025 Unicode®, Inc." and are licensed under the Unicode License V3
|
|
20
|
-
(SPDX-License-Identifier: Unicode-3.0), as https://www.unicode.org/license.txt
|
|
21
|
-
gives it:
|
|
22
|
-
|
|
23
|
-
UNICODE LICENSE V3
|
|
24
|
-
|
|
25
|
-
COPYRIGHT AND PERMISSION NOTICE
|
|
26
|
-
|
|
27
|
-
Copyright © 1991-2026 Unicode, Inc.
|
|
28
|
-
|
|
29
|
-
NOTICE TO USER: Carefully read the following legal agreement. BY
|
|
30
|
-
DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR
|
|
31
|
-
SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE
|
|
32
|
-
TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT
|
|
33
|
-
DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE.
|
|
34
|
-
|
|
35
|
-
Permission is hereby granted, free of charge, to any person obtaining a
|
|
36
|
-
copy of data files and any associated documentation (the "Data Files") or
|
|
37
|
-
software and any associated documentation (the "Software") to deal in the
|
|
38
|
-
Data Files or Software without restriction, including without limitation
|
|
39
|
-
the rights to use, copy, modify, merge, publish, distribute, and/or sell
|
|
40
|
-
copies of the Data Files or Software, and to permit persons to whom the
|
|
41
|
-
Data Files or Software are furnished to do so, provided that either (a)
|
|
42
|
-
this copyright and permission notice appear with all copies of the Data
|
|
43
|
-
Files or Software, or (b) this copyright and permission notice appear in
|
|
44
|
-
associated Documentation.
|
|
45
|
-
|
|
46
|
-
THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
|
47
|
-
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
48
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
|
49
|
-
THIRD PARTY RIGHTS.
|
|
50
|
-
|
|
51
|
-
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE
|
|
52
|
-
BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES,
|
|
53
|
-
OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
|
54
|
-
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
|
55
|
-
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA
|
|
56
|
-
FILES OR SOFTWARE.
|
|
57
|
-
|
|
58
|
-
Except as contained in this notice, the name of a copyright holder shall
|
|
59
|
-
not be used in advertising or otherwise to promote the sale, use or other
|
|
60
|
-
dealings in these Data Files or Software without prior written
|
|
61
|
-
authorization of the copyright holder.
|
|
62
|
-
|
|
63
|
-
License notice for https://github.com/ridiculousfish/regress
|
|
64
|
-
-------------------------------
|
|
65
|
-
|
|
66
|
-
The tables of src/ecmaregex/tables_gen.rs were written by
|
|
67
|
-
tools/gen-ucd-tables.ps1 from the tables of the Corvus Go module, which were
|
|
68
|
-
written from src/unicodetables.rs of regress 0.12.0. That crate generates the
|
|
69
|
-
file from the Unicode Character Database. regress is licensed under the MIT
|
|
70
|
-
license or the Apache License, Version 2.0, at the user's option. This crate
|
|
71
|
-
does not depend on it.
|
|
72
|
-
|
|
73
|
-
MIT License
|
|
74
|
-
|
|
75
|
-
Copyright (c) 2020 ridiculous_fish
|
|
76
|
-
|
|
77
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
78
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
79
|
-
in the Software without restriction, including without limitation the rights
|
|
80
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
81
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
82
|
-
furnished to do so, subject to the following conditions:
|
|
83
|
-
|
|
84
|
-
The above copyright notice and this permission notice shall be included in all
|
|
85
|
-
copies or substantial portions of the Software.
|
|
86
|
-
|
|
87
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
88
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
89
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
90
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
91
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
92
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
93
|
-
SOFTWARE.
|
|
@@ -1,271 +0,0 @@
|
|
|
1
|
-
//! Sets of code points, the classes ECMA-262 defines, and the sets of the Unicode properties (`charset.go`).
|
|
2
|
-
|
|
3
|
-
use std::collections::HashMap;
|
|
4
|
-
use std::sync::{Arc, LazyLock, Mutex};
|
|
5
|
-
|
|
6
|
-
use super::Rune;
|
|
7
|
-
use super::ucd;
|
|
8
|
-
|
|
9
|
-
/// The last Unicode code point.
|
|
10
|
-
pub(crate) const MAX_RUNE: Rune = ucd::MAX_RUNE;
|
|
11
|
-
|
|
12
|
-
/// An immutable set of code points. The ranges are sorted, inclusive, and neither overlap nor touch. The two words
|
|
13
|
-
/// of `ascii` repeat the membership of the code points below 128 so that the common case is one bit test.
|
|
14
|
-
#[derive(Debug, PartialEq, Eq)]
|
|
15
|
-
pub(crate) struct CharSet {
|
|
16
|
-
pub(crate) ranges: Vec<Rune>,
|
|
17
|
-
pub(crate) ascii: [u64; 2],
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
impl CharSet {
|
|
21
|
-
/// Builds a set from inclusive pairs in any order, which may overlap. With `negate` it builds the complement.
|
|
22
|
-
pub(crate) fn new(pairs: &[Rune], negate: bool) -> CharSet {
|
|
23
|
-
let mut idx: Vec<usize> = (0..pairs.len() / 2).collect();
|
|
24
|
-
idx.sort_by_key(|&i| pairs[2 * i]);
|
|
25
|
-
let mut merged: Vec<Rune> = Vec::with_capacity(pairs.len());
|
|
26
|
-
for i in idx {
|
|
27
|
-
let (lo, hi) = (pairs[2 * i], pairs[2 * i + 1]);
|
|
28
|
-
if let Some(last) = merged.last_mut()
|
|
29
|
-
&& lo <= *last + 1
|
|
30
|
-
{
|
|
31
|
-
if hi > *last {
|
|
32
|
-
*last = hi;
|
|
33
|
-
}
|
|
34
|
-
continue;
|
|
35
|
-
}
|
|
36
|
-
merged.push(lo);
|
|
37
|
-
merged.push(hi);
|
|
38
|
-
}
|
|
39
|
-
if negate {
|
|
40
|
-
let mut inverse = Vec::with_capacity(merged.len() + 2);
|
|
41
|
-
let mut next: Rune = 0;
|
|
42
|
-
for &[lo, hi] in merged.as_chunks::<2>().0 {
|
|
43
|
-
if lo > next {
|
|
44
|
-
inverse.push(next);
|
|
45
|
-
inverse.push(lo - 1);
|
|
46
|
-
}
|
|
47
|
-
next = hi + 1;
|
|
48
|
-
}
|
|
49
|
-
if next <= MAX_RUNE {
|
|
50
|
-
inverse.push(next);
|
|
51
|
-
inverse.push(MAX_RUNE);
|
|
52
|
-
}
|
|
53
|
-
merged = inverse;
|
|
54
|
-
}
|
|
55
|
-
let mut ascii = [0u64; 2];
|
|
56
|
-
for &[lo, hi] in merged.as_chunks::<2>().0 {
|
|
57
|
-
if lo >= 128 {
|
|
58
|
-
break;
|
|
59
|
-
}
|
|
60
|
-
let mut c = lo;
|
|
61
|
-
while c <= hi && c < 128 {
|
|
62
|
-
ascii[(c >> 6) as usize] |= 1 << (c & 63);
|
|
63
|
-
c += 1;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
CharSet { ranges: merged, ascii }
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/// [`CharSet::new`], shared.
|
|
70
|
-
pub(crate) fn shared(pairs: &[Rune], negate: bool) -> Arc<CharSet> {
|
|
71
|
-
Arc::new(CharSet::new(pairs, negate))
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/// Whether the set holds the ASCII character.
|
|
75
|
-
#[inline(always)]
|
|
76
|
-
pub(crate) fn has_ascii(&self, c: u8) -> bool {
|
|
77
|
-
(self.ascii[(c >> 6) as usize & 1] >> (c & 63)) & 1 != 0
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/// Whether the set holds the code point.
|
|
81
|
-
#[inline]
|
|
82
|
-
pub(crate) fn contains(&self, r: Rune) -> bool {
|
|
83
|
-
if (0..128).contains(&r) {
|
|
84
|
-
return (self.ascii[(r >> 6) as usize] >> (r & 63)) & 1 != 0;
|
|
85
|
-
}
|
|
86
|
-
let ranges = &self.ranges[..];
|
|
87
|
-
let (mut lo, mut hi) = (0, ranges.len() / 2);
|
|
88
|
-
while lo < hi {
|
|
89
|
-
let mid = (lo + hi) >> 1;
|
|
90
|
-
if r > ranges[2 * mid + 1] {
|
|
91
|
-
lo = mid + 1;
|
|
92
|
-
} else if r < ranges[2 * mid] {
|
|
93
|
-
hi = mid;
|
|
94
|
-
} else {
|
|
95
|
-
return true;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
false
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/// Whether the set holds no code point.
|
|
102
|
-
pub(crate) fn is_empty(&self) -> bool {
|
|
103
|
-
self.ranges.is_empty()
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// The classes ECMA-262 defines. \d and \w are ASCII only, \s is WhiteSpace and LineTerminator, and . is everything
|
|
108
|
-
// but the four line terminators.
|
|
109
|
-
pub(crate) const DIGIT_PAIRS: &[Rune] = &[0x30, 0x39];
|
|
110
|
-
pub(crate) const WORD_PAIRS: &[Rune] = &[0x30, 0x39, 0x41, 0x5A, 0x5F, 0x5F, 0x61, 0x7A];
|
|
111
|
-
pub(crate) const SPACE_PAIRS: &[Rune] = &[
|
|
112
|
-
0x9, 0xD, 0x20, 0x20, 0xA0, 0xA0, 0x1680, 0x1680, 0x2000, 0x200A, 0x2028, 0x2029, 0x202F, 0x202F, 0x205F, 0x205F,
|
|
113
|
-
0x3000, 0x3000, 0xFEFF, 0xFEFF,
|
|
114
|
-
];
|
|
115
|
-
pub(crate) const LINE_TERMINATOR_PAIRS: &[Rune] = &[0xA, 0xA, 0xD, 0xD, 0x2028, 0x2029];
|
|
116
|
-
|
|
117
|
-
pub(crate) static DOT_SET: LazyLock<Arc<CharSet>> = LazyLock::new(|| CharSet::shared(LINE_TERMINATOR_PAIRS, true));
|
|
118
|
-
|
|
119
|
-
/// Whether a byte is an ECMA-262 word character. Every word character is ASCII, so a word boundary can be decided
|
|
120
|
-
/// from the bytes on either side of a position.
|
|
121
|
-
#[inline(always)]
|
|
122
|
-
pub(crate) fn is_word_byte(b: u8) -> bool {
|
|
123
|
-
b.is_ascii_alphanumeric() || b == b'_'
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/// The short name of a General_Category value, from its long name, an alias or the short name itself.
|
|
127
|
-
fn category_name(value: &str) -> Option<&'static str> {
|
|
128
|
-
Some(match value {
|
|
129
|
-
"Letter" | "L" => "L",
|
|
130
|
-
"Lowercase_Letter" | "Ll" => "Ll",
|
|
131
|
-
"Uppercase_Letter" | "Lu" => "Lu",
|
|
132
|
-
"Titlecase_Letter" | "Lt" => "Lt",
|
|
133
|
-
"Cased_Letter" | "LC" => "LC",
|
|
134
|
-
"Modifier_Letter" | "Lm" => "Lm",
|
|
135
|
-
"Other_Letter" | "Lo" => "Lo",
|
|
136
|
-
"Mark" | "Combining_Mark" | "M" => "M",
|
|
137
|
-
"Nonspacing_Mark" | "Mn" => "Mn",
|
|
138
|
-
"Spacing_Mark" | "Mc" => "Mc",
|
|
139
|
-
"Enclosing_Mark" | "Me" => "Me",
|
|
140
|
-
"Number" | "N" => "N",
|
|
141
|
-
"Decimal_Number" | "digit" | "Nd" => "Nd",
|
|
142
|
-
"Letter_Number" | "Nl" => "Nl",
|
|
143
|
-
"Other_Number" | "No" => "No",
|
|
144
|
-
"Punctuation" | "punct" | "P" => "P",
|
|
145
|
-
"Connector_Punctuation" | "Pc" => "Pc",
|
|
146
|
-
"Dash_Punctuation" | "Pd" => "Pd",
|
|
147
|
-
"Open_Punctuation" | "Ps" => "Ps",
|
|
148
|
-
"Close_Punctuation" | "Pe" => "Pe",
|
|
149
|
-
"Initial_Punctuation" | "Pi" => "Pi",
|
|
150
|
-
"Final_Punctuation" | "Pf" => "Pf",
|
|
151
|
-
"Other_Punctuation" | "Po" => "Po",
|
|
152
|
-
"Symbol" | "S" => "S",
|
|
153
|
-
"Math_Symbol" | "Sm" => "Sm",
|
|
154
|
-
"Currency_Symbol" | "Sc" => "Sc",
|
|
155
|
-
"Modifier_Symbol" | "Sk" => "Sk",
|
|
156
|
-
"Other_Symbol" | "So" => "So",
|
|
157
|
-
"Separator" | "Z" => "Z",
|
|
158
|
-
"Space_Separator" | "Zs" => "Zs",
|
|
159
|
-
"Line_Separator" | "Zl" => "Zl",
|
|
160
|
-
"Paragraph_Separator" | "Zp" => "Zp",
|
|
161
|
-
"Other" | "C" => "C",
|
|
162
|
-
"Control" | "cntrl" | "Cc" => "Cc",
|
|
163
|
-
"Format" | "Cf" => "Cf",
|
|
164
|
-
"Surrogate" | "Cs" => "Cs",
|
|
165
|
-
"Private_Use" | "Co" => "Co",
|
|
166
|
-
"Unassigned" | "Cn" => "Cn",
|
|
167
|
-
_ => return None,
|
|
168
|
-
})
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/// The canonical name of a binary property ECMA-262 lists, from the name or an alias.
|
|
172
|
-
fn binary_name(name: &str) -> Option<&'static str> {
|
|
173
|
-
Some(match name {
|
|
174
|
-
"ASCII" => "ASCII",
|
|
175
|
-
"ASCII_Hex_Digit" | "AHex" => "ASCII_Hex_Digit",
|
|
176
|
-
"Alphabetic" | "Alpha" => "Alphabetic",
|
|
177
|
-
"Any" => "Any",
|
|
178
|
-
"Assigned" => "Assigned",
|
|
179
|
-
"Bidi_Control" | "Bidi_C" => "Bidi_Control",
|
|
180
|
-
"Bidi_Mirrored" | "Bidi_M" => "Bidi_Mirrored",
|
|
181
|
-
"Case_Ignorable" | "CI" => "Case_Ignorable",
|
|
182
|
-
"Cased" => "Cased",
|
|
183
|
-
"Changes_When_Casefolded" | "CWCF" => "Changes_When_Casefolded",
|
|
184
|
-
"Changes_When_Casemapped" | "CWCM" => "Changes_When_Casemapped",
|
|
185
|
-
"Changes_When_Lowercased" | "CWL" => "Changes_When_Lowercased",
|
|
186
|
-
"Changes_When_NFKC_Casefolded" | "CWKCF" => "Changes_When_NFKC_Casefolded",
|
|
187
|
-
"Changes_When_Titlecased" | "CWT" => "Changes_When_Titlecased",
|
|
188
|
-
"Changes_When_Uppercased" | "CWU" => "Changes_When_Uppercased",
|
|
189
|
-
"Dash" => "Dash",
|
|
190
|
-
"Default_Ignorable_Code_Point" | "DI" => "Default_Ignorable_Code_Point",
|
|
191
|
-
"Deprecated" | "Dep" => "Deprecated",
|
|
192
|
-
"Diacritic" | "Dia" => "Diacritic",
|
|
193
|
-
"Emoji" => "Emoji",
|
|
194
|
-
"Emoji_Component" | "EComp" => "Emoji_Component",
|
|
195
|
-
"Emoji_Modifier" | "EMod" => "Emoji_Modifier",
|
|
196
|
-
"Emoji_Modifier_Base" | "EBase" => "Emoji_Modifier_Base",
|
|
197
|
-
"Emoji_Presentation" | "EPres" => "Emoji_Presentation",
|
|
198
|
-
"Extended_Pictographic" | "ExtPict" => "Extended_Pictographic",
|
|
199
|
-
"Extender" | "Ext" => "Extender",
|
|
200
|
-
"Grapheme_Base" | "Gr_Base" => "Grapheme_Base",
|
|
201
|
-
"Grapheme_Extend" | "Gr_Ext" => "Grapheme_Extend",
|
|
202
|
-
"Hex_Digit" | "Hex" => "Hex_Digit",
|
|
203
|
-
"IDS_Binary_Operator" | "IDSB" => "IDS_Binary_Operator",
|
|
204
|
-
"IDS_Trinary_Operator" | "IDST" => "IDS_Trinary_Operator",
|
|
205
|
-
"ID_Continue" | "IDC" => "ID_Continue",
|
|
206
|
-
"ID_Start" | "IDS" => "ID_Start",
|
|
207
|
-
"Ideographic" | "Ideo" => "Ideographic",
|
|
208
|
-
"Join_Control" | "Join_C" => "Join_Control",
|
|
209
|
-
"Logical_Order_Exception" | "LOE" => "Logical_Order_Exception",
|
|
210
|
-
"Lowercase" | "Lower" => "Lowercase",
|
|
211
|
-
"Math" => "Math",
|
|
212
|
-
"Noncharacter_Code_Point" | "NChar" => "Noncharacter_Code_Point",
|
|
213
|
-
"Pattern_Syntax" | "Pat_Syn" => "Pattern_Syntax",
|
|
214
|
-
"Pattern_White_Space" | "Pat_WS" => "Pattern_White_Space",
|
|
215
|
-
"Quotation_Mark" | "QMark" => "Quotation_Mark",
|
|
216
|
-
"Radical" => "Radical",
|
|
217
|
-
"Regional_Indicator" | "RI" => "Regional_Indicator",
|
|
218
|
-
"Sentence_Terminal" | "STerm" => "Sentence_Terminal",
|
|
219
|
-
"Soft_Dotted" | "SD" => "Soft_Dotted",
|
|
220
|
-
"Terminal_Punctuation" | "Term" => "Terminal_Punctuation",
|
|
221
|
-
"Unified_Ideograph" | "UIdeo" => "Unified_Ideograph",
|
|
222
|
-
"Uppercase" | "Upper" => "Uppercase",
|
|
223
|
-
"Variation_Selector" | "VS" => "Variation_Selector",
|
|
224
|
-
"White_Space" | "space" => "White_Space",
|
|
225
|
-
"XID_Continue" | "XIDC" => "XID_Continue",
|
|
226
|
-
"XID_Start" | "XIDS" => "XID_Start",
|
|
227
|
-
_ => return None,
|
|
228
|
-
})
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
/// The sets already built for property expressions. A property set can have hundreds of ranges, and schemas tend to
|
|
232
|
-
/// repeat the same few. Only an expression ECMA-262 defines is kept, and those are a fixed few hundred, so the
|
|
233
|
-
/// cache is bounded.
|
|
234
|
-
static PROPERTY_CACHE: LazyLock<Mutex<HashMap<String, Arc<CharSet>>>> = LazyLock::new(|| Mutex::new(HashMap::new()));
|
|
235
|
-
|
|
236
|
-
/// Resolves the expression between the braces of `\p{...}` to its set. `None` for a name or value that ECMA-262
|
|
237
|
-
/// does not define.
|
|
238
|
-
pub(crate) fn property_set(expr: &str) -> Option<Arc<CharSet>> {
|
|
239
|
-
if let Some(cached) = PROPERTY_CACHE.lock().unwrap_or_else(|e| e.into_inner()).get(expr) {
|
|
240
|
-
return Some(cached.clone());
|
|
241
|
-
}
|
|
242
|
-
let pairs = property_pairs(expr)?;
|
|
243
|
-
let set = CharSet::shared(&pairs, false);
|
|
244
|
-
PROPERTY_CACHE.lock().unwrap_or_else(|e| e.into_inner()).insert(expr.to_string(), set.clone());
|
|
245
|
-
Some(set)
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
/// The ranges of a property expression. Every range comes from the tables of `ucd`, which hold one fixed version of
|
|
249
|
-
/// Unicode, so the answer does not depend on the toolchain.
|
|
250
|
-
fn property_pairs(expr: &str) -> Option<Vec<Rune>> {
|
|
251
|
-
if let Some((name, value)) = expr.split_once('=') {
|
|
252
|
-
return match name {
|
|
253
|
-
"General_Category" | "gc" => category_pairs(value),
|
|
254
|
-
"Script" | "sc" => ucd::script(value).map(|t| t.pairs()),
|
|
255
|
-
"Script_Extensions" | "scx" => ucd::script_extensions(value).map(|t| t.pairs()),
|
|
256
|
-
_ => None,
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
if let Some(pairs) = category_pairs(expr) {
|
|
260
|
-
return Some(pairs);
|
|
261
|
-
}
|
|
262
|
-
match binary_name(expr)? {
|
|
263
|
-
"ASCII" => Some(vec![0, 0x7F]),
|
|
264
|
-
"Any" => Some(vec![0, MAX_RUNE]),
|
|
265
|
-
canonical => ucd::binary(canonical).map(|t| t.pairs()),
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
fn category_pairs(value: &str) -> Option<Vec<Rune>> {
|
|
270
|
-
ucd::category(category_name(value)?).map(|t| t.pairs())
|
|
271
|
-
}
|