From d28f4dc05c45f35a429fa818e060aed648778718 Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Wed, 15 Feb 2023 12:23:11 +0000 Subject: [PATCH] Add support for variable string serializers (#6) * Add support for variable string serializers * Create sixty-nails-reflect.md * Update sixty-nails-reflect.md --- .changeset/sixty-nails-reflect.md | 22 +++++++++++++++++++ packages/umi-core/src/SerializerInterface.ts | 17 +++++++++++++- .../umi-serializer-beet/src/BeetSerializer.ts | 12 ++++++++++ .../test/BeetSerializer.test.ts | 14 ++++++++++++ 4 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 .changeset/sixty-nails-reflect.md diff --git a/.changeset/sixty-nails-reflect.md b/.changeset/sixty-nails-reflect.md new file mode 100644 index 00000000..8f0e4f3e --- /dev/null +++ b/.changeset/sixty-nails-reflect.md @@ -0,0 +1,22 @@ +--- +'@metaplex-foundation/umi-core': patch +'@metaplex-foundation/umi-serializer-beet': patch +--- + +Add support for variable string serializers + +There are now three ways to serialize/deserialize a string: + +```ts +// With prefix. +umi.serializer.string().serialize('A'); +// -> 0x0100000041 + +// Fixed. +umi.serializer.fixedString(8).serialize('A'); +// -> 0x4100000000000000 + +// Variable. +umi.serializer.variableString().serialize('A'); +// -> 0x41 +``` diff --git a/packages/umi-core/src/SerializerInterface.ts b/packages/umi-core/src/SerializerInterface.ts index e284c42c..31bf5f80 100644 --- a/packages/umi-core/src/SerializerInterface.ts +++ b/packages/umi-core/src/SerializerInterface.ts @@ -202,7 +202,7 @@ export interface SerializerInterface { ) => Serializer; /** - * Creates serializer of fixed length strings. + * Creates a fixed-length serializer for strings. * * @param bytes - The fixed number of bytes to read. * @param content - The string serializer to use for the content. Defaults to `utf8`. @@ -214,6 +214,17 @@ export interface SerializerInterface { description?: string ) => Serializer; + /** + * Creates a variable-length serializer for strings. + * + * @param content - The string serializer to use for the content. Defaults to `utf8`. + * @param description - A custom description for the serializer. + */ + variableString: ( + content?: Serializer, + description?: string + ) => Serializer; + /** * Creates a boolean serializer. * @@ -337,6 +348,10 @@ export class NullSerializer implements SerializerInterface { throw this.error; } + variableString(): Serializer { + throw this.error; + } + bool(): Serializer { throw this.error; } diff --git a/packages/umi-serializer-beet/src/BeetSerializer.ts b/packages/umi-serializer-beet/src/BeetSerializer.ts index f837ef7f..420d1407 100644 --- a/packages/umi-serializer-beet/src/BeetSerializer.ts +++ b/packages/umi-serializer-beet/src/BeetSerializer.ts @@ -583,6 +583,18 @@ export class BeetSerializer implements SerializerInterface { ); } + variableString( + content?: Serializer, + description?: string + ): Serializer { + const contentSerializer = content ?? utf8; + return { + ...contentSerializer, + description: + description ?? `variableString(${contentSerializer.description})`, + }; + } + bool(size?: NumberSerializer, description?: string): Serializer { const serializer = size ?? u8(); if (serializer.fixedSize === null) { diff --git a/packages/umi-serializer-beet/test/BeetSerializer.test.ts b/packages/umi-serializer-beet/test/BeetSerializer.test.ts index 8121fd9b..e6996928 100644 --- a/packages/umi-serializer-beet/test/BeetSerializer.test.ts +++ b/packages/umi-serializer-beet/test/BeetSerializer.test.ts @@ -316,6 +316,20 @@ test('it can serialize fixed strings', (t) => { t.is(doffset(fixedString(5, base58), '7893000000'), 5); }); +test('it can serialize variable strings', (t) => { + const { variableString } = new BeetSerializer(); + t.is(variableString().description, 'variableString(utf8)'); + t.is(variableString(undefined, 'My string').description, 'My string'); + t.is(variableString().fixedSize, null); + t.is(variableString().maxSize, null); + + // It simply delegates to the content serializer. + t.is(s(variableString(), 'Hello World!'), '48656c6c6f20576f726c6421'); + t.is(d(variableString(), '48656c6c6f20576f726c6421'), 'Hello World!'); + t.is(doffset(variableString(), '48656c6c6f20576f726c6421'), 12); + t.is(sd(variableString(), 'Hello World!'), 'Hello World!'); +}); + test('it can serialize bytes', (t) => { const { bytes } = new BeetSerializer(); t.is(bytes.description, 'bytes');