@data-vegle/serial 0.1.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/LICENSE +21 -0
- package/README.md +87 -0
- package/flamework.build +11 -0
- package/out/index.d.ts +3 -0
- package/out/init.luau +5 -0
- package/out/lib/BufferReader.d.ts +19 -0
- package/out/lib/BufferReader.luau +97 -0
- package/out/lib/BufferWriter.d.ts +22 -0
- package/out/lib/BufferWriter.luau +122 -0
- package/out/lib/Codec.d.ts +7 -0
- package/out/lib/Codec.luau +2 -0
- package/out/lib/CodecCompiler.d.ts +5 -0
- package/out/lib/CodecCompiler.luau +164 -0
- package/out/lib/CollectionCodecs.d.ts +10 -0
- package/out/lib/CollectionCodecs.luau +256 -0
- package/out/lib/PrimitiveCodecs.d.ts +8 -0
- package/out/lib/PrimitiveCodecs.luau +110 -0
- package/out/lib/RobloxCodecs.d.ts +29 -0
- package/out/lib/RobloxCodecs.luau +506 -0
- package/out/lib/Serializer.d.ts +14 -0
- package/out/lib/Serializer.luau +45 -0
- package/out/lib/SerializerMetadata.d.ts +63 -0
- package/out/lib/SerializerMetadata.luau +2 -0
- package/package.json +45 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 datax-e
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# @rbxts/serial
|
|
2
|
+
|
|
3
|
+
Serialize roblox-ts types into buffers.
|
|
4
|
+
|
|
5
|
+
> **Status:** scaffolding only. The toolchain is set up and verified; the serializer
|
|
6
|
+
> itself is not written yet.
|
|
7
|
+
|
|
8
|
+
## Toolchain
|
|
9
|
+
|
|
10
|
+
| Piece | Why it's here |
|
|
11
|
+
| -------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
|
|
12
|
+
| [roblox-ts](https://roblox-ts.com) 3.0 | TypeScript → Luau compiler |
|
|
13
|
+
| [Flamework](https://flamework.fireboltofdeath.dev) 1.3 | its transformer exposes compile-time type metadata (user macros) |
|
|
14
|
+
| [Rojo](https://rojo.space) 7 | syncs the compiled output into Studio |
|
|
15
|
+
| [Prettier](https://prettier.io) | formatting, enforced in CI |
|
|
16
|
+
|
|
17
|
+
Flamework is the reason this project isn't a plain roblox-ts package. Its
|
|
18
|
+
transformer can hand you a type's identity, a printed form of the type, and a
|
|
19
|
+
generated runtime guard — all derived from a TypeScript type at build time. That
|
|
20
|
+
is what the serializer templates will be generated from, instead of asking
|
|
21
|
+
callers to hand-write a schema next to every interface.
|
|
22
|
+
|
|
23
|
+
## Setup
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
npm install
|
|
27
|
+
npm run build
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Studio-side tooling is pinned in `rokit.toml`:
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
rokit install # installs Rojo
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Scripts
|
|
37
|
+
|
|
38
|
+
| Script | What it does |
|
|
39
|
+
| --------------------- | ----------------------------------------------------------------------- |
|
|
40
|
+
| `npm run build` | compile `src/` → `out/` as a package |
|
|
41
|
+
| `npm run watch` | same, in watch mode |
|
|
42
|
+
| `npm run build:place` | compile as a game instead, emitting the `include/` runtime |
|
|
43
|
+
| `npm run place` | build the place and pack it into `serial-test.rbxl` for Studio |
|
|
44
|
+
| `npm run clean` | remove `out/` and `include/` |
|
|
45
|
+
| `npm run format` | run Prettier over `src/` |
|
|
46
|
+
|
|
47
|
+
`build` and `build:place` write to the same `out/` directory, so `build:place`
|
|
48
|
+
cleans first. Run `npm run build` again before publishing.
|
|
49
|
+
|
|
50
|
+
## Layout
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
src/ library source, compiled to out/
|
|
54
|
+
default.project.json Rojo project for the package itself
|
|
55
|
+
test.project.json Rojo place used to try the library in Studio
|
|
56
|
+
flamework.build Flamework's identifier table — commit it, don't edit it
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
`flamework.build` holds the stable ids the transformer hands out. It is tracked
|
|
60
|
+
in git and shipped in the published package on purpose; deleting it makes
|
|
61
|
+
previously generated ids drift.
|
|
62
|
+
|
|
63
|
+
## Writing a type macro
|
|
64
|
+
|
|
65
|
+
Flamework user macros need two things: the `plugins` entry in `tsconfig.json`
|
|
66
|
+
(already there), and a `@metadata macro` JSDoc tag on the function. Without the
|
|
67
|
+
tag the transformer silently skips the call and the parameter arrives as
|
|
68
|
+
`undefined`.
|
|
69
|
+
|
|
70
|
+
`src/index.ts` has the minimal working example:
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
/** @metadata macro */
|
|
74
|
+
export function typeIdOf<T>(id?: Modding.Generic<T, "id">): string {
|
|
75
|
+
assert(id !== undefined, "typeIdOf<T>() was called without the Flamework transformer");
|
|
76
|
+
return id;
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Callers just write `typeIdOf<PlayerState>()` and the transformer rewrites it to
|
|
81
|
+
`typeIdOf("@rbxts/serial:src/index@PlayerState")`. Swapping `"id"` for `"text"`
|
|
82
|
+
or `"guard"` in `Modding.Generic` gives the printed type or a runtime type guard
|
|
83
|
+
instead — those are the hooks the buffer serializer will be built from.
|
|
84
|
+
|
|
85
|
+
## License
|
|
86
|
+
|
|
87
|
+
MIT
|
package/flamework.build
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"flameworkVersion": "1.3.2",
|
|
4
|
+
"identifiers": {
|
|
5
|
+
"@data-vegle/serial:out/lib/BufferReader@BufferReader": "@data-vegle/serial:lib/BufferReader@BufferReader",
|
|
6
|
+
"@data-vegle/serial:out/lib/BufferWriter@BufferWriter": "@data-vegle/serial:lib/BufferWriter@BufferWriter",
|
|
7
|
+
"@data-vegle/serial:out/lib/Serializer@Serializer": "@data-vegle/serial:lib/Serializer@Serializer"
|
|
8
|
+
},
|
|
9
|
+
"metadata": {},
|
|
10
|
+
"identifierPrefix": "@data-vegle/serial"
|
|
11
|
+
}
|
package/out/index.d.ts
ADDED
package/out/init.luau
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export declare class BufferReader {
|
|
2
|
+
private readonly data;
|
|
3
|
+
private readonly blobs;
|
|
4
|
+
private cursor;
|
|
5
|
+
constructor(data: buffer, blobs: ReadonlyArray<defined>);
|
|
6
|
+
readBool(): boolean;
|
|
7
|
+
readU8(): number;
|
|
8
|
+
readU16(): number;
|
|
9
|
+
readU32(): number;
|
|
10
|
+
readI8(): number;
|
|
11
|
+
readI16(): number;
|
|
12
|
+
readI32(): number;
|
|
13
|
+
readF32(): number;
|
|
14
|
+
readF64(): number;
|
|
15
|
+
readVarUint(): number;
|
|
16
|
+
readString(): string;
|
|
17
|
+
readBuffer(): buffer;
|
|
18
|
+
readBlob<T>(): T;
|
|
19
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
|
|
2
|
+
local a=128
|
|
3
|
+
local b
|
|
4
|
+
do
|
|
5
|
+
b=setmetatable({},{
|
|
6
|
+
__tostring=function()
|
|
7
|
+
return"BufferReader"
|
|
8
|
+
end,
|
|
9
|
+
})
|
|
10
|
+
b.__index=b
|
|
11
|
+
function b.new(...)
|
|
12
|
+
local c=setmetatable({},b)
|
|
13
|
+
return c:constructor(...)or c
|
|
14
|
+
end
|
|
15
|
+
function b.constructor(c,d,e)
|
|
16
|
+
c.data=d
|
|
17
|
+
c.blobs=e
|
|
18
|
+
c.cursor=0
|
|
19
|
+
end
|
|
20
|
+
function b.readBool(c)
|
|
21
|
+
local d=c:readU8()
|
|
22
|
+
return d==1
|
|
23
|
+
end
|
|
24
|
+
function b.readU8(c)
|
|
25
|
+
local d=buffer.readu8(c.data,c.cursor)
|
|
26
|
+
c.cursor=c.cursor+1
|
|
27
|
+
return d
|
|
28
|
+
end
|
|
29
|
+
function b.readU16(c)
|
|
30
|
+
local d=buffer.readu16(c.data,c.cursor)
|
|
31
|
+
c.cursor=c.cursor+2
|
|
32
|
+
return d
|
|
33
|
+
end
|
|
34
|
+
function b.readU32(c)
|
|
35
|
+
local d=buffer.readu32(c.data,c.cursor)
|
|
36
|
+
c.cursor=c.cursor+4
|
|
37
|
+
return d
|
|
38
|
+
end
|
|
39
|
+
function b.readI8(c)
|
|
40
|
+
local d=buffer.readi8(c.data,c.cursor)
|
|
41
|
+
c.cursor=c.cursor+1
|
|
42
|
+
return d
|
|
43
|
+
end
|
|
44
|
+
function b.readI16(c)
|
|
45
|
+
local d=buffer.readi16(c.data,c.cursor)
|
|
46
|
+
c.cursor=c.cursor+2
|
|
47
|
+
return d
|
|
48
|
+
end
|
|
49
|
+
function b.readI32(c)
|
|
50
|
+
local d=buffer.readi32(c.data,c.cursor)
|
|
51
|
+
c.cursor=c.cursor+4
|
|
52
|
+
return d
|
|
53
|
+
end
|
|
54
|
+
function b.readF32(c)
|
|
55
|
+
local d=buffer.readf32(c.data,c.cursor)
|
|
56
|
+
c.cursor=c.cursor+4
|
|
57
|
+
return d
|
|
58
|
+
end
|
|
59
|
+
function b.readF64(c)
|
|
60
|
+
local d=buffer.readf64(c.data,c.cursor)
|
|
61
|
+
c.cursor=c.cursor+8
|
|
62
|
+
return d
|
|
63
|
+
end
|
|
64
|
+
function b.readVarUint(c)
|
|
65
|
+
local d=0
|
|
66
|
+
local e=1
|
|
67
|
+
local f=c:readU8()
|
|
68
|
+
while f>=a do
|
|
69
|
+
local g=f-a
|
|
70
|
+
d=d+g*e
|
|
71
|
+
e=e*a
|
|
72
|
+
f=c:readU8()
|
|
73
|
+
end
|
|
74
|
+
d=d+f*e
|
|
75
|
+
return d
|
|
76
|
+
end
|
|
77
|
+
function b.readString(c)
|
|
78
|
+
local d=c:readVarUint()
|
|
79
|
+
local e=buffer.readstring(c.data,c.cursor,d)
|
|
80
|
+
c.cursor=c.cursor+d
|
|
81
|
+
return e
|
|
82
|
+
end
|
|
83
|
+
function b.readBuffer(c)
|
|
84
|
+
local d=c:readVarUint()
|
|
85
|
+
local e=buffer.create(d)
|
|
86
|
+
buffer.copy(e,0,c.data,c.cursor,d)
|
|
87
|
+
c.cursor=c.cursor+d
|
|
88
|
+
return e
|
|
89
|
+
end
|
|
90
|
+
function b.readBlob(c)
|
|
91
|
+
local d=c:readVarUint()
|
|
92
|
+
return c.blobs[d+1]
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
return{
|
|
96
|
+
BufferReader=b,
|
|
97
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare class BufferWriter {
|
|
2
|
+
private data;
|
|
3
|
+
private capacity;
|
|
4
|
+
private cursor;
|
|
5
|
+
private readonly blobs;
|
|
6
|
+
writeBool(value: boolean): void;
|
|
7
|
+
writeU8(value: number): void;
|
|
8
|
+
writeU16(value: number): void;
|
|
9
|
+
writeU32(value: number): void;
|
|
10
|
+
writeI8(value: number): void;
|
|
11
|
+
writeI16(value: number): void;
|
|
12
|
+
writeI32(value: number): void;
|
|
13
|
+
writeF32(value: number): void;
|
|
14
|
+
writeF64(value: number): void;
|
|
15
|
+
writeVarUint(value: number): void;
|
|
16
|
+
writeString(value: string): void;
|
|
17
|
+
writeBuffer(value: buffer): void;
|
|
18
|
+
writeBlob(value: defined): void;
|
|
19
|
+
getBuffer(): buffer;
|
|
20
|
+
getBlobs(): Array<defined>;
|
|
21
|
+
private reserve;
|
|
22
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
|
|
2
|
+
local a=64
|
|
3
|
+
local b=128
|
|
4
|
+
local c
|
|
5
|
+
do
|
|
6
|
+
c=setmetatable({},{
|
|
7
|
+
__tostring=function()
|
|
8
|
+
return"BufferWriter"
|
|
9
|
+
end,
|
|
10
|
+
})
|
|
11
|
+
c.__index=c
|
|
12
|
+
function c.new(...)
|
|
13
|
+
local d=setmetatable({},c)
|
|
14
|
+
return d:constructor(...)or d
|
|
15
|
+
end
|
|
16
|
+
function c.constructor(d)
|
|
17
|
+
d.data=buffer.create(a)
|
|
18
|
+
d.capacity=a
|
|
19
|
+
d.cursor=0
|
|
20
|
+
d.blobs={}
|
|
21
|
+
end
|
|
22
|
+
function c.writeBool(d,e)
|
|
23
|
+
local f=if e then 1 else 0
|
|
24
|
+
d:writeU8(f)
|
|
25
|
+
end
|
|
26
|
+
function c.writeU8(d,e)
|
|
27
|
+
d:reserve(1)
|
|
28
|
+
buffer.writeu8(d.data,d.cursor,e)
|
|
29
|
+
d.cursor=d.cursor+1
|
|
30
|
+
end
|
|
31
|
+
function c.writeU16(d,e)
|
|
32
|
+
d:reserve(2)
|
|
33
|
+
buffer.writeu16(d.data,d.cursor,e)
|
|
34
|
+
d.cursor=d.cursor+2
|
|
35
|
+
end
|
|
36
|
+
function c.writeU32(d,e)
|
|
37
|
+
d:reserve(4)
|
|
38
|
+
buffer.writeu32(d.data,d.cursor,e)
|
|
39
|
+
d.cursor=d.cursor+4
|
|
40
|
+
end
|
|
41
|
+
function c.writeI8(d,e)
|
|
42
|
+
d:reserve(1)
|
|
43
|
+
buffer.writei8(d.data,d.cursor,e)
|
|
44
|
+
d.cursor=d.cursor+1
|
|
45
|
+
end
|
|
46
|
+
function c.writeI16(d,e)
|
|
47
|
+
d:reserve(2)
|
|
48
|
+
buffer.writei16(d.data,d.cursor,e)
|
|
49
|
+
d.cursor=d.cursor+2
|
|
50
|
+
end
|
|
51
|
+
function c.writeI32(d,e)
|
|
52
|
+
d:reserve(4)
|
|
53
|
+
buffer.writei32(d.data,d.cursor,e)
|
|
54
|
+
d.cursor=d.cursor+4
|
|
55
|
+
end
|
|
56
|
+
function c.writeF32(d,e)
|
|
57
|
+
d:reserve(4)
|
|
58
|
+
buffer.writef32(d.data,d.cursor,e)
|
|
59
|
+
d.cursor=d.cursor+4
|
|
60
|
+
end
|
|
61
|
+
function c.writeF64(d,e)
|
|
62
|
+
d:reserve(8)
|
|
63
|
+
buffer.writef64(d.data,d.cursor,e)
|
|
64
|
+
d.cursor=d.cursor+8
|
|
65
|
+
end
|
|
66
|
+
function c.writeVarUint(d,e)
|
|
67
|
+
local f=e
|
|
68
|
+
while f>=b do
|
|
69
|
+
local g=f%b
|
|
70
|
+
local h=g+b
|
|
71
|
+
d:writeU8(h)
|
|
72
|
+
f=math.floor(f/b)
|
|
73
|
+
end
|
|
74
|
+
d:writeU8(f)
|
|
75
|
+
end
|
|
76
|
+
function c.writeString(d,e)
|
|
77
|
+
local f=#e
|
|
78
|
+
d:writeVarUint(f)
|
|
79
|
+
d:reserve(f)
|
|
80
|
+
buffer.writestring(d.data,d.cursor,e,f)
|
|
81
|
+
d.cursor=d.cursor+f
|
|
82
|
+
end
|
|
83
|
+
function c.writeBuffer(d,e)
|
|
84
|
+
local f=buffer.len(e)
|
|
85
|
+
d:writeVarUint(f)
|
|
86
|
+
d:reserve(f)
|
|
87
|
+
buffer.copy(d.data,d.cursor,e,0,f)
|
|
88
|
+
d.cursor=d.cursor+f
|
|
89
|
+
end
|
|
90
|
+
function c.writeBlob(d,e)
|
|
91
|
+
local f=#d.blobs
|
|
92
|
+
local g=d.blobs
|
|
93
|
+
local h=e
|
|
94
|
+
table.insert(g,h)
|
|
95
|
+
d:writeVarUint(f)
|
|
96
|
+
end
|
|
97
|
+
function c.getBuffer(d)
|
|
98
|
+
local e=buffer.create(d.cursor)
|
|
99
|
+
buffer.copy(e,0,d.data,0,d.cursor)
|
|
100
|
+
return e
|
|
101
|
+
end
|
|
102
|
+
function c.getBlobs(d)
|
|
103
|
+
return d.blobs
|
|
104
|
+
end
|
|
105
|
+
function c.reserve(d,e)
|
|
106
|
+
local f=d.cursor+e
|
|
107
|
+
if f<=d.capacity then
|
|
108
|
+
return nil
|
|
109
|
+
end
|
|
110
|
+
local g=d.capacity*2
|
|
111
|
+
while g<f do
|
|
112
|
+
g=g*2
|
|
113
|
+
end
|
|
114
|
+
local h=buffer.create(g)
|
|
115
|
+
buffer.copy(h,0,d.data,0,d.cursor)
|
|
116
|
+
d.data=h
|
|
117
|
+
d.capacity=g
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
return{
|
|
121
|
+
BufferWriter=c,
|
|
122
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { AnyCodec } from "./Codec";
|
|
2
|
+
type SimpleKind = "bool" | "f64" | "string" | "buffer" | "blob" | "vector3" | "vector2" | "vector3int16" | "vector2int16" | "cframe" | "color3" | "brickcolor" | "udim" | "udim2" | "rect" | "ray" | "region3" | "region3int16" | "numberrange" | "numbersequence" | "colorsequence" | "physicalproperties" | "datetime" | "tweeninfo" | "font" | "axes" | "faces";
|
|
3
|
+
export type Metadata = [SimpleKind] | ["optional", Metadata] | ["literal", Array<defined>, number] | ["list", Metadata] | ["tuple", Array<Metadata>] | ["set", Metadata] | ["map", Metadata, Metadata] | ["object", Array<[string, Metadata]>] | ["enum", string] | ["union", string, Array<[defined, Metadata]>];
|
|
4
|
+
export declare function compileCodec(meta: Metadata): AnyCodec;
|
|
5
|
+
export {};
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
|
|
2
|
+
local a=_G[script]
|
|
3
|
+
local b=a.import(script,script.Parent,"CollectionCodecs")
|
|
4
|
+
local c=b.list
|
|
5
|
+
local d=b.map
|
|
6
|
+
local e=b.object
|
|
7
|
+
local f=b.optional
|
|
8
|
+
local g=b.set
|
|
9
|
+
local h=b.tuple
|
|
10
|
+
local i=b.variant
|
|
11
|
+
local j=a.import(script,script.Parent,"PrimitiveCodecs")
|
|
12
|
+
local k=j.blobCodec
|
|
13
|
+
local l=j.boolCodec
|
|
14
|
+
local m=j.bufferCodec
|
|
15
|
+
local n=j.f64Codec
|
|
16
|
+
local o=j.literal
|
|
17
|
+
local p=j.literalUnion
|
|
18
|
+
local q=j.stringCodec
|
|
19
|
+
local r=a.import(script,script.Parent,"RobloxCodecs")
|
|
20
|
+
local s=r.axesCodec
|
|
21
|
+
local t=r.brickColorCodec
|
|
22
|
+
local u=r.cframeCodec
|
|
23
|
+
local v=r.color3Codec
|
|
24
|
+
local w=r.colorSequenceCodec
|
|
25
|
+
local x=r.createEnumCodecByName
|
|
26
|
+
local y=r.dateTimeCodec
|
|
27
|
+
local z=r.facesCodec
|
|
28
|
+
local A=r.fontCodec
|
|
29
|
+
local B=r.numberRangeCodec
|
|
30
|
+
local C=r.numberSequenceCodec
|
|
31
|
+
local D=r.physicalPropertiesCodec
|
|
32
|
+
local E=r.rayCodec
|
|
33
|
+
local F=r.rectCodec
|
|
34
|
+
local G=r.region3Codec
|
|
35
|
+
local H=r.region3int16Codec
|
|
36
|
+
local I=r.tweenInfoCodec
|
|
37
|
+
local J=r.udim2Codec
|
|
38
|
+
local K=r.udimCodec
|
|
39
|
+
local L=r.vector2Codec
|
|
40
|
+
local M=r.vector2int16Codec
|
|
41
|
+
local N=r.vector3Codec
|
|
42
|
+
local O=r.vector3int16Codec
|
|
43
|
+
local P=-1
|
|
44
|
+
local Q=1
|
|
45
|
+
local R={
|
|
46
|
+
bool=l,
|
|
47
|
+
f64=n,
|
|
48
|
+
string=q,
|
|
49
|
+
buffer=m,
|
|
50
|
+
blob=k,
|
|
51
|
+
vector3=N,
|
|
52
|
+
vector2=L,
|
|
53
|
+
vector3int16=O,
|
|
54
|
+
vector2int16=M,
|
|
55
|
+
cframe=u,
|
|
56
|
+
color3=v,
|
|
57
|
+
brickcolor=t,
|
|
58
|
+
udim=K,
|
|
59
|
+
udim2=J,
|
|
60
|
+
rect=F,
|
|
61
|
+
ray=E,
|
|
62
|
+
region3=G,
|
|
63
|
+
region3int16=H,
|
|
64
|
+
numberrange=B,
|
|
65
|
+
numbersequence=C,
|
|
66
|
+
colorsequence=w,
|
|
67
|
+
physicalproperties=D,
|
|
68
|
+
datetime=y,
|
|
69
|
+
tweeninfo=I,
|
|
70
|
+
font=A,
|
|
71
|
+
axes=s,
|
|
72
|
+
faces=z,
|
|
73
|
+
}
|
|
74
|
+
local S
|
|
75
|
+
local function compileEach(T)
|
|
76
|
+
local U={}
|
|
77
|
+
for V,W in T do
|
|
78
|
+
local X=S(W)
|
|
79
|
+
table.insert(U,X)
|
|
80
|
+
end
|
|
81
|
+
return U
|
|
82
|
+
end
|
|
83
|
+
local function compileFields(T)
|
|
84
|
+
local U={}
|
|
85
|
+
for V,W in T do
|
|
86
|
+
local X=W[1]
|
|
87
|
+
local Y=W[2]
|
|
88
|
+
local Z=S(Y)
|
|
89
|
+
local _={X,Z}
|
|
90
|
+
table.insert(U,_)
|
|
91
|
+
end
|
|
92
|
+
return U
|
|
93
|
+
end
|
|
94
|
+
local function compileVariants(T)
|
|
95
|
+
local U={}
|
|
96
|
+
for V,W in T do
|
|
97
|
+
local X=W[1]
|
|
98
|
+
local Y=W[2]
|
|
99
|
+
local Z=S(Y)
|
|
100
|
+
local _={X,Z}
|
|
101
|
+
table.insert(U,_)
|
|
102
|
+
end
|
|
103
|
+
return U
|
|
104
|
+
end
|
|
105
|
+
function S(T)
|
|
106
|
+
local U=T[1]
|
|
107
|
+
repeat
|
|
108
|
+
if U=="optional"then
|
|
109
|
+
local V=S(T[2])
|
|
110
|
+
return f(V)
|
|
111
|
+
end
|
|
112
|
+
if U=="literal"then
|
|
113
|
+
local V=T[2]
|
|
114
|
+
local W=T[3]
|
|
115
|
+
if W==P then
|
|
116
|
+
local X=V[1]
|
|
117
|
+
return o(X)
|
|
118
|
+
end
|
|
119
|
+
local X=W==Q
|
|
120
|
+
return p(V,X)
|
|
121
|
+
end
|
|
122
|
+
if U=="list"then
|
|
123
|
+
local V=S(T[2])
|
|
124
|
+
return c(V)
|
|
125
|
+
end
|
|
126
|
+
if U=="tuple"then
|
|
127
|
+
local V=compileEach(T[2])
|
|
128
|
+
return h(V)
|
|
129
|
+
end
|
|
130
|
+
if U=="set"then
|
|
131
|
+
local V=S(T[2])
|
|
132
|
+
return g(V)
|
|
133
|
+
end
|
|
134
|
+
if U=="map"then
|
|
135
|
+
local V=S(T[2])
|
|
136
|
+
local W=S(T[3])
|
|
137
|
+
return d(V,W)
|
|
138
|
+
end
|
|
139
|
+
if U=="object"then
|
|
140
|
+
local V=compileFields(T[2])
|
|
141
|
+
return e(V)
|
|
142
|
+
end
|
|
143
|
+
if U=="enum"then
|
|
144
|
+
local V=T[2]
|
|
145
|
+
return x(V)
|
|
146
|
+
end
|
|
147
|
+
if U=="union"then
|
|
148
|
+
local V=T[2]
|
|
149
|
+
local W=compileVariants(T[3])
|
|
150
|
+
return i(V,W)
|
|
151
|
+
end
|
|
152
|
+
do
|
|
153
|
+
local V=T[1]
|
|
154
|
+
local W=R[V]
|
|
155
|
+
if W==nil then
|
|
156
|
+
error(string.format('[Serialization] the schema contains an unsupported kind: %s', tostring(V)))
|
|
157
|
+
end
|
|
158
|
+
return W
|
|
159
|
+
end
|
|
160
|
+
until true
|
|
161
|
+
end
|
|
162
|
+
return{
|
|
163
|
+
compileCodec=S,
|
|
164
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AnyCodec } from "./Codec";
|
|
2
|
+
export type ObjectField = [name: string, codec: AnyCodec];
|
|
3
|
+
export type VariantEntry = [tag: defined, codec: AnyCodec];
|
|
4
|
+
export declare function optional(inner: AnyCodec): AnyCodec;
|
|
5
|
+
export declare function list(inner: AnyCodec): AnyCodec;
|
|
6
|
+
export declare function tuple(members: ReadonlyArray<AnyCodec>): AnyCodec;
|
|
7
|
+
export declare function set(inner: AnyCodec): AnyCodec;
|
|
8
|
+
export declare function map(keyCodec: AnyCodec, valueCodec: AnyCodec): AnyCodec;
|
|
9
|
+
export declare function object(fields: ReadonlyArray<ObjectField>): AnyCodec;
|
|
10
|
+
export declare function variant(discriminator: string, entries: ReadonlyArray<VariantEntry>): AnyCodec;
|