-
Notifications
You must be signed in to change notification settings - Fork 25
/
dataHelpers.js
36 lines (29 loc) · 1.43 KB
/
dataHelpers.js
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
// @flow
import { errors } from '@tanker/core';
export type Data = ArrayBuffer | Buffer | Uint8Array;
export const getConstructor = <T: Data>(instance: T): * => {
if (instance instanceof ArrayBuffer)
return ArrayBuffer;
else if (instance instanceof Buffer) // must be before Uint8Array
return Buffer;
else if (instance instanceof Uint8Array)
return Uint8Array;
throw new Error('Assertion error: unhandled type');
};
export const assertDataType = (value: any, argName: string): void => {
if (![ArrayBuffer, Buffer, Uint8Array].some(klass => value instanceof klass))
throw new errors.InvalidArgument(argName, 'ArrayBuffer | Buffer | Uint8Array', value);
};
const casterMap = {
ArrayBuffer: (input: Buffer | Uint8Array): ArrayBuffer => (input.buffer.byteLength === input.length ? input.buffer : (new Uint8Array(input)).buffer),
Buffer: (input: ArrayBuffer | Uint8Array): Buffer => Buffer.from(input instanceof ArrayBuffer ? input : input.buffer),
Uint8Array: (input: ArrayBuffer | Buffer): Uint8Array => (input instanceof ArrayBuffer ? new Uint8Array(input) : input),
};
export const castData = <T: Data>(input: Data, outputType: Class<T>): T => {
if (input instanceof outputType)
return input;
const caster = casterMap[outputType.name];
if (!caster)
throw new errors.InvalidArgument('outputType', 'ArrayBuffer.prototype | Buffer.prototype | Uint8Array.prototype', outputType.name);
return caster(input);
};