Skip to content

Commit

Permalink
Merge pull request #2 from ungap/deserializer
Browse files Browse the repository at this point in the history
using similar serializer pattern
  • Loading branch information
WebReflection authored Nov 7, 2021
2 parents 14ca0a4 + e75e9e5 commit a4e4e0a
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 103 deletions.
105 changes: 54 additions & 51 deletions cjs/deserialize.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,60 +5,63 @@ const {

const env = typeof self === 'object' ? self : globalThis;

const _deserialize = (index, $, _) => {
if ($.has(index))
return $.get(index);
const deserializer = ($, _) => {
const as = (out, index) => {
$.set(index, out);
return out;
};

const [type, value] = _[index];
const unpair = index => {
if ($.has(index))
return $.get(index);

const as = deserialized => {
$.set(index, deserialized);
return deserialized;
const [type, value] = _[index];
switch (type) {
case PRIMITIVE:
return as(value, index);
case ARRAY: {
const arr = as([], index);
for (const index of value)
arr.push(unpair(index));
return arr;
}
case OBJECT: {
const object = as({}, index);
for (const [key, index] of value)
object[unpair(key)] = unpair(index);
return object;
}
case DATE:
return as(new Date(value), index);
case REGEXP: {
const {source, flags} = value;
return as(new RegExp(source, flags), index);
}
case MAP: {
const map = as(new Map, index);
for (const [key, index] of value)
map.set(unpair(key), unpair(index));
return map;
}
case SET: {
const set = as(new Set, index);
for (const index of value)
set.add(unpair(index));
return set;
}
case ERROR: {
const {name, message} = value;
return as(new env[name](message), index);
}
case BIGINT:
return as(BigInt(value), index);
case 'BigInt':
return as(Object(BigInt(value)), index);
}
return as(new env[type](value), index);
};

switch (type) {
case PRIMITIVE:
return as(value);
case ARRAY: {
const arr = as([]);
for (const index of value)
arr.push(_deserialize(index, $, _));
return arr;
}
case OBJECT: {
const object = as({});
for (const [key, index] of value)
object[_deserialize(key, $, _)] = _deserialize(index, $, _);
return object;
}
case DATE:
return as(new Date(value));
case REGEXP: {
const {source, flags} = value;
return as(new RegExp(source, flags));
}
case MAP: {
const map = as(new Map);
for (const [key, index] of value)
map.set(_deserialize(key, $, _), _deserialize(index, $, _));
return map;
}
case SET: {
const set = as(new Set);
for (const index of value)
set.add(_deserialize(index, $, _));
return set;
}
case ERROR: {
const {name, message} = value;
return as(new env[name](message));
}
case BIGINT:
return as(BigInt(value));
case 'BigInt':
return as(Object(BigInt(value)));
}
return as(new env[type](value));
return unpair;
};

/**
Expand All @@ -70,5 +73,5 @@ const _deserialize = (index, $, _) => {
* @param {Record[]} serialized a previously serialized value.
* @returns {any}
*/
const deserialize = serialized => _deserialize(0, new Map, serialized);
const deserialize = serialized => deserializer(new Map, serialized)(0);
exports.deserialize = deserialize;
105 changes: 54 additions & 51 deletions esm/deserialize.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,60 +6,63 @@ import {

const env = typeof self === 'object' ? self : globalThis;

const _deserialize = (index, $, _) => {
if ($.has(index))
return $.get(index);
const deserializer = ($, _) => {
const as = (out, index) => {
$.set(index, out);
return out;
};

const [type, value] = _[index];
const unpair = index => {
if ($.has(index))
return $.get(index);

const as = deserialized => {
$.set(index, deserialized);
return deserialized;
const [type, value] = _[index];
switch (type) {
case PRIMITIVE:
return as(value, index);
case ARRAY: {
const arr = as([], index);
for (const index of value)
arr.push(unpair(index));
return arr;
}
case OBJECT: {
const object = as({}, index);
for (const [key, index] of value)
object[unpair(key)] = unpair(index);
return object;
}
case DATE:
return as(new Date(value), index);
case REGEXP: {
const {source, flags} = value;
return as(new RegExp(source, flags), index);
}
case MAP: {
const map = as(new Map, index);
for (const [key, index] of value)
map.set(unpair(key), unpair(index));
return map;
}
case SET: {
const set = as(new Set, index);
for (const index of value)
set.add(unpair(index));
return set;
}
case ERROR: {
const {name, message} = value;
return as(new env[name](message), index);
}
case BIGINT:
return as(BigInt(value), index);
case 'BigInt':
return as(Object(BigInt(value)), index);
}
return as(new env[type](value), index);
};

switch (type) {
case PRIMITIVE:
return as(value);
case ARRAY: {
const arr = as([]);
for (const index of value)
arr.push(_deserialize(index, $, _));
return arr;
}
case OBJECT: {
const object = as({});
for (const [key, index] of value)
object[_deserialize(key, $, _)] = _deserialize(index, $, _);
return object;
}
case DATE:
return as(new Date(value));
case REGEXP: {
const {source, flags} = value;
return as(new RegExp(source, flags));
}
case MAP: {
const map = as(new Map);
for (const [key, index] of value)
map.set(_deserialize(key, $, _), _deserialize(index, $, _));
return map;
}
case SET: {
const set = as(new Set);
for (const index of value)
set.add(_deserialize(index, $, _));
return set;
}
case ERROR: {
const {name, message} = value;
return as(new env[name](message));
}
case BIGINT:
return as(BigInt(value));
case 'BigInt':
return as(Object(BigInt(value)));
}
return as(new env[type](value));
return unpair;
};

/**
Expand All @@ -71,4 +74,4 @@ const _deserialize = (index, $, _) => {
* @param {Record[]} serialized a previously serialized value.
* @returns {any}
*/
export const deserialize = serialized => _deserialize(0, new Map, serialized);
export const deserialize = serialized => deserializer(new Map, serialized)(0);
2 changes: 1 addition & 1 deletion structured-json.js

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

0 comments on commit a4e4e0a

Please sign in to comment.