Skip to content

Commit 10d6a79

Browse files
committed
Example: Json
1 parent 9c8ecb2 commit 10d6a79

4 files changed

Lines changed: 193 additions & 11 deletions

File tree

example/json/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,6 @@ THE SOFTWARE.
2626
2727
---------------------------------------------------------------------------*/
2828

29+
export * from './json'
30+
export * from './runtime'
2931
export * from './static'

example/json/json.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*--------------------------------------------------------------------------
2+
3+
@sinclair/parsebox
4+
5+
The MIT License (MIT)
6+
7+
Copyright (c) 2024 Haydn Paterson (sinclair) (haydn.developer@gmail.com)
8+
9+
Permission is hereby granted, free of charge, to any person obtaining a copy
10+
of this software and associated documentation files (the "Software"), to deal
11+
in the Software without restriction, including without limitation the rights
12+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
copies of the Software, and to permit persons to whom the Software is
14+
furnished to do so, subject to the following conditions:
15+
16+
The above copyright notice and this permission notice shall be included in
17+
all copies or substantial portions of the Software.
18+
19+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
THE SOFTWARE.
26+
27+
---------------------------------------------------------------------------*/
28+
29+
import { Static } from '@sinclair/parsebox'
30+
import { Module } from './runtime'
31+
import { Json } from './static'
32+
33+
/** Parses a Json string (orders of magnitude slower than JSON.parse()) */
34+
export function ParseJson<S extends string>(value: S): Static.Parse<Json, S>[0] {
35+
return Module.Parse('Json', value)[0]
36+
}

