瀏覽代碼

Support type aliases from DefinedTypeNodes in Rust renderer (#152)

Loris Leiva 1 年之前
父節點
當前提交
33cc3b7d29

+ 5 - 0
.changeset/brave-pens-float.md

@@ -0,0 +1,5 @@
+---
+"@kinobi-so/renderers-rust": patch
+---
+
+Support type aliases from `DefinedTypeNodes`

+ 22 - 7
packages/renderers-rust/src/getTypeManifestVisitor.ts

@@ -137,20 +137,35 @@ export function getTypeManifestVisitor(options: { nestedStruct?: boolean; parent
                     parentName = pascalCase(definedType.name);
                     const manifest = visit(definedType.type, self);
                     parentName = null;
-                    manifest.imports.add(['borsh::BorshSerialize', 'borsh::BorshDeserialize']);
                     const traits = ['BorshSerialize', 'BorshDeserialize', 'Clone', 'Debug', 'Eq', 'PartialEq'];
+
                     if (isNode(definedType.type, 'enumTypeNode') && isScalarEnum(definedType.type)) {
                         traits.push('Copy', 'PartialOrd', 'Hash', 'FromPrimitive');
                         manifest.imports.add(['num_derive::FromPrimitive']);
                     }
+
+                    const nestedStructs = manifest.nestedStructs.map(
+                        struct =>
+                            `#[derive(${traits.join(', ')})]\n` +
+                            '#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]\n' +
+                            `${struct}`,
+                    );
+
+                    if (!isNode(definedType.type, ['enumTypeNode', 'structTypeNode'])) {
+                        if (nestedStructs.length > 0) {
+                            manifest.imports.add(['borsh::BorshSerialize', 'borsh::BorshDeserialize']);
+                        }
+                        return {
+                            ...manifest,
+                            nestedStructs,
+                            type: `pub type ${pascalCase(definedType.name)} = ${manifest.type}`,
+                        };
+                    }
+
+                    manifest.imports.add(['borsh::BorshSerialize', 'borsh::BorshDeserialize']);
                     return {
                         ...manifest,
-                        nestedStructs: manifest.nestedStructs.map(
-                            struct =>
-                                `#[derive(${traits.join(', ')})]\n` +
-                                '#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]\n' +
-                                `${struct}`,
-                        ),
+                        nestedStructs,
                         type:
                             `#[derive(${traits.join(', ')})]\n` +
                             '#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]\n' +

+ 24 - 2
packages/renderers-rust/test/types/array.test.ts

@@ -11,9 +11,31 @@ import { visit } from '@kinobi-so/visitors-core';
 import { test } from 'vitest';
 
 import { getRenderMapVisitor } from '../../src';
-import { codeContains } from '../_setup';
+import { codeContains, codeDoesNotContains } from '../_setup';
 
 test('it exports short vecs', () => {
+    // Given an array using a shortU16 prefix.
+    const node = definedTypeNode({
+        name: 'myShortVec',
+        type: arrayTypeNode(publicKeyTypeNode(), prefixedCountNode(numberTypeNode('shortU16'))),
+    });
+
+    // When we render the array.
+    const renderMap = visit(node, getRenderMapVisitor());
+
+    // Then we expect a short vec to be exported.
+    codeContains(renderMap.get('types/my_short_vec.rs'), [
+        /pub type MyShortVec = ShortVec<Pubkey>/,
+        /use solana_program::pubkey::Pubkey/,
+        /use solana_program::short_vec::ShortVec/,
+    ]);
+    codeDoesNotContains(renderMap.get('types/my_short_vec.rs'), [
+        /use borsh::BorshSerialize/,
+        /use borsh::BorshDeserialize/,
+    ]);
+});
+
+test('it exports short vecs as struct fields', () => {
     // Given an array using a shortU16 prefix.
     const node = definedTypeNode({
         name: 'myShortVec',
@@ -28,7 +50,7 @@ test('it exports short vecs', () => {
     // When we render the array.
     const renderMap = visit(node, getRenderMapVisitor());
 
-    // Then we expect a short vec to be exported.
+    // Then we expect a short vec to be exported as a struct field.
     codeContains(renderMap.get('types/my_short_vec.rs'), [
         /pub value: ShortVec<Pubkey>/,
         /use solana_program::pubkey::Pubkey/,

+ 23 - 2
packages/renderers-rust/test/types/number.test.ts

@@ -3,19 +3,40 @@ import { visit } from '@kinobi-so/visitors-core';
 import { test } from 'vitest';
 
 import { getRenderMapVisitor } from '../../src';
-import { codeContains } from '../_setup';
+import { codeContains, codeDoesNotContains } from '../_setup';
 
 test('it exports short u16 numbers', () => {
     // Given a shortU16 number.
     const node = definedTypeNode({
         name: 'myShortU16',
-        type: structTypeNode([structFieldTypeNode({ name: 'value', type: numberTypeNode('shortU16') })]),
+        type: numberTypeNode('shortU16'),
     });
 
     // When we render the number.
     const renderMap = visit(node, getRenderMapVisitor());
 
     // Then we expect a short u16 to be exported.
+    codeContains(renderMap.get('types/my_short_u16.rs'), [
+        /pub type MyShortU16 = ShortU16/,
+        /use solana_program::short_vec::ShortU16/,
+    ]);
+    codeDoesNotContains(renderMap.get('types/my_short_u16.rs'), [
+        /use borsh::BorshSerialize/,
+        /use borsh::BorshDeserialize/,
+    ]);
+});
+
+test('it exports short u16 numbers as struct fields', () => {
+    // Given a shortU16 number.
+    const node = definedTypeNode({
+        name: 'myShortU16',
+        type: structTypeNode([structFieldTypeNode({ name: 'value', type: numberTypeNode('shortU16') })]),
+    });
+
+    // When we render the number.
+    const renderMap = visit(node, getRenderMapVisitor());
+
+    // Then we expect a short u16 to be exported as a struct field.
     codeContains(renderMap.get('types/my_short_u16.rs'), [
         /pub value: ShortU16/,
         /use solana_program::short_vec::ShortU16/,