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

feat: add createTupleson fn and more #2

Merged
merged 16 commits into from
Sep 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading