11import { CODAMA_ERROR__RENDERERS__UNSUPPORTED_NODE , CodamaError } from '@codama/errors' ;
22import {
3+ AccountNode ,
34 arrayTypeNode ,
45 CountNode ,
6+ DefinedTypeNode ,
57 definedTypeNode ,
68 fixedCountNode ,
9+ InstructionNode ,
710 isNode ,
811 NumberTypeNode ,
912 numberTypeNode ,
@@ -18,7 +21,13 @@ import {
1821import { extendVisitor , mergeVisitor , pipe , visit } from '@codama/visitors-core' ;
1922
2023import { ImportMap } from './ImportMap' ;
21- import { GetImportFromFunction , GetTraitsFromNodeFunction , rustDocblock } from './utils' ;
24+ import {
25+ GetImportFromFunction ,
26+ getSerdeFieldAttribute ,
27+ GetTraitsFromNodeFunction ,
28+ rustDocblock ,
29+ TraitOptions ,
30+ } from './utils' ;
2231
2332export type TypeManifest = {
2433 imports : ImportMap ;
@@ -31,12 +40,14 @@ export function getTypeManifestVisitor(options: {
3140 getTraitsFromNode : GetTraitsFromNodeFunction ;
3241 nestedStruct ?: boolean ;
3342 parentName ?: string | null ;
43+ traitOptions ?: TraitOptions ;
3444} ) {
35- const { getImportFrom, getTraitsFromNode } = options ;
45+ const { getImportFrom, getTraitsFromNode, traitOptions } = options ;
3646 let parentName : string | null = options . parentName ?? null ;
3747 let nestedStruct : boolean = options . nestedStruct ?? false ;
3848 let inlineStruct : boolean = false ;
3949 let parentSize : NumberTypeNode | number | null = null ;
50+ let parentNode : AccountNode | DefinedTypeNode | InstructionNode | null = null ;
4051
4152 return pipe (
4253 mergeVisitor (
@@ -51,10 +62,12 @@ export function getTypeManifestVisitor(options: {
5162 extendVisitor ( v , {
5263 visitAccount ( account , { self } ) {
5364 parentName = pascalCase ( account . name ) ;
65+ parentNode = account ;
5466 const manifest = visit ( account . data , self ) ;
5567 const traits = getTraitsFromNode ( account ) ;
5668 manifest . imports . mergeWith ( traits . imports ) ;
5769 parentName = null ;
70+ parentNode = null ;
5871 return {
5972 ...manifest ,
6073 type : traits . render + manifest . type ,
@@ -140,10 +153,12 @@ export function getTypeManifestVisitor(options: {
140153
141154 visitDefinedType ( definedType , { self } ) {
142155 parentName = pascalCase ( definedType . name ) ;
156+ parentNode = definedType ;
143157 const manifest = visit ( definedType . type , self ) ;
144158 const traits = getTraitsFromNode ( definedType ) ;
145159 manifest . imports . mergeWith ( traits . imports ) ;
146160 parentName = null ;
161+ parentNode = null ;
147162
148163 const renderedType = isNode ( definedType . type , [ 'enumTypeNode' , 'structTypeNode' ] )
149164 ? manifest . type
@@ -204,12 +219,18 @@ export function getTypeManifestVisitor(options: {
204219 parentName = originalParentName ;
205220
206221 let derive = '' ;
207- if ( childManifest . type === '(Pubkey)' ) {
208- derive =
209- '#[cfg_attr(feature = "serde", serde(with = "serde_with::As::<serde_with::DisplayFromStr>"))]\n' ;
210- } else if ( childManifest . type === '(Vec<Pubkey>)' ) {
211- derive =
212- '#[cfg_attr(feature = "serde", serde(with = "serde_with::As::<Vec<serde_with::DisplayFromStr>>"))]\n' ;
222+ if ( parentNode && childManifest . type === '(Pubkey)' ) {
223+ derive = getSerdeFieldAttribute (
224+ 'serde_with::As::<serde_with::DisplayFromStr>' ,
225+ parentNode ,
226+ traitOptions ,
227+ ) ;
228+ } else if ( parentNode && childManifest . type === '(Vec<Pubkey>)' ) {
229+ derive = getSerdeFieldAttribute (
230+ 'serde_with::As::<Vec<serde_with::DisplayFromStr>>' ,
231+ parentNode ,
232+ traitOptions ,
233+ ) ;
213234 }
214235
215236 return {
@@ -385,25 +406,36 @@ export function getTypeManifestVisitor(options: {
385406 const resolvedNestedType = resolveNestedTypeNode ( structFieldType . type ) ;
386407
387408 let derive = '' ;
388- if ( fieldManifest . type === 'Pubkey' ) {
389- derive =
390- '#[cfg_attr(feature = "serde", serde(with = "serde_with::As::<serde_with::DisplayFromStr>"))]\n' ;
391- } else if ( fieldManifest . type === 'Vec<Pubkey>' ) {
392- derive =
393- '#[cfg_attr(feature = "serde", serde(with = "serde_with::As::<Vec<serde_with::DisplayFromStr>>"))]\n' ;
394- } else if (
395- isNode ( resolvedNestedType , 'arrayTypeNode' ) &&
396- isNode ( resolvedNestedType . count , 'fixedCountNode' ) &&
397- resolvedNestedType . count . value > 32
398- ) {
399- derive = '#[cfg_attr(feature = "serde", serde(with = "serde_big_array::BigArray"))]\n' ;
400- } else if (
401- isNode ( resolvedNestedType , [ 'bytesTypeNode' , 'stringTypeNode' ] ) &&
402- isNode ( structFieldType . type , 'fixedSizeTypeNode' ) &&
403- structFieldType . type . size > 32
404- ) {
405- derive =
406- '#[cfg_attr(feature = "serde", serde(with = "serde_with::As::<serde_with::Bytes>"))]\n' ;
409+ if ( parentNode ) {
410+ if ( fieldManifest . type === 'Pubkey' ) {
411+ derive = getSerdeFieldAttribute (
412+ 'serde_with::As::<serde_with::DisplayFromStr>' ,
413+ parentNode ,
414+ traitOptions ,
415+ ) ;
416+ } else if ( fieldManifest . type === 'Vec<Pubkey>' ) {
417+ derive = getSerdeFieldAttribute (
418+ 'serde_with::As::<Vec<serde_with::DisplayFromStr>>' ,
419+ parentNode ,
420+ traitOptions ,
421+ ) ;
422+ } else if (
423+ isNode ( resolvedNestedType , 'arrayTypeNode' ) &&
424+ isNode ( resolvedNestedType . count , 'fixedCountNode' ) &&
425+ resolvedNestedType . count . value > 32
426+ ) {
427+ derive = getSerdeFieldAttribute ( 'serde_big_array::BigArray' , parentNode , traitOptions ) ;
428+ } else if (
429+ isNode ( resolvedNestedType , [ 'bytesTypeNode' , 'stringTypeNode' ] ) &&
430+ isNode ( structFieldType . type , 'fixedSizeTypeNode' ) &&
431+ structFieldType . type . size > 32
432+ ) {
433+ derive = getSerdeFieldAttribute (
434+ 'serde_with::As::<serde_with::Bytes>' ,
435+ parentNode ,
436+ traitOptions ,
437+ ) ;
438+ }
407439 }
408440
409441 return {
0 commit comments