Skip to content

Commit 0c96251

Browse files
authored
Add anchorTraits option to Rust renderer (#250)
* Add anchorTraits option * Add test * Add changeset * Fix lint * Add option documentation
1 parent d98b51a commit 0c96251

File tree

5 files changed

+66
-25
lines changed

5 files changed

+66
-25
lines changed

.changeset/good-readers-flash.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@codama/renderers-rust': patch
3+
---
4+
5+
Add anchorTraits option to Rust renderer

packages/renderers-rust/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ The `renderVisitor` accepts the following options.
4747
| `dependencyMap` | `Record<string, string>` | `{}` | A mapping between import aliases and their actual crate name or path in Rust. |
4848
| `renderParentInstructions` | `boolean` | `false` | When using nested instructions, whether the parent instructions should also be rendered. When set to `false` (default), only the instruction leaves are being rendered. |
4949
| `traitOptions` | [`TraitOptions`](#trait-options) | `DEFAULT_TRAIT_OPTIONS` | A set of options that can be used to configure how traits are rendered for every Rust types. See [documentation below](#trait-options) for more information. |
50+
| `anchorTraits` | `boolean` | `true` | Whether to generate Anchor traits `impl` for account types. |
5051

5152
## Trait Options
5253

packages/renderers-rust/public/templates/accountsPage.njk

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -128,33 +128,35 @@ impl<'a> TryFrom<&solana_program::account_info::AccountInfo<'a>> for {{ account.
128128
}
129129
}
130130

131-
#[cfg(feature = "anchor")]
132-
impl anchor_lang::AccountDeserialize for {{ account.name | pascalCase }} {
133-
fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result<Self> {
134-
Ok(Self::deserialize(buf)?)
135-
}
136-
}
131+
{% if anchorTraits %}
132+
#[cfg(feature = "anchor")]
133+
impl anchor_lang::AccountDeserialize for {{ account.name | pascalCase }} {
134+
fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result<Self> {
135+
Ok(Self::deserialize(buf)?)
136+
}
137+
}
137138

138-
#[cfg(feature = "anchor")]
139-
impl anchor_lang::AccountSerialize for {{ account.name | pascalCase }} {}
139+
#[cfg(feature = "anchor")]
140+
impl anchor_lang::AccountSerialize for {{ account.name | pascalCase }} {}
140141

141-
#[cfg(feature = "anchor")]
142-
impl anchor_lang::Owner for {{ account.name | pascalCase }} {
143-
fn owner() -> Pubkey {
144-
crate::{{ program.name | snakeCase | upper }}_ID
145-
}
146-
}
142+
#[cfg(feature = "anchor")]
143+
impl anchor_lang::Owner for {{ account.name | pascalCase }} {
144+
fn owner() -> Pubkey {
145+
crate::{{ program.name | snakeCase | upper }}_ID
146+
}
147+
}
147148

148-
#[cfg(feature = "anchor-idl-build")]
149-
impl anchor_lang::IdlBuild for {{ account.name | pascalCase }} {}
149+
#[cfg(feature = "anchor-idl-build")]
150+
impl anchor_lang::IdlBuild for {{ account.name | pascalCase }} {}
150151

151-
{#
152-
This is not used for the IDL generation since default `IdlBuild` impl doesn't include
153-
the type in the IDL but it stil needs to be added in order to make compilation work.
154-
#}
155-
#[cfg(feature = "anchor-idl-build")]
156-
impl anchor_lang::Discriminator for {{ account.name | pascalCase }} {
157-
const DISCRIMINATOR: [u8; 8] = [0; 8];
158-
}
152+
{#
153+
This is not used for the IDL generation since default `IdlBuild` impl doesn't include
154+
the type in the IDL but it stil needs to be added in order to make compilation work.
155+
#}
156+
#[cfg(feature = "anchor-idl-build")]
157+
impl anchor_lang::Discriminator for {{ account.name | pascalCase }} {
158+
const DISCRIMINATOR: [u8; 8] = [0; 8];
159+
}
160+
{% endif %}
159161

160162
{% endblock %}

packages/renderers-rust/src/getRenderMapVisitor.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import { renderValueNode } from './renderValueNodeVisitor';
3030
import { getImportFromFactory, getTraitsFromNodeFactory, LinkOverrides, render, TraitOptions } from './utils';
3131

3232
export type GetRenderMapOptions = {
33+
anchorTraits?: boolean;
3334
defaultTraitOverrides?: string[];
3435
dependencyMap?: Record<string, string>;
3536
linkOverrides?: LinkOverrides;
@@ -46,6 +47,7 @@ export function getRenderMapVisitor(options: GetRenderMapOptions = {}) {
4647
const getImportFrom = getImportFromFactory(options.linkOverrides ?? {});
4748
const getTraitsFromNode = getTraitsFromNodeFactory(options.traitOptions);
4849
const typeManifestVisitor = getTypeManifestVisitor({ getImportFrom, getTraitsFromNode });
50+
const anchorTraits = options.anchorTraits ?? true;
4951

5052
return pipe(
5153
staticVisitor(
@@ -92,6 +94,7 @@ export function getRenderMapVisitor(options: GetRenderMapOptions = {}) {
9294
`accounts/${snakeCase(node.name)}.rs`,
9395
render('accountsPage.njk', {
9496
account: node,
97+
anchorTraits,
9598
constantSeeds,
9699
hasVariableSeeds,
97100
imports: imports

packages/renderers-rust/test/accountsPage.test.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { visit } from '@codama/visitors-core';
1717
import { test } from 'vitest';
1818

1919
import { getRenderMapVisitor } from '../src';
20-
import { codeContains } from './_setup';
20+
import { codeContains, codeDoesNotContains } from './_setup';
2121

2222
test('it renders a byte array seed used on an account', () => {
2323
// Given the following program with 1 account and 1 pda with a byte array as seeds.
@@ -134,3 +134,33 @@ test('it renders anchor traits impl', () => {
134134
'impl anchor_lang::Owner for TestAccount',
135135
]);
136136
});
137+
138+
test('it renders account without anchor traits', () => {
139+
// Given the following account.
140+
const node = programNode({
141+
accounts: [
142+
accountNode({
143+
discriminators: [
144+
{
145+
kind: 'fieldDiscriminatorNode',
146+
name: camelCase('discriminator'),
147+
offset: 0,
148+
},
149+
],
150+
name: 'testAccount',
151+
pda: pdaLinkNode('testPda'),
152+
}),
153+
],
154+
name: 'myProgram',
155+
publicKey: '1111',
156+
});
157+
158+
// When we render it with anchor traits disabled.
159+
const renderMap = visit(node, getRenderMapVisitor({ anchorTraits: false }));
160+
161+
// Then we do not expect Anchor traits.
162+
codeDoesNotContains(renderMap.get('accounts/test_account.rs'), [
163+
'#[cfg(feature = "anchor")]',
164+
'#[cfg(feature = "anchor-idl-build")]',
165+
]);
166+
});

0 commit comments

Comments
 (0)