diff --git a/.changeset/lucky-numbers-glow.md b/.changeset/lucky-numbers-glow.md new file mode 100644 index 000000000..3be05928b --- /dev/null +++ b/.changeset/lucky-numbers-glow.md @@ -0,0 +1,5 @@ +--- +'@metaplex-foundation/kinobi': patch +--- + +Add support to prefix string type in Rust client diff --git a/src/renderers/rust/getTypeManifestVisitor.ts b/src/renderers/rust/getTypeManifestVisitor.ts index f516f1de5..f6ff7a980 100644 --- a/src/renderers/rust/getTypeManifestVisitor.ts +++ b/src/renderers/rust/getTypeManifestVisitor.ts @@ -400,14 +400,32 @@ export function getTypeManifestVisitor() { visitStringType(stringType) { if ( isNode(stringType.size, 'prefixedSizeNode') && - stringType.size.prefix.format === 'u32' && stringType.size.prefix.endian === 'le' ) { - return { - type: 'String', - imports: new RustImportMap(), - nestedStructs: [], - }; + switch (stringType.size.prefix.format) { + case 'u32': + return { + type: 'String', + imports: new RustImportMap(), + nestedStructs: [], + }; + case 'u8': + case 'u16': + case 'u64': { + const prefix = stringType.size.prefix.format.toUpperCase(); + return { + type: `${prefix}PrefixString`, + imports: new RustImportMap().add( + `kaigan::types::${prefix}PrefixString` + ), + nestedStructs: [], + }; + } + default: + throw new Error( + `'String size not supported: ${stringType.size.prefix.format}` + ); + } } if (isNode(stringType.size, 'fixedSizeNode')) { diff --git a/test/renderers/rust/definedTypesPage.test.ts b/test/renderers/rust/definedTypesPage.test.ts new file mode 100644 index 000000000..2416ffff6 --- /dev/null +++ b/test/renderers/rust/definedTypesPage.test.ts @@ -0,0 +1,43 @@ +import test from 'ava'; +import { + definedTypeNode, + numberTypeNode, + prefixedSizeNode, + programNode, + stringTypeNode, + structFieldTypeNode, + structTypeNode, + visit, +} from '../../../src'; +import { getRenderMapVisitor } from '../../../src/renderers/rust/getRenderMapVisitor'; +import { codeContains } from './_setup'; + +test('it renders a prefix string on a defined type', (t) => { + // Given the following program with 1 defined type using a prefixed size string. + const node = programNode({ + name: 'splToken', + publicKey: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', + definedTypes: [ + definedTypeNode({ + name: 'blob', + type: structTypeNode([ + structFieldTypeNode({ + name: 'contentType', + type: stringTypeNode({ + size: prefixedSizeNode(numberTypeNode('u8')), + }), + }), + ]), + }), + ], + }); + + // When we render it. + const renderMap = visit(node, getRenderMapVisitor()); + + // Then we expect the following use and identifier to be rendered. + codeContains(t, renderMap.get('types/blob.rs'), [ + `use kaigan::types::U8PrefixString;`, + `content_type: U8PrefixString,`, + ]); +});