-
Notifications
You must be signed in to change notification settings - Fork 0
/
props.ts
37 lines (35 loc) · 1.04 KB
/
props.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import { BufferCodec, FieldsOf } from "../types";
/**
* A codec for parsing a Buffer into an object. Fields are executed in the
* order they are specified.
*
* @example
* const userCodec = fields({
* userId: number.UInt8,
* foo: number.UInt16LE
* })
*/
export const props = <T, C>(fields: FieldsOf<T, C>): BufferCodec<T, C> => {
const fieldEntries = Object.entries(fields) as [
keyof T,
BufferCodec<any, C>
][];
return {
parse: (buffer, context = {} as C) =>
fieldEntries.reduce(
({ value, byteLength }, [name, { parse }]) => {
const view = buffer.slice(byteLength);
const result = parse(view, { ...context, ...value });
return {
value: { ...value, [name]: result.value },
byteLength: byteLength + result.byteLength,
};
},
{ value: {}, byteLength: 0 }
) as { value: T; byteLength: number },
serialize: (parsed) =>
Buffer.concat(
fieldEntries.map(([name, { serialize }]) => serialize(parsed[name]))
),
};
};