|
1 | | -import { AnyShape, createShape, Expand, Input, metadata, Output, Shape, ShapeVisitor, U2I } from "../common/mod.ts" |
2 | | -import { constant } from "./constant.ts" |
| 1 | +import { |
| 2 | + AnyShape, |
| 3 | + createShape, |
| 4 | + DecodeBuffer, |
| 5 | + EncodeBuffer, |
| 6 | + Expand, |
| 7 | + Input, |
| 8 | + metadata, |
| 9 | + Output, |
| 10 | + Shape, |
| 11 | + U2I |
| 12 | +} from "../common/mod.ts" |
3 | 13 | import { option } from "./option.ts" |
4 | 14 |
|
5 | 15 | export function field<K extends keyof any, VI, VO>(key: K, $value: Shape<VI, VO>): Shape< |
@@ -70,7 +80,7 @@ type UnionKeys<T> = T extends T ? keyof T : never |
70 | 80 | export type ObjectMembers<T extends AnyShape[]> = [ |
71 | 81 | ...never extends T ? { |
72 | 82 | [K in keyof T]: AnyShape extends T[K] ? AnyShape |
73 | | - : |
| 83 | + : |
74 | 84 | & UnionKeys<Input<T[K]>> |
75 | 85 | & { |
76 | 86 | [L in keyof T]: K extends L ? never : UnionKeys<Input<T[L]>> |
@@ -98,82 +108,17 @@ export function object<T extends AnyShape[]>(...members: ObjectMembers<T>): Shap |
98 | 108 | } |
99 | 109 |
|
100 | 110 | function generateEncode(members: Shape<any>[]) { |
101 | | - const vars: string[] = [] |
102 | | - const args: unknown[] = [] |
103 | | - |
104 | | - const valueVisitor = new ShapeVisitor<(v: string) => string>() |
105 | | - valueVisitor.add(constant, (shape, value, pattern) => (v) => { |
106 | | - if (pattern) { |
107 | | - return `${addVar(shape)}.subEncode(buffer, ${v})` |
108 | | - } |
109 | | - return addVar(value) |
110 | | - }) |
111 | | - valueVisitor.fallback((shape) => (v) => { |
112 | | - return `${addVar(shape)}.subEncode(buffer, ${v})` |
113 | | - }) |
114 | | - |
115 | | - const fieldVisitor = new ShapeVisitor<string>() |
116 | | - fieldVisitor.add(field, (_, key, value) => { |
117 | | - return valueVisitor.visit(value)(`value[${typeof key === "symbol" ? addVar(key) : JSON.stringify(key)}]`) |
118 | | - }) |
119 | | - fieldVisitor.add(optionalField, (_, key, value) => { |
120 | | - return fieldVisitor.visit(field(key, option(value))) |
121 | | - }) |
122 | | - fieldVisitor.add(object, (_, ...members) => { |
123 | | - return members.map((x) => fieldVisitor.visit(x)).join(";") |
124 | | - }) |
125 | | - fieldVisitor.fallback((shape) => { |
126 | | - return `${addVar(shape)}.subEncode(buffer, value)` |
127 | | - }) |
128 | | - |
129 | | - const content = members.map((x) => fieldVisitor.visit(x)).join(";") |
130 | | - |
131 | | - return (new Function(...vars, `return function objectEncode(buffer,value){${content}}`))(...args) |
132 | | - |
133 | | - function addVar(value: unknown) { |
134 | | - const v = "v" + vars.length |
135 | | - vars.push(v) |
136 | | - args.push(value) |
137 | | - return v |
| 111 | + return (buffer: EncodeBuffer, value: any) => { |
| 112 | + members.forEach(member => { |
| 113 | + member.subEncode(buffer, value); |
| 114 | + }); |
138 | 115 | } |
139 | 116 | } |
140 | 117 |
|
141 | 118 | function generateDecode(members: Shape<any>[]) { |
142 | | - const vars: string[] = [] |
143 | | - const args: unknown[] = [] |
144 | | - |
145 | | - const valueVisitor = new ShapeVisitor<string>() |
146 | | - valueVisitor.add(constant, (shape, value, pattern) => { |
147 | | - if (pattern) { |
148 | | - return `${addVar(shape)}.subDecode(buffer)` |
149 | | - } |
150 | | - return addVar(value) |
151 | | - }) |
152 | | - valueVisitor.fallback((shape) => { |
153 | | - return `${addVar(shape)}.subDecode(buffer)` |
154 | | - }) |
155 | | - const fieldVisitor = new ShapeVisitor<string>() |
156 | | - fieldVisitor.add(field, (_, key, value) => { |
157 | | - return `[${typeof key === "symbol" ? addVar(key) : JSON.stringify(key)}]: ${valueVisitor.visit(value)}` |
158 | | - }) |
159 | | - fieldVisitor.add(optionalField, (_, key, value) => { |
160 | | - return `...buffer.array[buffer.index++] ? {${fieldVisitor.visit(field(key, value))} } : undefined` |
161 | | - }) |
162 | | - fieldVisitor.add(object, (_, ...members) => { |
163 | | - return members.map((x) => fieldVisitor.visit(x)).join(",") |
164 | | - }) |
165 | | - fieldVisitor.fallback((shape) => { |
166 | | - return `...${addVar(shape)}.subDecode(buffer)` |
167 | | - }) |
168 | | - |
169 | | - const content = members.map((x) => fieldVisitor.visit(x)).join(",") |
170 | | - |
171 | | - return (new Function(...vars, `return function objectDecode(buffer){return{${content}}}`))(...args) |
172 | | - |
173 | | - function addVar(value: unknown) { |
174 | | - const v = "v" + vars.length |
175 | | - vars.push(v) |
176 | | - args.push(value) |
177 | | - return v |
| 119 | + return (buffer: DecodeBuffer) => { |
| 120 | + return members.reduce((o, member) => { |
| 121 | + return { ...o, ...member.subDecode(buffer) } |
| 122 | + }, {} as any); |
178 | 123 | } |
179 | 124 | } |
0 commit comments