effect-grammar 0.3.0 → 0.5.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.
Files changed (68) hide show
  1. package/README.md +168 -229
  2. package/dist/binary.d.ts +64 -0
  3. package/dist/binary.d.ts.map +1 -0
  4. package/dist/binary.js +246 -0
  5. package/dist/binary.js.map +1 -0
  6. package/dist/codec.d.ts +17 -0
  7. package/dist/codec.d.ts.map +1 -0
  8. package/dist/codec.js +14 -0
  9. package/dist/codec.js.map +1 -0
  10. package/dist/combinators.d.ts +112 -6
  11. package/dist/combinators.d.ts.map +1 -1
  12. package/dist/combinators.js +218 -28
  13. package/dist/combinators.js.map +1 -1
  14. package/dist/compile.d.ts +36 -0
  15. package/dist/compile.d.ts.map +1 -0
  16. package/dist/compile.js +228 -0
  17. package/dist/compile.js.map +1 -0
  18. package/dist/core.d.ts +34 -1
  19. package/dist/core.d.ts.map +1 -1
  20. package/dist/core.js +51 -1
  21. package/dist/core.js.map +1 -1
  22. package/dist/env.d.ts +5 -0
  23. package/dist/env.d.ts.map +1 -1
  24. package/dist/env.js +20 -1
  25. package/dist/env.js.map +1 -1
  26. package/dist/errors.d.ts +12 -0
  27. package/dist/errors.d.ts.map +1 -1
  28. package/dist/errors.js +40 -4
  29. package/dist/errors.js.map +1 -1
  30. package/dist/gen.d.ts.map +1 -1
  31. package/dist/gen.js +5 -7
  32. package/dist/gen.js.map +1 -1
  33. package/dist/index.d.ts +5 -4
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +4 -3
  36. package/dist/index.js.map +1 -1
  37. package/dist/parse.d.ts +10 -1
  38. package/dist/parse.d.ts.map +1 -1
  39. package/dist/parse.js +81 -19
  40. package/dist/parse.js.map +1 -1
  41. package/dist/pattern.d.ts +2 -1
  42. package/dist/pattern.d.ts.map +1 -1
  43. package/dist/pattern.js +46 -2
  44. package/dist/pattern.js.map +1 -1
  45. package/dist/print.d.ts +8 -0
  46. package/dist/print.d.ts.map +1 -1
  47. package/dist/print.js +136 -18
  48. package/dist/print.js.map +1 -1
  49. package/dist/render.d.ts.map +1 -1
  50. package/dist/render.js +33 -6
  51. package/dist/render.js.map +1 -1
  52. package/dist/schema.d.ts +8 -3
  53. package/dist/schema.d.ts.map +1 -1
  54. package/dist/schema.js +11 -13
  55. package/dist/schema.js.map +1 -1
  56. package/dist/testing.d.ts +18 -0
  57. package/dist/testing.d.ts.map +1 -0
  58. package/dist/testing.js +72 -0
  59. package/dist/testing.js.map +1 -0
  60. package/package.json +9 -3
  61. package/dist/grammar.d.ts +0 -8
  62. package/dist/grammar.d.ts.map +0 -1
  63. package/dist/grammar.js +0 -8
  64. package/dist/grammar.js.map +0 -1
  65. package/dist/recovery.d.ts +0 -10
  66. package/dist/recovery.d.ts.map +0 -1
  67. package/dist/recovery.js +0 -296
  68. package/dist/recovery.js.map +0 -1
package/README.md CHANGED
@@ -1,255 +1,194 @@
1
1
  # effect-grammar
2
2
 
