Skip to content

Commit

Permalink
feat: serialize and parse ComposedKeySet to allow for array of keySet…
Browse files Browse the repository at this point in the history
…s as input
  • Loading branch information
eturino committed Jan 9, 2025
1 parent d0c0213 commit 5b0791b
Show file tree
Hide file tree
Showing 2 changed files with 191 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
type ComposedKeySetSerialized,
type IKeyLabel,
InvalidKeySetError,
type KeyLabelSet,
type KeyLabelSetAll,
type KeyLabelSetAllExceptSome,
type KeyLabelSetAllExceptSomeSerialized,
Expand Down Expand Up @@ -46,7 +47,7 @@ import {
serializeKeyLabelSet,
serializeKeySet,
some,
} from "../..";
} from "../../..";

const allSerialized: KeySetAllSerialized = { type: KeySetTypes.all };
const noneSerialized: KeySetNoneSerialized = { type: KeySetTypes.none };
Expand Down Expand Up @@ -606,6 +607,7 @@ describe("serialize KeySet", () => {
};

const composedSerialized: KeySetSerialized[] = [keySetSerialized1, keySetSerialized2];
const arrayKeySets: KeySet[] = [keySet1, keySet2];
const composedKeySet = composedKeySetFrom([keySet1, keySet2]);

describe("isComposedKeySetSerialized()", () => {
Expand All @@ -618,6 +620,9 @@ describe("serialize KeySet", () => {
it("isComposedKeySetSerialized(keySet) -> NOPE", () => {
expect(isComposedKeySetSerialized(keySet1)).toBeFalsy();
});
it("isComposedKeySetSerialized(arrayKeySets) -> NOPE", () => {
expect(isComposedKeySetSerialized(arrayKeySets)).toBeFalsy();
});
it("isComposedKeySetSerialized(keySetSerialized) -> NOPE", () => {
expect(isComposedKeySetSerialized(keySetSerialized1)).toBeFalsy();
});
Expand All @@ -633,26 +638,42 @@ describe("serialize KeySet", () => {
it("serializeComposedKeySet(composedSerialized) -> return same", () => {
expect(serializeComposedKeySet(composedSerialized)).toBe(composedSerialized);
});
it("serializeComposedKeySet(arrayKeySets) -> serialize each", () => {
expect(serializeComposedKeySet(arrayKeySets)).toEqual(composedSerialized);
});
it("serializeComposedKeySet(composedKeySet) -> serialize each", () => {
expect(serializeComposedKeySet(composedKeySet)).toEqual(composedSerialized);
});
it("serializeComposedKeySet(invalid) -> throw", () => {
expect(() => serializeComposedKeySet(new Date() as unknown as ComposedKeySetSerialized)).toThrow();
});
it("serializeComposedKeySet(invalid element in array) -> throw", () => {
expect(() =>
serializeComposedKeySet([keySet1, new Date(), keySet2] as unknown as ComposedKeySetSerialized),
).toThrow();
});
it("composedKeySet.serialized() -> serialize each", () => {
expect(composedKeySet.serialized()).toEqual(composedSerialized);
});
});

describe("parseComposedKeySet()", () => {
it("parseComposedKeySet() with key sets", () => {
it("parseComposedKeySet() with composedKeySetSerialized", () => {
expect(parseComposedKeySet(composedSerialized)).toEqual(composedKeySet);
});
it("parseComposedKeySet() with a list of keySets", () => {
expect(parseComposedKeySet(arrayKeySets)).toEqual(composedKeySet);
});
it("parseComposedKeySet() with empty list", () => {
expect(parseComposedKeySet([])).toEqual(composedKeySetFrom([]));
});
it("parseComposedKeySet() with an already composedKeySet", () => {
expect(parseComposedKeySet(composedKeySet)).toBe(composedKeySet);
});

it("parseComposedKeySet() with empty list", () => {
it("parseComposedKeySet() with invalid argument", () => {
expect(() => parseComposedKeySet({ invalid: "stuff" } as unknown as ComposedKeySetSerialized)).toThrow();
});
it("parseComposedKeySet() with invalid elements", () => {
expect(() => parseComposedKeySet([{ invalid: "stuff" }] as unknown as ComposedKeySetSerialized)).toThrow();
});
});
Expand Down Expand Up @@ -685,6 +706,7 @@ describe("serialize KeySet", () => {
};

const composedSerialized: KeyLabelSetSerialized[] = [keySetSerialized1, keySetSerialized2];
const arrayKeySets: KeyLabelSet[] = [keySet1, keySet2];
const composedKeyLabelSet = composedKeySetFrom([keySet1, keySet2]);

describe("isComposedKeyLabelSetSerialized()", () => {
Expand All @@ -697,6 +719,9 @@ describe("serialize KeySet", () => {
it("isComposedKeyLabelSetSerialized(keySet) -> NOPE", () => {
expect(isComposedKeyLabelSetSerialized(keySet1)).toBeFalsy();
});
it("isComposedKeyLabelSetSerialized(arrayKeySets) -> NOPE", () => {
expect(isComposedKeyLabelSetSerialized(arrayKeySets)).toBeFalsy();
});
it("isComposedKeyLabelSetSerialized(keySetSerialized) -> NOPE", () => {
expect(isComposedKeyLabelSetSerialized(keySetSerialized1)).toBeFalsy();
});
Expand All @@ -706,6 +731,9 @@ describe("serialize KeySet", () => {
it("isComposedKeyLabelSetSerialized(composedKeyLabelSet) -> NOPE", () => {
expect(isComposedKeyLabelSetSerialized(keySet1)).toBeFalsy();
});
it("isComposedKeyLabelSetSerialized(invalid) -> NOPE", () => {
expect(isComposedKeyLabelSetSerialized(new Date())).toBeFalsy();
});
});

describe("serializeComposedKeyLabelSet()", () => {
Expand All @@ -715,6 +743,37 @@ describe("serialize KeySet", () => {
it("serializeComposedKeyLabelSet(composedKeyLabelSet) -> serialize each", () => {
expect(serializeComposedKeyLabelSet(composedKeyLabelSet)).toEqual(composedSerialized);
});
it("serializeComposedKeyLabelSet(arrayKeySets) -> serialize each", () => {
expect(serializeComposedKeyLabelSet(arrayKeySets)).toEqual(composedSerialized);
});
it("serializeComposedKeyLabelSet(invalid) -> throw", () => {
expect(() => serializeComposedKeyLabelSet(new Date() as unknown as KeyLabelSetSerialized[])).toThrow();
});
it("serializeComposedKeyLabelSet(invalid) -> throw", () => {
expect(() =>
serializeComposedKeyLabelSet([keySet1, new Date(), keySetSerialized2] as unknown as KeyLabelSetSerialized[]),
).toThrow();
});
it("serializeComposedKeyLabelSet(composedKeySet not of KeyLabels) -> throw", () => {
expect(() =>
serializeComposedKeyLabelSet(
composedKeySetFrom([allExceptSome([1, 2]), some([1, 2])]) as unknown as KeyLabelSetSerialized[],
),
).toThrow();
});
it("serializeComposedKeyLabelSet(array not of KeyLabels) -> throw", () => {
expect(() =>
serializeComposedKeyLabelSet([allExceptSome([1, 2]), some([1, 2])] as unknown as KeyLabelSetSerialized[]),
).toThrow();
});
it("serializeComposedKeyLabelSet(array not of KeyLabel serialized) -> throw", () => {
expect(() =>
serializeComposedKeyLabelSet([
allExceptSome([1, 2]).serialized(),
some([1, 2]).serialized(),
] as unknown as KeyLabelSetSerialized[]),
).toThrow();
});
it("composedKeyLabelSet.serialized() -> serialize each", () => {
expect(composedKeyLabelSet.serialized()).toEqual(composedSerialized);
});
Expand All @@ -724,18 +783,43 @@ describe("serialize KeySet", () => {
it("parseComposedKeyLabelSet() with key sets", () => {
expect(parseComposedKeyLabelSet(composedSerialized)).toEqual(composedKeyLabelSet);
});
it("parseComposedKeyLabelSet() with arrayKeySets", () => {
expect(parseComposedKeyLabelSet(arrayKeySets)).toEqual(composedKeyLabelSet);
});
it("parseComposedKeyLabelSet() with empty list", () => {
expect(parseComposedKeyLabelSet([])).toEqual(composedKeySetFrom([]));
});
it("parseComposedKeyLabelSet() with an already composedKeyLabelSet", () => {
expect(parseComposedKeyLabelSet(composedKeyLabelSet)).toBe(composedKeyLabelSet);
});

it("parseComposedKeyLabelSet() with empty list", () => {
it("parseComposedKeyLabelSet() with key set not keyLabelSet", () => {
expect(() =>
parseComposedKeyLabelSet([allExceptSome([1, 2])] as unknown as ComposedKeyLabelSetSerialized),
).toThrow();
});
it("parseComposedKeyLabelSet() with composedKeySet not keyLabelSet", () => {
expect(() =>
parseComposedKeyLabelSet(
composedKeySetFrom([allExceptSome([1, 2])]) as unknown as ComposedKeyLabelSetSerialized,
),
).toThrow();
});
it("parseComposedKeyLabelSet() with key set not keyLabelSet serialized", () => {
expect(() =>
parseComposedKeyLabelSet([allExceptSome([1, 2]).serialized()] as unknown as ComposedKeyLabelSetSerialized),
).toThrow();
});
it("parseComposedKeyLabelSet() with invalid element", () => {
expect(() =>
parseComposedKeyLabelSet([{ invalid: "stuff" }] as unknown as ComposedKeyLabelSetSerialized),
).toThrow();
});
it("parseComposedKeyLabelSet() with invalid", () => {
expect(() =>
parseComposedKeyLabelSet({ invalid: "stuff" } as unknown as ComposedKeyLabelSetSerialized),
).toThrow();
});
});
});
});
117 changes: 102 additions & 15 deletions src/lib/key-set/serialize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,17 +132,69 @@ export function isComposedKeyLabelSetSerialized(x: unknown): x is ComposedKeyLab
}

export function serializeComposedKeySet<T extends Key>(
x: ComposedKeySet<T> | ComposedKeySetSerialized<T>,
x: ComposedKeySet<T> | ComposedKeySetSerialized<T> | Array<KeySet<T>>,
): ComposedKeySetSerialized<T> {
if (isComposedKeySetSerialized(x)) return x;
return x.serialized();
if (isComposedKeySet(x)) return x.serialized();
if (Array.isArray(x)) {
let allSerialized = true;
const newList: KeySetSerialized<T>[] = [];
for (const ks of x) {
if (isKeySet(ks)) {
allSerialized = false;
newList.push(ks.serialized());
} else if (isKeySetSerialized(ks)) {
newList.push(ks);
} else {
// ERROR: invalid element
throw new InvalidKeySetError(
`ComposedKeySet or array of key sets expected. Invalid element found ${JSON.stringify(ks)}. Full argument given ${JSON.stringify(x)}`,
);
}
}

// if all elements are already serialized, return the original array, reusing the same instance in memory
return allSerialized ? (x as ComposedKeySetSerialized<T>) : newList;
}

// not recognised: error
throw new InvalidKeySetError(`ComposedKeySet expected, given ${JSON.stringify(x)}`);
}

export function serializeComposedKeyLabelSet<T extends string | number>(
x: ComposedKeyLabelSet<T> | ComposedKeyLabelSetSerialized<T>,
x: ComposedKeyLabelSet<T> | ComposedKeyLabelSetSerialized<T> | Array<KeyLabelSet<T>>,
): ComposedKeyLabelSetSerialized<T> {
if (isComposedKeyLabelSetSerialized(x)) return x;
return x.serialized();
if (isComposedKeySet(x)) {
if (isComposedKeyLabelSet(x)) {
return x.serialized();
}
throw new InvalidKeySetError(
`ComposedKeyLabelSet expected, a ComposedKeySet with no KeyLabels given ${JSON.stringify(x)}`,
);
}

if (Array.isArray(x)) {
let allSerialized = true;
const newList: KeyLabelSetSerialized<T>[] = [];
for (const ks of x) {
if (isKeyLabelSet(ks)) {
allSerialized = false;
newList.push(ks.serialized());
} else if (isKeyLabelSetSerialized(ks)) {
newList.push(ks);
} else {
// ERROR: invalid element
throw new InvalidKeySetError(
`ComposedKeyLabelSet or array of key sets expected. Invalid element found ${JSON.stringify(ks)}. Full argument given ${JSON.stringify(x)}`,
);
}
}

// if all elements are already serialized, return the original array, reusing the same instance in memory
return allSerialized ? (x as ComposedKeySetSerialized<T>) : newList;
}

// not recognised: error
throw new InvalidKeySetError(`ComposedKeySet expected, given ${JSON.stringify(x)}`);
}

export function serializeKeySet<T extends string | number>(
Expand Down Expand Up @@ -177,27 +229,62 @@ export function serializeKeySet<T extends Key>(keySet: KeySet<T> | KeySetSeriali
export const serializeKeyLabelSet = serializeKeySet;

export function parseComposedKeySet<T extends Key>(
x: ComposedKeySetSerialized<T> | ComposedKeySet<T>,
x: ComposedKeySetSerialized<T> | ComposedKeySet<T> | Array<KeySet<T>>,
): ComposedKeySet<T> {
if (isComposedKeySet(x)) return x;

if (!isComposedKeySetSerialized(x)) {
throw new InvalidKeySetError(`composedKeySetSerialized expected, given ${JSON.stringify(x)}`);
if (Array.isArray(x)) {
const newList: KeySet<T>[] = [];
for (const ks of x) {
if (isKeySet(ks)) {
newList.push(ks.clone());
} else if (isKeySetSerialized(ks)) {
newList.push(parseKeySet<T>(ks));
} else {
// ERROR: invalid element
throw new InvalidKeySetError(
`ComposedKeySet or array of key sets expected. Invalid element found ${JSON.stringify(ks)}. Full argument given ${JSON.stringify(x)}`,
);
}
}
return composedKeySetFrom(newList);
}

return composedKeySetFrom(x.map((y) => parseKeySet(y)));
// not recognised: error
throw new InvalidKeySetError(`ComposedKeySet expected, given ${JSON.stringify(x)}`);
}

export function parseComposedKeyLabelSet<T extends string | number>(
x: ComposedKeyLabelSetSerialized<T> | ComposedKeyLabelSet<T>,
x: ComposedKeyLabelSetSerialized<T> | ComposedKeyLabelSet<T> | Array<KeyLabelSet<T>>,
): ComposedKeyLabelSet<T> {
if (isComposedKeyLabelSet(x)) return x;
if (isComposedKeySet(x)) {
if (isComposedKeyLabelSet(x)) {
return x as ComposedKeyLabelSet<T>;
}
throw new InvalidKeySetError(
`ComposedKeyLabelSet expected, a ComposedKeySet with no KeyLabels given ${JSON.stringify(x)}`,
);
}

if (!isComposedKeySetSerialized(x)) {
throw new InvalidKeySetError(`composedKeySetSerialized expected, given ${JSON.stringify(x)}`);
if (Array.isArray(x)) {
const newList: KeyLabelSet<T>[] = [];
for (const ks of x) {
if (isKeyLabelSet(ks)) {
newList.push(ks.clone());
} else if (isKeyLabelSetSerialized(ks)) {
newList.push(parseKeyLabelSet<T>(ks));
} else {
// ERROR: invalid element
throw new InvalidKeySetError(
`ComposedKeyLabelSet or array of key sets expected. Invalid element found ${JSON.stringify(ks)}. Full argument given ${JSON.stringify(x)}`,
);
}
}
return composedKeySetFrom(newList);
}

return composedKeySetFrom(x.map((y) => parseKeyLabelSet(y)));
// not recognised: error
throw new InvalidKeySetError(`ComposedKeyLabelSet expected, given ${JSON.stringify(x)}`);
}

export function parseKeySet<T extends Key>(x: KeySetAllSerialized<T> | KeySetAll<T>): KeySetAll<T>;
Expand Down

0 comments on commit 5b0791b

Please sign in to comment.