example/json/runtime.ts

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
/*--------------------------------------------------------------------------
2+
3+
@sinclair/parsebox
4+
5+
The MIT License (MIT)
6+
7+
Copyright (c) 2024 Haydn Paterson (sinclair) (haydn.developer@gmail.com)
8+
9+
Permission is hereby granted, free of charge, to any person obtaining a copy
10+
of this software and associated documentation files (the "Software"), to deal
11+
in the Software without restriction, including without limitation the rights
12+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
copies of the Software, and to permit persons to whom the Software is
14+
furnished to do so, subject to the following conditions:
15+
16+
The above copyright notice and this permission notice shall be included in
17+
all copies or substantial portions of the Software.
18+
19+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
THE SOFTWARE.
26+
27+
---------------------------------------------------------------------------*/
28+
29+
import { Runtime } from '@sinclair/parsebox'
30+
31+
// -----------------------------------------------------------------------
32+
// Json
33+
// -----------------------------------------------------------------------
34+
const Json = Runtime.Union([
35+
Runtime.Ref('Number'),
36+
Runtime.Ref('Boolean'),
37+
Runtime.Ref('String'),
38+
Runtime.Ref('Null'),
39+
Runtime.Ref('Object'),
40+
Runtime.Ref('Array')
41+
])
42+
// -----------------------------------------------------------------------
43+
// Number
44+
// -----------------------------------------------------------------------
45+
function NumberMapping(value: string) {
46+
return parseFloat(value)
47+
}
48+
const Number = Runtime.Number(NumberMapping)
49+
// -----------------------------------------------------------------------
50+
// String
51+
// -----------------------------------------------------------------------
52+
function StringMapping(value: string) {
53+
return value
54+
}
55+
const String = Runtime.String(['"'], StringMapping)
56+
// -----------------------------------------------------------------------
57+
// Boolean
58+
// -----------------------------------------------------------------------
59+
function BooleanMapping(value: string) {
60+
return value === 'true'
61+
}
62+
const Boolean = Runtime.Union([
63+
Runtime.Const('true'),
64+
Runtime.Const('false'),
65+
], BooleanMapping)
66+
67+
// -----------------------------------------------------------------------
68+
// Null
69+
// -----------------------------------------------------------------------
70+
function NullMapping(_value: string) {
71+
return null
72+
}
73+
const Null = Runtime.Const('null', NullMapping)
74+
// -----------------------------------------------------------------------
75+
// Property
76+
// -----------------------------------------------------------------------
77+
const Key = Runtime.Union([Runtime.String(['"'])])
78+
79+
function PropertyMapping(values: unknown[]) {
80+
return { [values[0] as string]: values[2] }
81+
}
82+
const Property = Runtime.Tuple([Runtime.Ref('Key'), Runtime.Const(':'), Runtime.Ref('Json')], PropertyMapping)
83+
84+
// -----------------------------------------------------------------------
85+
// Properties
86+
// -----------------------------------------------------------------------
87+
function PropertiesMapping(values: unknown[]) {
88+
return (
89+
values.length === 3 ? [values[0], ...values[2] as unknown[]] :
90+
values.length === 1 ? [values[0]] :
91+
[]
92+
)
93+
}
94+
const Properties = Runtime.Union([
95+
Runtime.Tuple([Runtime.Ref('Property'), Runtime.Const(','), Runtime.Ref('Properties')]),
96+
Runtime.Tuple([Runtime.Ref('Property')]),
97+
Runtime.Tuple([])
98+
], PropertiesMapping)
99+
// -----------------------------------------------------------------------
100+
// Object
101+
// -----------------------------------------------------------------------
102+
function ObjectReduce(propertiesList: Record<PropertyKey, unknown>[]) {
103+
return propertiesList.reduce((result, properties) => {
104+
return {...result, ...properties }
105+
}, {})
106+
}
107+
function ObjectMapping(values: unknown[]) {
108+
return ObjectReduce(values[1] as Record<PropertyKey, unknown>[])
109+
}
110+
const _Object = Runtime.Tuple([
111+
Runtime.Const('{'),
112+
Runtime.Ref('Properties'),
113+
Runtime.Const('}')
114+
], ObjectMapping)
115+
// -----------------------------------------------------------------------
116+
// Elemments
117+
// -----------------------------------------------------------------------
118+
function ElementsMapping(values: unknown[]) {
119+
return (
120+
values.length === 3 ? [values[0], ...values[2] as unknown[]] :
121+
values.length === 1 ? [values[0]] :
122+
[]
123+
)
124+
}
125+
const Elements = Runtime.Union([
126+
Runtime.Tuple([Runtime.Ref('Json'), Runtime.Const(','), Runtime.Ref('Elements')]),
127+
Runtime.Tuple([Runtime.Ref('Json')]),
128+
Runtime.Tuple([])
129+
], ElementsMapping)
130+
// -----------------------------------------------------------------------
131+
// Array
132+
// -----------------------------------------------------------------------
133+
function ArrayMapping(values: unknown[]) {
134+
return values[1]
135+
}
136+
const Array = Runtime.Tuple([Runtime.Const('['), Elements, Runtime.Const(']')], ArrayMapping)
137+
138+
export const Module = new Runtime.Module({
139+
Number,
140+
Boolean,
141+
String,
142+
Null,
143+
Key,
144+
Property,
145+
Properties,
146+
Object: _Object,
147+
Elements,
148+
Array,
149+
Json
150+
})

example/json/static.ts

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,6 @@ THE SOFTWARE.
2828

2929
import { Static } from '@sinclair/parsebox'
3030

31-
// Usage
32-
type Result = Static.Parse<Json, `{
33-
"x": 1,
34-
"y": 2,
35-
"z": 3
36-
}`>[0]
37-
3831
// -----------------------------------------------------------------------
3932
// Json
4033
// -----------------------------------------------------------------------
@@ -79,17 +72,18 @@ interface NullMapping extends Static.IMapping {
7972
}
8073
type Null = Static.Const<'null', NullMapping>
8174
// -----------------------------------------------------------------------
75+
// Key
76+
// -----------------------------------------------------------------------
77+
type Key = Static.Union<[Static.String<['"']>]>
78+
// -----------------------------------------------------------------------
8279
// Property
8380
// -----------------------------------------------------------------------
84-
type Key = Static.Union<[ /* Static.Ident, */ Static.String<['"']>]>
85-
86-
type Property = Static.Tuple<[Key, Static.Const<':'>, Json], PropertyMapping>
87-
8881
interface PropertyMapping extends Static.IMapping {
8982
output: this['input'] extends [infer Key extends string, ':', infer Value extends unknown]
9083
? { [_ in Key]: Value }
9184
: never
9285
}
86+
type Property = Static.Tuple<[Key, Static.Const<':'>, Json], PropertyMapping>
9387
// -----------------------------------------------------------------------
9488
// Properties
9589
// -----------------------------------------------------------------------

0 commit comments

Comments
 (0)