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

Commit

Permalink
feat: add createTupleson fn and more (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
KATT authored Sep 30, 2023
1 parent ccce25b commit 6fecdce
Show file tree
Hide file tree
Showing 30 changed files with 550 additions and 464 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
],
"scripts": {
"build": "tsup",
"fix": "pnpm lint --fix && pnpm format:write",
"format": "prettier \"**/*\" --ignore-unknown",
"format:write": "pnpm format --write",
"lint": "eslint . .*js --max-warnings 0 --report-unused-disable-directives",
Expand All @@ -32,6 +33,7 @@
},
"devDependencies": {
"@release-it/conventional-changelog": "^7.0.2",
"@tsconfig/strictest": "^2.0.2",
"@types/eslint": "^8.44.3",
"@typescript-eslint/eslint-plugin": "^6.7.3",
"@typescript-eslint/parser": "^6.7.3",
Expand Down
7 changes: 7 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

83 changes: 0 additions & 83 deletions src/handlers.ts

This file was deleted.

8 changes: 8 additions & 0 deletions src/handlers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export * from "./tsonBigint.js";
export * from "./tsonDate.js";
export * from "./tsonRegExp.js";
export * from "./tsonSet.js";
export * from "./tsonMap.js";
export * from "./tsonUndefined.js";
export * from "./tsonUnknownObjectGuard.js";
export * from "./tsonNumber.js";
42 changes: 42 additions & 0 deletions src/handlers/tsonBigint.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
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: [tsonMap, tsonSet, tsonBigint],
});

{
// bigint
const expected = 1n;

const stringified = t.stringify(expected);
const deserialized = t.parse(stringified);

expect(deserialized).toEqual(expected);

{
// set of BigInt
const expected = new Set([1n]);

const stringified = t.stringify(expected);
const deserialized = t.parse(stringified);

expect(deserialized).toEqual(expected);
}

{
// set of a map of bigint
const expected = new Set([new Map([["a", 1n]])]);

const stringified = t.stringify(expected);
const deserialized = t.parse(stringified);

expect(deserialized).toEqual(expected);
}
}
});
8 changes: 8 additions & 0 deletions src/handlers/tsonBigint.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { TsonType } from "../types.js";

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

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

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

const date = new Date();

const stringified = ctx.stringify(date);
const deserialized = ctx.parse(stringified);
expect(deserialized).toEqual(date);
});
8 changes: 8 additions & 0 deletions src/handlers/tsonDate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
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,
};
16 changes: 16 additions & 0 deletions src/handlers/tsonMap.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { expect, test } from "vitest";

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

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

const expected = new Map([["a", "b"]]);

const stringified = t.stringify(expected);
const deserialized = t.parse(stringified);
expect(deserialized).toEqual(expected);
});
8 changes: 8 additions & 0 deletions src/handlers/tsonMap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
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,
};
39 changes: 39 additions & 0 deletions src/handlers/tsonNumber.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { expect, test } from "vitest";

import { expectError } from "../testUtils.js";
import { createTupleson } from "../tson.js";
import { tsonNumber } from "./tsonNumber.js";

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

const bad = [
//
NaN,
Infinity,
-Infinity,
];
const good = [1, 0, -1, 1.1, -1.1];

const errors: unknown[] = [];

for (const n of bad) {
const err = expectError(() => t.parse(t.stringify(n)));
errors.push(err);
}

expect(errors).toMatchInlineSnapshot(`
[
[Error: Encountered NaN],
[Error: Encountered Infinity],
[Error: Encountered Infinity],
]
`);

for (const n of good) {
const deserialized = t.parse(t.stringify(n));
expect(deserialized).toEqual(n);
}
});
21 changes: 21 additions & 0 deletions src/handlers/tsonNumber.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { TsonType } from "../types.js";

/**
* Prevents `NaN` and `Infinity` from being serialized
*/

export const tsonNumber: TsonType<number, number> = {
primitive: "number",
test: (v) => {
const value = v as number;
if (isNaN(value)) {
throw new Error("Encountered NaN");
}

if (!isFinite(value)) {
throw new Error("Encountered Infinity");
}

return false;
},
};
33 changes: 33 additions & 0 deletions src/handlers/tsonRegExp.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { expect, test } from "vitest";

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

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

const expected = /foo/g;

const stringified = t.stringify(expected, 2);

expect(stringified).toMatchInlineSnapshot(
`
"{
\\"json\\": [
\\"RegExp\\",
\\"/foo/g\\",
\\"__tson\\"
],
\\"nonce\\": \\"__tson\\"
}"
`,
);

const deserialized = t.parse(stringified);

expect(deserialized).toBeInstanceOf(RegExp);
expect(deserialized).toMatchInlineSnapshot("/foo/g");
expect(deserialized + "").toEqual(expected + "");
});
12 changes: 12 additions & 0 deletions src/handlers/tsonRegExp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { TsonType } from "../types.js";

export const tsonRegExp: TsonType<RegExp, string> = {
deserialize: (str) => {
const body = str.slice(1, str.lastIndexOf("/"));
const flags = str.slice(str.lastIndexOf("/") + 1);
return new RegExp(body, flags);
},
key: "RegExp",
serialize: (value) => "" + value,
test: (value) => value instanceof RegExp,
};
16 changes: 16 additions & 0 deletions src/handlers/tsonSet.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { expect, test } from "vitest";

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

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

const expected = new Set(["a", "b"]);

const stringified = t.stringify(expected);
const deserialized = t.parse(stringified);
expect(deserialized).toEqual(expected);
});
8 changes: 8 additions & 0 deletions src/handlers/tsonSet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
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,
};
Loading

0 comments on commit 6fecdce

Please sign in to comment.