3
- Invertible grammar combinators and parser-printers for Effect.
4
-
5
- Schema models your structured data. `effect-grammar` models the text formats
6
- inside your strings: connection strings, duration strings (`1h30m`), cron
7
- expressions, search queries, or DSLs.
8
-
9
- You write the grammar definition once. You get four outputs:
10
-
11
- - **A parser.** Reads text and outputs structured data, with line and column
12
- error messages.
13
- - **A printer.** Converts structured data back to canonical text.
14
- - **A `Schema.Codec<A, string>`.** Decoding parses, encoding prints, and Schema
15
- refinements compose.
16
- - **A text renderer.** Formats the grammar as readable text, for documentation
17
- and schema descriptions.
18
-
19
- ## Why effect-grammar?
20
-
21
- `Schema.transformOrFail` makes you write and maintain both directions by hand.
22
- `Schema.TemplateLiteralParser` only handles flat `${a}-${b}` patterns.
23
- `effect-grammar` derives both directions for you. It handles optional parts,
24
- repetition, alternation, recursion, and parts that depend on earlier parts.
25
-
26
- This is for format strings, not documents. The parser backtracks. There is no
27
- memoization and no left recursion. Printing is canonical, not pretty.
3
+ Write a grammar once, then use it to parse text, print values, or derive an
4
+ Effect Schema codec. Grammars are bidirectional by design, with explicit
5
+ round-trip checking when you need an invertibility guarantee.
28
6
 
29
7
  ## Install
30
8
 
31
- ```bash
32
- pnpm add effect-grammar
33
- ```
34
-
35
- Requires Effect `4.0.0-rc.112` or newer in the Effect 4 line.
36
-
37
- ## A grammar
38
-
39
- ```ts
40
- import * as Grammar from "effect-grammar"
41
-
42
- const endpoint = Grammar.gen(function* () {
43
- yield* Grammar.literal("https://")
44
- const host = yield* Grammar.regex(/[^:/?#]+/, "host")
45
- const port = yield* Grammar.optional(Grammar.prefix(":", Grammar.integer))
46
- return { host, port }
47
- })
48
-
49
- Grammar.parse(endpoint, "https://effect.website:8080")
50
- // Result.succeed({ host: "effect.website", port: 8080 })
51
-
52
- Grammar.parse(endpoint, "https://effect.website:abc")
53
- // Result.fail(ParseError: line 1, column 24: expected integer, found "a")
54
-
55
- Grammar.print(endpoint, { host: "effect.website", port: 443 })
56
- // Result.succeed("https://effect.website:443")
9
+ `effect` is a peer dependency:
57
10
 
58
- Grammar.render(endpoint)
59
- // "https://" host:<host> port:(":" <integer>)?
11
+ ```sh
12
+ npm install effect effect-grammar
60
13
  ```
61
14
 
62
- `gen` runs the generator once, when you build the grammar. Nothing is parsed
63
- yet.
64
-
65
- Inside the generator, `yield*` on a value grammar does not give you a value. It
66
- gives you a `Ref<A>`: a stand-in for the value that will exist at parse and
67
- print time. `yield*` on a silent grammar, such as `literal` or `symbol`, gives
68
- nothing back. Silent grammars carry no value.
69
-
70
- The generator's return value is a pattern over those refs. It can be a bare ref,
71
- an object, an array, or constants around them. Parsing fills the pattern in.
72
- Printing reads each ref back out of the value you hand it. That is what makes
73
- the grammar invertible.
15
+ ## Quick start
74
16
 
75
17
  ```ts
