@bcts/envelope-pattern 1.0.0-alpha.22 → 1.0.0-beta.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.
- package/dist/index.cjs +1291 -826
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +101 -59
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +102 -60
- package/dist/index.d.mts.map +1 -1
- package/dist/index.iife.js +1643 -1179
- package/dist/index.iife.js.map +1 -1
- package/dist/index.mjs +1315 -853
- package/dist/index.mjs.map +1 -1
- package/package.json +13 -11
- package/src/error.ts +1 -1
- package/src/format.ts +19 -31
- package/src/parse/index.ts +17 -1010
- package/src/parse/leaf/array-parser.ts +36 -0
- package/src/parse/leaf/cbor-parser.ts +43 -0
- package/src/parse/leaf/date-parser.ts +81 -0
- package/src/parse/leaf/known-value-parser.ts +73 -0
- package/src/parse/leaf/null-parser.ts +16 -0
- package/src/parse/leaf/number-parser.ts +90 -0
- package/src/parse/leaf/tag-parser.ts +160 -0
- package/src/parse/meta/and-parser.ts +40 -0
- package/src/parse/meta/capture-parser.ts +50 -0
- package/src/parse/meta/group-parser.ts +77 -0
- package/src/parse/meta/not-parser.ts +30 -0
- package/src/parse/meta/or-parser.ts +36 -0
- package/src/parse/meta/primary-parser.ts +234 -0
- package/src/parse/meta/search-parser.ts +41 -0
- package/src/parse/meta/traverse-parser.ts +42 -0
- package/src/parse/structure/assertion-obj-parser.ts +44 -0
- package/src/parse/structure/assertion-parser.ts +22 -0
- package/src/parse/structure/assertion-pred-parser.ts +45 -0
- package/src/parse/structure/compressed-parser.ts +17 -0
- package/src/parse/structure/digest-parser.ts +132 -0
- package/src/parse/structure/elided-parser.ts +17 -0
- package/src/parse/structure/encrypted-parser.ts +17 -0
- package/src/parse/structure/node-parser.ts +54 -0
- package/src/parse/structure/object-parser.ts +32 -0
- package/src/parse/structure/obscured-parser.ts +17 -0
- package/src/parse/structure/predicate-parser.ts +32 -0
- package/src/parse/structure/subject-parser.ts +32 -0
- package/src/parse/structure/wrapped-parser.ts +36 -0
- package/src/pattern/dcbor-integration.ts +40 -8
- package/src/pattern/index.ts +29 -0
- package/src/pattern/leaf/array-pattern.ts +67 -169
- package/src/pattern/leaf/cbor-pattern.ts +37 -23
- package/src/pattern/leaf/index.ts +1 -1
- package/src/pattern/leaf/map-pattern.ts +21 -2
- package/src/pattern/leaf/tagged-pattern.ts +6 -1
- package/src/pattern/meta/search-pattern.ts +13 -38
- package/src/pattern/meta/traverse-pattern.ts +2 -2
- package/src/pattern/structure/assertions-pattern.ts +19 -53
- package/src/pattern/structure/digest-pattern.ts +18 -22
- package/src/pattern/structure/index.ts +3 -0
- package/src/pattern/structure/node-pattern.ts +10 -29
- package/src/pattern/structure/object-pattern.ts +2 -2
- package/src/pattern/structure/predicate-pattern.ts +2 -2
- package/src/pattern/structure/subject-pattern.ts +31 -4
- package/src/pattern/structure/wrapped-pattern.ts +28 -9
- package/src/pattern/vm.ts +4 -4
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
import type { Envelope } from "@bcts/envelope";
|
|
14
14
|
import type { Path } from "../../format";
|
|
15
|
-
import { matchPattern, type Matcher } from "../matcher";
|
|
15
|
+
import { dispatchPatternToString, matchPattern, type Matcher } from "../matcher";
|
|
16
16
|
import type { Instr } from "../vm";
|
|
17
17
|
import type { Pattern } from "../index";
|
|
18
18
|
|
|
@@ -126,7 +126,7 @@ export class PredicatePattern implements Matcher {
|
|
|
126
126
|
case "Any":
|
|
127
127
|
return "pred";
|
|
128
128
|
case "Pattern":
|
|
129
|
-
return `pred(${(this._pattern.pattern
|
|
129
|
+
return `pred(${dispatchPatternToString(this._pattern.pattern)})`;
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
132
|
|
|
@@ -19,10 +19,28 @@ import type { Pattern } from "../index";
|
|
|
19
19
|
// Forward declaration for Pattern factory (used for late binding)
|
|
20
20
|
export let createStructureSubjectPattern: ((pattern: SubjectPattern) => Pattern) | undefined;
|
|
21
21
|
|
|
22
|
+
// Forward declaration for top-level pattern compile/toString dispatch.
|
|
23
|
+
// Mirrors Rust `pat.compile(code, lits, caps)` on the top-level `Pattern`
|
|
24
|
+
// enum — the TS port can't call methods on the tagged-union value, so we
|
|
25
|
+
// register the compile dispatcher (which lives in `pattern/index.ts`)
|
|
26
|
+
// during module initialisation.
|
|
27
|
+
let dispatchPatternCompile:
|
|
28
|
+
| ((pattern: Pattern, code: Instr[], literals: Pattern[], captures: string[]) => void)
|
|
29
|
+
| undefined;
|
|
30
|
+
let dispatchPatternToString: ((pattern: Pattern) => string) | undefined;
|
|
31
|
+
|
|
22
32
|
export function registerSubjectPatternFactory(factory: (pattern: SubjectPattern) => Pattern): void {
|
|
23
33
|
createStructureSubjectPattern = factory;
|
|
24
34
|
}
|
|
25
35
|
|
|
36
|
+
export function registerSubjectPatternDispatch(dispatch: {
|
|
37
|
+
compile: (pattern: Pattern, code: Instr[], literals: Pattern[], captures: string[]) => void;
|
|
38
|
+
toString: (pattern: Pattern) => string;
|
|
39
|
+
}): void {
|
|
40
|
+
dispatchPatternCompile = dispatch.compile;
|
|
41
|
+
dispatchPatternToString = dispatch.toString;
|
|
42
|
+
}
|
|
43
|
+
|
|
26
44
|
/**
|
|
27
45
|
* Pattern type for subject pattern matching.
|
|
28
46
|
*
|
|
@@ -106,14 +124,20 @@ export class SubjectPattern implements Matcher {
|
|
|
106
124
|
case "Any":
|
|
107
125
|
code.push({ type: "NavigateSubject" });
|
|
108
126
|
break;
|
|
109
|
-
case "Pattern":
|
|
127
|
+
case "Pattern": {
|
|
128
|
+
if (dispatchPatternCompile === undefined) {
|
|
129
|
+
throw new Error(
|
|
130
|
+
"SubjectPattern.compile requires the top-level Pattern compile dispatch; not registered",
|
|
131
|
+
);
|
|
132
|
+
}
|
|
110
133
|
// Navigate to the subject first
|
|
111
134
|
code.push({ type: "NavigateSubject" });
|
|
112
135
|
// Save the path and run the inner pattern relative to the subject
|
|
113
136
|
code.push({ type: "ExtendTraversal" });
|
|
114
|
-
(this._pattern.pattern
|
|
137
|
+
dispatchPatternCompile(this._pattern.pattern, code, literals, captures);
|
|
115
138
|
code.push({ type: "CombineTraversal" });
|
|
116
139
|
break;
|
|
140
|
+
}
|
|
117
141
|
}
|
|
118
142
|
}
|
|
119
143
|
|
|
@@ -125,8 +149,11 @@ export class SubjectPattern implements Matcher {
|
|
|
125
149
|
switch (this._pattern.type) {
|
|
126
150
|
case "Any":
|
|
127
151
|
return "subj";
|
|
128
|
-
case "Pattern":
|
|
129
|
-
|
|
152
|
+
case "Pattern": {
|
|
153
|
+
const fmt = dispatchPatternToString;
|
|
154
|
+
const inner = fmt !== undefined ? fmt(this._pattern.pattern) : "?";
|
|
155
|
+
return `subj(${inner})`;
|
|
156
|
+
}
|
|
130
157
|
}
|
|
131
158
|
}
|
|
132
159
|
|
|
@@ -19,6 +19,12 @@ import type { Pattern } from "../index";
|
|
|
19
19
|
// Forward declaration for Pattern factory
|
|
20
20
|
let createStructureWrappedPattern: ((pattern: WrappedPattern) => Pattern) | undefined;
|
|
21
21
|
|
|
22
|
+
// Forward declaration for `Pattern::any()` so that
|
|
23
|
+
// `WrappedPattern.unwrap()` can mirror Rust's
|
|
24
|
+
// `Self::unwrap_matching(Pattern::any())` factory exactly. Resolved during
|
|
25
|
+
// pattern-module registration to avoid the circular import.
|
|
26
|
+
let createAnyPattern: (() => Pattern) | undefined;
|
|
27
|
+
|
|
22
28
|
// Forward declaration for pattern dispatch (avoids circular imports)
|
|
23
29
|
let dispatchPatternPathsWithCaptures:
|
|
24
30
|
| ((pattern: Pattern, haystack: Envelope) => [Path[], Map<string, Path[]>])
|
|
@@ -32,6 +38,10 @@ export function registerWrappedPatternFactory(factory: (pattern: WrappedPattern)
|
|
|
32
38
|
createStructureWrappedPattern = factory;
|
|
33
39
|
}
|
|
34
40
|
|
|
41
|
+
export function registerWrappedPatternAny(factory: () => Pattern): void {
|
|
42
|
+
createAnyPattern = factory;
|
|
43
|
+
}
|
|
44
|
+
|
|
35
45
|
export function registerWrappedPatternDispatch(dispatch: {
|
|
36
46
|
pathsWithCaptures: (pattern: Pattern, haystack: Envelope) => [Path[], Map<string, Path[]>];
|
|
37
47
|
compile: (pattern: Pattern, code: Instr[], literals: Pattern[], captures: string[]) => void;
|
|
@@ -80,12 +90,17 @@ export class WrappedPattern implements Matcher {
|
|
|
80
90
|
|
|
81
91
|
/**
|
|
82
92
|
* Creates a new WrappedPattern that matches any wrapped envelope and descends into it.
|
|
83
|
-
*
|
|
93
|
+
*
|
|
94
|
+
* Mirrors Rust `WrappedPattern::unwrap()` which delegates to
|
|
95
|
+
* `Self::unwrap_matching(Pattern::any())`. The `any` factory is wired in
|
|
96
|
+
* during module-load registration to break the circular import on the
|
|
97
|
+
* top-level `Pattern` type.
|
|
84
98
|
*/
|
|
85
99
|
static unwrap(): WrappedPattern {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
100
|
+
if (createAnyPattern === undefined) {
|
|
101
|
+
throw new Error("WrappedPattern.unwrap() requires Pattern.any factory; not registered");
|
|
102
|
+
}
|
|
103
|
+
return WrappedPattern.unwrapMatching(createAnyPattern());
|
|
89
104
|
}
|
|
90
105
|
|
|
91
106
|
/**
|
|
@@ -184,13 +199,17 @@ export class WrappedPattern implements Matcher {
|
|
|
184
199
|
case "Any":
|
|
185
200
|
return "wrapped";
|
|
186
201
|
case "Unwrap": {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
202
|
+
// Rust collapses `Unwrap(Pattern::any())` to the bare keyword
|
|
203
|
+
// `unwrap`. We detect the "any" pattern by inspecting the tagged
|
|
204
|
+
// union shape rather than by string compare so this stays correct
|
|
205
|
+
// if `Pattern::any()`'s display ever changes.
|
|
206
|
+
const inner = this._pattern.pattern;
|
|
207
|
+
const isAny = inner.type === "Meta" && inner.pattern.type === "Any";
|
|
208
|
+
if (isAny) {
|
|
192
209
|
return "unwrap";
|
|
193
210
|
}
|
|
211
|
+
const patternStr =
|
|
212
|
+
dispatchPatternToString !== undefined ? dispatchPatternToString(inner) : "?";
|
|
194
213
|
return `unwrap(${patternStr})`;
|
|
195
214
|
}
|
|
196
215
|
}
|
package/src/pattern/vm.ts
CHANGED
|
@@ -86,10 +86,10 @@ export function axisChildren(axis: Axis, env: Envelope): [Envelope, EdgeType][]
|
|
|
86
86
|
if (envCase.type === "node") {
|
|
87
87
|
const subject = envCase.subject;
|
|
88
88
|
if (subject.isWrapped()) {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
89
|
+
// Mirror Rust `subject.try_unwrap().unwrap()`: the "is wrapped"
|
|
90
|
+
// check above already guarantees `tryUnwrap` won't throw.
|
|
91
|
+
const unwrapped = subject.tryUnwrap();
|
|
92
|
+
return [[unwrapped, "Content"]];
|
|
93
93
|
}
|
|
94
94
|
} else if (envCase.type === "wrapped") {
|
|
95
95
|
return [[envCase.envelope, "Content"]];
|