From 72eb80c82c45c0d336104fec3c2407f8811ff92a Mon Sep 17 00:00:00 2001 From: bloodwiing Date: Fri, 17 May 2024 16:27:49 +0300 Subject: [PATCH] Add: JSON Serialization and Parsing --- src/lib/serialize/base.js | 61 +++++++++++++++++++++++++++++++++ src/lib/serialize/parse.js | 69 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 src/lib/serialize/base.js create mode 100644 src/lib/serialize/parse.js diff --git a/src/lib/serialize/base.js b/src/lib/serialize/base.js new file mode 100644 index 0000000..12b23f6 --- /dev/null +++ b/src/lib/serialize/base.js @@ -0,0 +1,61 @@ +/** + * @param {string} key + * @param {any} value + * @returns {any} + */ +function replacer(key, value) { + switch (typeof value) { + case 'bigint': + return value.toString(); + + case 'object': + if (value instanceof Date) { + return value.toJSON(); + } + return value; + + default: + return value; + } +} + +/** + * @param {any} data + * @returns {string} + */ +export function jsonSerialize(data) { + return JSON.stringify(data, replacer); +} + +/** + * @template T + * @param {{[key: string]: any}} object + * @param {string} key + * @param {T} def + * @returns {T} */ +export function get(object, key, def) { + try { + return object[key]; + } catch { + return def; + } +} + +/** + * @param {{[key: string]: any}} object + * @param {string} key + * @returns {Date} */ +export function getDate(object, key) { + return new Date(Date.parse(get(object, key, (new Date()).toJSON()))); +} + +/** + * @param {{[key: string]: any}} object + * @param {string} key + * @param {{[key: string]: any} | null} def + * @param {function({[key: string]: any}): any} callback + */ +export function getObject(object, key, def, callback) { + const data = key in object ? get(object, key, def) : def; + return data ? callback(data) : null; +} diff --git a/src/lib/serialize/parse.js b/src/lib/serialize/parse.js new file mode 100644 index 0000000..b2dd341 --- /dev/null +++ b/src/lib/serialize/parse.js @@ -0,0 +1,69 @@ +import { get, getDate, getObject } from "./base"; + +/** + * @param {object} object + * @returns {import("$types/base").Rating} + */ +export function parseRating(object) { + return { + likes: BigInt(get(object, 'likes', 0)), + dislikes: BigInt(get(object, 'dislikes', 0)), + }; +} + +/** + * @param {object} object + * @returns {import("$types/base").Category} + */ +export function parseCategory(object) { + return { + id: get(object, 'id', 0), + name: get(object, 'name', ''), + }; +} + +/** + * @param {object} object + * @returns {import("$types/base").User} + */ +export function parseUser(object) { + return { + id: get(object, 'id', 0), + name: get(object, 'name', ''), + joinDate: getDate(object, 'joinDate'), + }; +} + +/** + * @param {object} object + * @returns {import("$types/base").PostMetrics} + */ +export function parsePostMetrics(object) { + return { + commentCount: BigInt(get(object, 'commentCount', 0)), + userCount: BigInt(get(object, 'userCount', 0)), + latestActivity: getDate(object, 'latestActivity'), + engagement: BigInt(get(object, 'engagement', 0)), + age: get(object, 'age', 0), + relevancy: get(object, 'relevancy', 0), + }; +} + +/** + * @param {object} object + * @returns {import("$types/base").Post} + */ +export function parsePost(object) { + return { + id: get(object, 'id', 0), + name: get(object, 'name', ''), + author: getObject(object, 'author', null, parseUser), + content: get(object, 'content', ''), + category: getObject(object, 'category', {}, parseCategory), + edited: get(object, 'edited', false), + editCount: get(object, 'editCount', 0), + postDate: getDate(object, 'postDate'), + rating: getObject(object, 'rating', {}, parseRating), + metrics: getObject(object, 'metrics', null, parsePostMetrics), + }; +}