76
- const nested = Grammar.gen(function* () {
77
- const host = yield* Grammar.regex(/[^:]+/, "host")
78
- yield* Grammar.literal(":")
79
- const port = yield* Grammar.integer
80
- return { kind: "endpoint", address: { host, port } } as const
81
- })
82
- // Grammar<{ kind: "endpoint"; address: { host: string; port: number } }>
83
- ```
84
-
85
- ## The one rule
86
-
87
- Every binding must appear in the return pattern exactly once. `gen` throws at
88
- build time if one does not. A binding the return does not hold is a value the
89
- printer could not print.
90
-
91
- To parse something and then drop it, wrap it with `skip`. The grammar prints its
92
- canonical form instead.
93
-
94
- ## Refs are not values
95
-
96
- A ref is a stand-in, so JavaScript cannot look inside it. Comparing a ref with
97
- `===` is a type error. Interpolating one into a string throws.
98
-
99
- Branching on a ref is `match`, described below. For everything else there are
100
- small helpers: `defaulted` supplies a value when a part is absent.
101
- `get(ref, key)` reads a property of a ref, including reserved names such as
102
- `then` and `toJSON`.
103
-
104
- ## Depending on an earlier part
105
-
106
- `match` picks a grammar based on an earlier binding. The printer runs the same
107
- choice backwards.
108
-
109
- ```ts
110
- const tagged = Grammar.gen(function* () {
111
- const kind = yield* Grammar.choice(
112
- Grammar.literal("n:").pipe(Grammar.as("num")),
113
- Grammar.literal("w:").pipe(Grammar.as("word")),
114
- )
115
- const value = yield* Grammar.match(kind, {
116
- num: Grammar.integer,
117
- word: Grammar.regex(/[a-z]+/, "word"),
118
- })
119
- return { kind, value }
120
- })
121
- // parses "n:12" → { kind: "num", value: 12 }
122
- ```
123
-
124
- `match` requires the cases to cover every literal of the selector's type.
125
- `matchValue` is the same idea with number or mixed literal keys. Keys keep their
126
- type, so `1` and `"1"` are distinct cases.
127
-
128
- A property of a ref is a ref to that property. A header parsed by one grammar
129
- can steer the body of another:
130
-
131
- ```ts
132
- const frame = Grammar.gen(function* () {
133
- const header = yield* headerGrammar // { kind: "text" | "bin"; size: number }
134
- yield* Grammar.literal(":")
135
- const body = yield* Grammar.match(header.kind, {
136
- text: Grammar.take(header.size),
137
- bin: Grammar.repeat(Grammar.regex(/[01]/, "bit"), header.size),
138
- })
139
- return { header, body }
18
+ import { Schema } from "effect"
19
+ import * as G from "effect-grammar"
20
+
21
+ const endpoint = G.gen(function* () {
22
+ yield* G.literal("https://")
23
+ const host = yield* G.regex(/[^:/?#]+/, "host")
24
+ yield* G.literal(":")
25
+ const port = yield* G.integer
26
+ return { host, port }
140
27
  })
141
- ```
142
28
 
143
- `take(n)` reads exactly `n` characters (UTF-16 code units). `repeat(g, n)` reads
144
- exactly `n` repetitions. The count is a value like any other: return it, and
145
- printing reads it back. A netstring is:
146
-
147
- ```ts
148
- const netstring = Grammar.gen(function* () {
149
- const length = yield* Grammar.integer
150
- yield* Grammar.literal(":")
151
- const payload = yield* Grammar.take(length)
152
- yield* Grammar.literal(",")
153
- return { length, payload }
154
- })
155
- // "5:hello," ⇄ { length: 5, payload: "hello" }
156
- ```
157
-
158
- `seq(...silents)` builds a silent sequence.
159
-
160
- ## Values and alternatives
161
-
162
- `transform` maps between two types, in both directions. Write plain functions.
163
- If a callback throws, the grammar fails cleanly. Use `transformOrFail` when a
164
- direction should return a `Result` instead:
165
-
166
- ```ts
167
- const jsonString = Grammar.regex(/"(?:[^"\\]|\\.)*"/, "string").pipe(
168
- Grammar.transformOrFail({
169
- decode: (text) =>
170
- Result.try({
171
- try: () => JSON.parse(text),
172
- catch: (error) => ({ message: String(error) }),
173
- }),
174
- encode: (value) => Result.succeed(JSON.stringify(value)),
29
+ const Endpoint = G.codec(
30
+ endpoint,
31
+ Schema.Struct({
32
+ host: Schema.NonEmptyString,
33
+ port: Schema.Int,
175
34
  }),
176
35
  )
177
- ```
178
36
 
179
- `decodeTo` checks the value against a Schema on parse and on print. `as` turns a
180
- silent grammar into a constant. `flag` turns presence into a boolean.
37
+ Schema.decodeSync(Endpoint)("https://effect.website:443")
38
+ // { host: "effect.website", port: 443 }
181
39
 
182
- `choice` tries its options in order and backtracks. It has one round-trip rule:
183
- the text printed for a branch must not parse as a different value through an
184
- earlier branch. `taggedChoice` records the chosen branch in the result.
185
-
186
- ```ts
187
- const value = Grammar.taggedChoice("kind", {
188
- number: Grammar.integer,
189
- word: Grammar.regex(/[a-z]+/, "word"),
190
- })
191
- // parses "12" → { kind: "number", value: 12 }
192
- // prints the same → "12"
40
+ Schema.encodeSync(Endpoint)({ host: "effect.website", port: 443 })
41
+ // "https://effect.website:443"
193
42
  ```
194
43
 
195
- Recursion uses `suspend`:
44
+ ## Operations
45
+
46
+ - `parse(grammar, text)` interprets from cursor zero and succeeds only after
47
+ consuming the whole string.
48
+ - `print(grammar, value)` runs the grammar's printer. It validates local printer
49
+ requirements but does not verify that the result parses back to the same
50
+ value.
51
+ - `printChecked(grammar, value)` prints, reparses the whole output, and compares
52
+ the result with Effect's equality. It fails when that value round trip does
53
+ not hold.
54
+ - `prepare(grammar)` runs the library's static validation once, then returns
55
+ `parse`, `print`, and `printChecked` functions bound to the grammar, plus its
56
+ rendering and fidelity audit. It is not compilation or optimization; runtime
57
+ failures remain possible.
58
+ - `codec(grammar, schema)` creates an Effect Schema codec. Encoding uses checked
59
+ printing by default; `{ roundTrip: "off" }` selects unchecked printing.
60
+
61
+ `regex(re, name)` stores the source and flags without `g` or `y`. During parsing
62
+ it uses a fresh sticky matcher at the current cursor, so `^`, `$`, lookarounds,
63
+ and flags retain JavaScript `RegExp` semantics relative to the original full
64
+ input. Printing requires the value itself to be a string matched in full. The
65
+ caller's `RegExp` and `lastIndex` are not mutated.
66
+
67
+ ## Composition and correctness
68
+
69
+ `choice` parses branches in order and prints with the first printer that accepts
70
+ the value. `checkedChoice` uses the first accepting branch whose produced text
71
+ reparses to an equal value. `choiceOn(tag, cases)` instead dispatches printing
72
+ from an existing discriminant field; parsing is still ordered and can remain
73
+ ambiguous. `taggedChoice(tag, cases)` wraps each branch's value as
74
+ `{ [tag]: key, value }` and dispatches by that generated tag.
75
+ `literals(...strings)` is a choice of strings whose value is the string that
76
+ matched. It tries longer strings first, so `literals(">", ">=")` still reads
77
+ `>=`.
78
+
79
+ For explicit branch order or number/boolean discriminants, use
80
+ `choiceOnEntries(tag, entries)` with an array of `[key, grammar]` entries.
81
+ `choiceOn` and `taggedChoice` reject JavaScript array-index keys because object
82
+ enumeration can reorder them.
83
+
84
+ `gen` result objects are exact printer patterns: printing rejects missing,
85
+ extra, symbol, or otherwise unexpected own keys. Arrays must have exactly the
86
+ expected length.
87
+
88
+ `many`, `sepBy`, and exact `repeat` require every successfully parsed item to
89
+ advance the cursor; zero-width items fail rather than loop. `validate`/`prepare`
90
+ report repetitions whose item can be proved to match empty input, but validation
91
+ is intentionally not a proof of all behavior.
92
+
93
+ `take(count)` reads a fixed number of UTF-16 code units and
94
+ `repeat(item, count)` a fixed number of items; the count is a number or a ref
95
+ bound earlier in the same `gen`. `lengthPrefixed(length)` and
96
+ `countPrefixed(item, count)` parse a prefix and then that many UTF-16 code units
97
+ or items, and derive the prefix from the value when printing, so the value does
98
+ not carry it. `filter(predicate, name)` keeps a grammar's value only when the
99
+ predicate accepts it, in both directions.
100
+
101
+ `merge(...parts)` sequences grammars that produce objects and flattens their
102
+ fields into one object. Each part must have statically known fields: a `struct`,
103
+ a `gen` that returns an object, another `merge`, `Binary.bits`, or a `filter`
104
+ over any of these. A general transform is rejected, because its fields cannot be
105
+ known. Printing splits the value by those fields, so errors keep flat paths.
106
+ Duplicate fields are rejected on construction.
107
+
108
+ `suspend(() => grammar)` enables recursive definitions. Its thunk is evaluated
109
+ lazily on first resolution and the resolved grammar is cached. Direct left
110
+ recursion at the same parse position and recursive printing that does not
111
+ consume a value are rejected; recursive grammars must be productive.
112
+
113
+ Transforms state different fidelity intentions:
114
+
115
+ - `transform` and `transformOrFail` make no inverse claim.
116
+ - `iso` records the author's inverse claim; the library does not prove it.
117
+ - `partialIso` records a fallible pair intended to agree where both directions
118
+ succeed.
119
+ - `auditFidelity` lists transforms without a full inverse claim; an empty list
120
+ is not proof of a round trip.
121
+
122
+ Use `printChecked` or the helpers from `effect-grammar/testing` to test the
123
+ values and accepted texts relevant to your grammar. These are properties to
124
+ verify, not laws guaranteed for every grammar.
125
+
126
+ ## Binary
127
+
128
+ `effect-grammar/Binary` applies the same grammars to a `Uint8Array`. Bytes pass
129
+ through the engine as a binary string with one code unit per byte, so every core
130
+ combinator composes with the byte-oriented ones.
196
131
 
197
132
  ```ts
198
- const jsonValue: Grammar.Grammar<Json> = Grammar.suspend(
199
- () =>
200
- Grammar.choice(
201
- jsonNull,
202
- jsonBool,
203
- jsonNumber,
204
- jsonString,
205
- jsonArray,
206
- jsonObject,
207
- ),
208
- "value",
209
- )
210
- ```
211
-
212
- See `examples/` for JSON, Scheme, a Postgres DSN, netstrings, a wire protocol,
213
- and GitHub's search syntax.
214
-
215
- ## Products, delimiters, and trivia
216
-
217
- `struct` and `tuple` build products without a generator. Their staged form is
218
- the same as what `gen` builds.
219
-
220
- Delimiter combinators work data-first and data-last:
133
+ import { Schema } from "effect"
134
+ import * as Grammar from "effect-grammar"
135
+ import * as Binary from "effect-grammar/Binary"
221
136
 
222
- ```ts
223
- const port = Grammar.integer.pipe(
224
- Grammar.prefix(":"),
225
- Grammar.optional(),
226
- Grammar.defaulted(443),
137
+ const header = Grammar.merge(
138
+ Grammar.struct({ id: Binary.uint16 }),
139
+ Binary.bits({ qr: 1, opcode: 4, aa: 1, tc: 1, rd: 1, ra: 1, z: 3, rcode: 4 }),
140
+ Grammar.struct({ qdcount: Binary.uint16 }),
227
141
  )
228
142
 
229
- const pair = Grammar.tuple(
230
- Grammar.integer,
231
- Grammar.integer.pipe(Grammar.prefix(",")),
143
+ const Header = Binary.codec(
144
+ header,
145
+ Schema.Struct({
146
+ id: Binary.Uint16,
147
+ qr: Binary.Bit,
148
+ opcode: Binary.Uint(4),
149
+ aa: Binary.Bit,
150
+ tc: Binary.Bit,
151
+ rd: Binary.Bit,
152
+ ra: Binary.Bit,
153
+ z: Binary.Uint(3),
154
+ rcode: Binary.Uint(4),
155
+ qdcount: Binary.Uint16,
156
+ }),
232
157
  )
233
- ```
234
-
235
- `between` is the two-sided delimiter. `wrap` is another name for it. `lexeme`
236
- skips trailing whitespace after a token, and prints none. `symbol` is a literal
237
- lexeme. `space` is one exact space. `spaces` accepts one or more whitespace
238
- characters and prints one canonical space.
239
-
240
- ## Rendering
241
158
 
242
- `render` formats a grammar as readable text, including binding paths. `describe`
243
- returns a short name for a grammar.
244
-
245
- The interpreter AST is private. Public grammars expose only `Grammar<A>`,
246
- `Ref<A>`, and the combinators.
247
-
248
- ## Errors
249
-
250
- Parse errors report the furthest position reached, with every expected form at
251
- that position, plus line and column.
159
+ Schema.decodeSync(Header)(Uint8Array.of(0xbe, 0xef, 0x01, 0x00, 0x00, 0x01))
160
+ // { id: 48879, qr: 0, opcode: 0, aa: 0, tc: 0, rd: 1, ra: 0, z: 0, rcode: 0, qdcount: 1 }
161
+ ```
252
162
 
253
- Print errors carry a `PrintIssue` tree. It records structural paths, missing
254
- fields, branch failures, and value mismatches. `PrintError.format` renders the
255
- tree as text.
163
+ - `uint8` to `uint64`, `int8` to `int64`, `float32`, and `float64` are
164
+ big-endian; the `le` suffix, as in `uint16le`, reads little-endian. 64-bit
165
+ integers are bigints. `float32` prints only numbers that single precision
166
+ holds exactly.
167
+ - `varuint` is unsigned LEB128 within the safe integer range, and `varint` its
168
+ zigzag-encoded signed form for integers from `-(2 ** 52)` to `2 ** 52 - 1`.
169
+ Parsing accepts padded encodings of any length; printing writes the shortest
170
+ one.
171
+ - `bits(layout)` splits a whole number of bytes into named fields, first field
172
+ highest. A one-bit field has type `0 | 1`; wider fields are numbers of up to
173
+ 53 bits. Printing rejects a field that does not fit its width.
174
+ - `bytes(count)` reads a `Uint8Array` of a constant or previously bound length,
175
+ `lengthPrefixed(length)` derives its prefix, a byte count, when printing, and
176
+ `literal(...bytes)` matches a fixed sequence such as a magic number.
177
+ - `ascii` and `utf8` turn a `Uint8Array` grammar into a string grammar. Invalid
178
+ bytes fail to parse and unencodable strings fail to print; `auditFidelity`
179
+ lists `utf8` as partial.
180
+ - `Bit`, `Uint(bits)` and `Int(bits)` for 1 to 53 bits, `Uint8` to `Uint64`, and
181
+ `Int8` to `Int64` are schemas for the values these grammars produce, and
182
+ `hex(bytes)` formats a `Uint8Array` for display.
183
+ - `parse`, `print`, `printChecked`, and `codec` mirror the text operations over
184
+ `Uint8Array`. Parse failures report a byte offset and the byte found; input
185
+ that ends inside a fixed-width field fails at the end of the input.
186
+
187
+ A grammar that prints a character above `0xff` cannot be encoded and fails to
188
+ print.
189
+
190
+ ## Examples
191
+
192
+ The `examples/` directory includes endpoint and connection-string grammars,
193
+ JSON, HTTP ranges, IP addresses, recursive Scheme syntax, contextual printing,
194
+ Schema error integration, and a binary DNS message codec.
@@ -0,0 +1,64 @@
1
+ import { Result, Schema } from "effect";
2
+ import { type CodecOptions } from "./codec.ts";
3
+ import { type Grammar, type Ref, type Silent } from "./core.ts";
4
+ import { PrintError } from "./errors.ts";
5
+ export { hex } from "./errors.ts";
6
+ export declare const Bit: Schema.Literals<readonly [0, 1]>;
7
+ export declare const Uint: (size: number) => Schema.Int;
8
+ export declare const Int: (size: number) => Schema.Int;
9
+ export declare const Uint8: Schema.Int;
10
+ export declare const Uint16: Schema.Int;
11
+ export declare const Uint32: Schema.Int;
12
+ export declare const Int8: Schema.Int;
13
+ export declare const Int16: Schema.Int;
14
+ export declare const Int32: Schema.Int;
15
+ export declare const Uint64: Schema.BigInt;
16
+ export declare const Int64: Schema.BigInt;
17
+ declare const ParseError_base: Schema.Class<ParseError, Schema.TaggedStruct<"BinaryParseError", {
18
+ readonly offset: Schema.Finite;
19
+ readonly expected: Schema.$Array<Schema.String>;
20
+ readonly found: Schema.UndefinedOr<Schema.Finite>;
21
+ }>, import("effect/Cause").YieldableError>;
22
+ export declare class ParseError extends ParseError_base {
23
+ get message(): string;
24
+ }
25
+ export declare const uint8: Grammar<number>;
26
+ export declare const uint16: Grammar<number>;
27
+ export declare const uint32: Grammar<number>;
28
+ export declare const uint64: Grammar<bigint>;
29
+ export declare const uint16le: Grammar<number>;
30
+ export declare const uint32le: Grammar<number>;
31
+ export declare const uint64le: Grammar<bigint>;
32
+ export declare const int8: Grammar<number>;
33
+ export declare const int16: Grammar<number>;
34
+ export declare const int32: Grammar<number>;
35
+ export declare const int64: Grammar<bigint>;
36
+ export declare const int16le: Grammar<number>;
37
+ export declare const int32le: Grammar<number>;
38
+ export declare const int64le: Grammar<bigint>;
39
+ export declare const float32: Grammar<number>;
40
+ export declare const float64: Grammar<number>;
41
+ export declare const float32le: Grammar<number>;
42
+ export declare const float64le: Grammar<number>;
43
+ /**
44
+ * Unsigned LEB128 within the safe integer range. Parsing accepts padded
45
+ * encodings of any length; printing writes the shortest one.
46
+ */
47
+ export declare const varuint: Grammar<number>;
48
+ /** Zigzag-encoded LEB128, as in protobuf `sint64`, for integers from -(2 ** 52) to 2 ** 52 - 1. */
49
+ export declare const varint: Grammar<number>;
50
+ export type BitLayout = Readonly<Record<string, number>>;
51
+ export type Bits<Layout extends BitLayout> = {
52
+ readonly [K in keyof Layout]: Layout[K] extends 1 ? 0 | 1 : number;
53
+ };
54
+ export declare const bits: <const Layout extends BitLayout>(layout: Layout) => Grammar<Bits<Layout>>;
55
+ export declare const bytes: (count: Ref<number> | number) => Grammar<Uint8Array>;
56
+ export declare const lengthPrefixed: (length: Grammar<number>) => Grammar<Uint8Array>;
57
+ export declare const literal: (...values: ReadonlyArray<number>) => Silent;
58
+ export declare const ascii: (inner: Grammar<Uint8Array<ArrayBufferLike>>) => Grammar<string>;
59
+ export declare const utf8: (inner: Grammar<Uint8Array<ArrayBufferLike>>) => Grammar<string>;
60
+ export declare const parse: <A>(grammar: Grammar<A>, input: Uint8Array) => Result.Result<A, ParseError>;
61
+ export declare const print: <A>(grammar: Grammar<A>, value: A) => Result.Result<Uint8Array, PrintError>;
62
+ export declare const printChecked: typeof print;
63
+ export declare const codec: <S extends Schema.Top, A extends S["Encoded"]>(grammar: Grammar<A>, target: S, options?: CodecOptions) => Schema.decodeTo<S, Schema.Codec<Uint8Array<ArrayBufferLike>, Uint8Array<ArrayBufferLike>, never, never>, never, never>;
64
+ //# sourceMappingURL=binary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"binary.d.ts","sourceRoot":"","sources":["../src/binary.ts"],"names":[],"mappings":"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"}