Skip to content
This repository has been archived by the owner on Jul 5, 2024. It is now read-only.

Commit

Permalink
make it an array
Browse files Browse the repository at this point in the history
  • Loading branch information
KATT committed Sep 30, 2023
1 parent 3268be9 commit d1d47fa
Show file tree
Hide file tree
Showing 18 changed files with 50 additions and 43 deletions.
7 changes: 2 additions & 5 deletions src/handlers/tsonBigint.test.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
import { expect, test } from "vitest";

import { createTupleson } from "../tson.js";
import { tsonBigint } from "./tsonBigint.js";
import { tsonMap } from "./tsonMap.js";
import { tsonSet } from "./tsonSet.js";

test("bigint", () => {
const t = createTupleson({
types: {
Map: tsonMap,
Set: tsonSet,
bigint: tsonBigint,
},
types: [tsonMap, tsonSet, tsonBigint],
});

{
Expand Down
1 change: 1 addition & 0 deletions src/handlers/tsonBigint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { TsonType } from "../types.js";

export const tsonBigint: TsonType<bigint, string> = {
deserialize: (v) => BigInt(v),
key: "bigint",
primitive: "bigint",
serialize: (v) => v.toString(),
};
5 changes: 2 additions & 3 deletions src/handlers/tsonDate.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { expect, test } from "vitest";

import { createTupleson } from "../tson.js";
import { tsonDate } from "./tsonDate.js";

test("Date", () => {
const ctx = createTupleson({
types: {
Date: tsonDate,
},
types: [tsonDate],
});

const date = new Date();
Expand Down
1 change: 1 addition & 0 deletions src/handlers/tsonDate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { TsonType } from "../types.js";

export const tsonDate: TsonType<Date, string> = {
deserialize: (value) => new Date(value),
key: "Date",
serialize: (value) => value.toJSON(),
test: (value) => value instanceof Date,
};
4 changes: 1 addition & 3 deletions src/handlers/tsonMap.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ import { tsonMap } from "./tsonMap.js";

test("Map", () => {
const t = createTupleson({
types: {
Map: tsonMap,
},
types: [tsonMap],
});

const expected = new Map([["a", "b"]]);
Expand Down
1 change: 1 addition & 0 deletions src/handlers/tsonMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { TsonType } from "../types.js";

export const tsonMap: TsonType<Map<unknown, unknown>, [unknown, unknown][]> = {
deserialize: (v) => new Map(v),
key: "Map",
serialize: (v) => Array.from(v.entries()),
test: (v) => v instanceof Map,
};
4 changes: 1 addition & 3 deletions src/handlers/tsonNumber.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ import { tsonNumber } from "./tsonNumber.js";

test("number", () => {
const t = createTupleson({
types: {
number: tsonNumber,
},
types: [tsonNumber],
});

const bad = [
Expand Down
5 changes: 2 additions & 3 deletions src/handlers/tsonRegExp.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { expect, test } from "vitest";

import { createTupleson } from "../tson.js";
import { tsonRegExp } from "./index.js";

test("regex", () => {
const t = createTupleson({
types: {
RegExp: tsonRegExp,
},
types: [tsonRegExp],
});

const expected = /foo/g;
Expand Down
1 change: 1 addition & 0 deletions src/handlers/tsonRegExp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export const tsonRegExp: TsonType<RegExp, string> = {
const flags = str.slice(str.lastIndexOf("/") + 1);
return new RegExp(body, flags);
},
key: "RegExp",
serialize: (value) => "" + value,
test: (value) => value instanceof RegExp,
};
4 changes: 1 addition & 3 deletions src/handlers/tsonSet.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ import { tsonSet } from "./tsonSet.js";

test("Set", () => {
const t = createTupleson({
types: {
Set: tsonSet,
},
types: [tsonSet],
});

const expected = new Set(["a", "b"]);
Expand Down
1 change: 1 addition & 0 deletions src/handlers/tsonSet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { TsonType } from "../types.js";

export const tsonSet: TsonType<Set<unknown>, unknown[]> = {
deserialize: (v) => new Set(v),
key: "Set",
serialize: (v) => Array.from(v),
test: (v) => v instanceof Set,
};
4 changes: 1 addition & 3 deletions src/handlers/tsonUndefined.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ import { tsonUndefined } from "./tsonUndefined.js";

test("undefined", () => {
const ctx = createTupleson({
types: {
undefined: tsonUndefined,
},
types: [tsonUndefined],
});

const expected = {
Expand Down
1 change: 1 addition & 0 deletions src/handlers/tsonUndefined.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { TsonType } from "../types.js";

export const tsonUndefined: TsonType<undefined, 0> = {
deserialize: () => undefined,
key: "undefined",
primitive: "undefined",
serialize: () => 0,
};
9 changes: 5 additions & 4 deletions src/handlers/tsonUnknown.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { assert, expect, test } from "vitest";

import { expectError } from "../testUtils.js";
import { createTupleson } from "../tson.js";
import { tsonSet } from "./tsonSet.js";
Expand All @@ -7,11 +8,11 @@ import { UnknownObjectGuardError, tsonUnknown } from "./tsonUnknown.js";
test("guard unwanted objects", () => {
// Sets are okay, but not Maps
const t = createTupleson({
types: {
Set: tsonSet,
types: [
tsonSet,
// defined last so it runs last
unknownObjectGuard: tsonUnknown,
},
tsonUnknown,
],
});

{
Expand Down
7 changes: 1 addition & 6 deletions src/stringify.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,7 @@ import { createTupleson } from "./tson.js";

test("lets have a look at the stringified output", () => {
const t = createTupleson({
types: {
Map: tsonMap,
Set: tsonSet,
bigint: tsonBigint,
undefined: tsonUndefined,
},
types: [tsonMap, tsonSet, tsonBigint, tsonUndefined],
});

const expected = new Set([
Expand Down
23 changes: 17 additions & 6 deletions src/tson.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,24 @@ function isTsonTuple(v: unknown, nonce: string): v is TsonTuple {
type WalkFn = (value: unknown) => unknown;
type WalkerFactory = (nonce: TsonNonce) => WalkFn;

type AnyTsonTransformerSerializeDeserialize =
TsonTransformerSerializeDeserialize<any, any>;

export function tsonDeserializer(opts: TsonOptions): TsonDeserializeFn {
const typeByKey: Record<string, AnyTsonTransformerSerializeDeserialize> = {};

for (const handler of opts.types) {
if (handler.key) {
typeByKey[handler.key] =
handler as AnyTsonTransformerSerializeDeserialize;
}
}

const walker: WalkerFactory = (nonce) => {
const walk: WalkFn = (value) => {
if (isTsonTuple(value, nonce)) {
const [type, serializedValue] = value;
const transformer = opts.types[
type
] as TsonTransformerSerializeDeserialize<any, any>;
const transformer = typeByKey[type];
return transformer.deserialize(walk(serializedValue));
}

Expand Down Expand Up @@ -63,8 +73,8 @@ export function tsonStringifier(opts: TsonOptions): TsonStringifyFn {
export function tsonSerializer(opts: TsonOptions): TsonSerializeFn {
const handlers = (() => {
// warmup the type handlers
const types = Object.entries(opts.types).map(([_key, handler]) => {
const key = _key as TsonTypeHandlerKey;
const types = opts.types.map((handler) => {
const key = handler.key as TsonTypeHandlerKey | undefined;
const serialize = handler.serialize;

type Serializer = (
Expand All @@ -75,7 +85,8 @@ export function tsonSerializer(opts: TsonOptions): TsonSerializeFn {

const $serialize: Serializer = serialize
? (value, nonce, walk): TsonTuple => [
key,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
key!,
walk(serialize(value)),
nonce,
]
Expand Down
4 changes: 1 addition & 3 deletions src/types.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ import { createTupleson } from "./tson.js";

test("types", () => {
const t = createTupleson({
types: {
bigint: tsonBigint,
},
types: [tsonBigint],
});

const expected = 1n;
Expand Down
11 changes: 10 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,12 @@ type SerializedType =
export interface TsonTransformerNone {
deserialize?: never;

/**
* The key to use when serialized
*/
key?: never;
serialize?: never;

/**
* Won't be deserialized nor serialized
*/
Expand All @@ -46,6 +51,10 @@ export interface TsonTransformerSerializeDeserialize<
*/
deserialize: (v: TSerializedType) => TValue;

/**
* The key to use when serialized
*/
key: string;
/**
* JSON-serializable value
*/
Expand Down Expand Up @@ -96,7 +105,7 @@ export type TsonType<

export interface TsonOptions {
nonce?: () => string;
types: Record<string, TsonType<any, any> | TsonType<any, never>>;
types: (TsonType<any, any> | TsonType<any, never>)[];
}

const serialized = Symbol("serialized");
Expand Down

0 comments on commit d1d47fa

Please sign in to comment.