From b1524d774fe6623a3eec45ac0da007ad7bbb5601 Mon Sep 17 00:00:00 2001 From: Pontus Persson Date: Tue, 11 Mar 2025 09:46:01 +0100 Subject: [PATCH] Add set codec --- src/__tests__/codecs.test.ts | 16 ++++++++++++++++ src/codecs.ts | 15 +++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/__tests__/codecs.test.ts b/src/__tests__/codecs.test.ts index 42be920..a82effc 100644 --- a/src/__tests__/codecs.test.ts +++ b/src/__tests__/codecs.test.ts @@ -43,6 +43,22 @@ describe('Codecs', () => { }); }); + describe('set codec', () => { + it('encodes', () => { + expect(codecs.set(['a', 'b']).encode('a')).toStrictEqual('a'); + expect(codecs.set(['a', 'b']).encode(undefined)).toStrictEqual(''); + }); + + it('decodes', () => { + expect(codecs.set(['a', 'b']).decode('a')).toStrictEqual('a'); + expect(codecs.set(['a', 'b']).decode('b')).toStrictEqual('b'); + expect(codecs.set(['a', 'b']).decode('')).toStrictEqual(undefined); + expect(codecs.set(['a', 'b']).decode('no match')).toStrictEqual( + undefined, + ); + }); + }); + describe('oneOf codec', () => { it('throws if two options has the same string representation', () => { expect(() => { diff --git a/src/codecs.ts b/src/codecs.ts index b389fd2..5d35a6f 100644 --- a/src/codecs.ts +++ b/src/codecs.ts @@ -34,3 +34,18 @@ export const oneOf = string }>( }, ); }; + +export const set = (valid: readonly T[]) => { + const VALID = new Set(valid); + + return createCodec( + (source) => source ?? '', + (source: string) => { + if (VALID.has(source as T)) { + return source as T; + } + + return undefined; + }, + ); +};