@@ -166,6 +166,13 @@ export function generateRust (schema) {
166166 // Build serde attributes
167167 const serdeAttrs = [ ]
168168
169+ // Check for @rustserde annotations
170+ for ( const annotation of annotations ) {
171+ if ( 'rustserde' in annotation ) {
172+ serdeAttrs . push ( annotation . rustserde )
173+ }
174+ }
175+
169176 // Determine the serialization name
170177 let serializationName = fieldName
171178 if ( hasExplicitRename && explicitRenameValue ) {
@@ -189,15 +196,21 @@ export function generateRust (schema) {
189196 if ( isMapRepr ) {
190197 serdeAttrs . push ( 'skip_serializing_if = "Option::is_none"' )
191198 } else if ( isTupleRepr ) {
192- serdeAttrs . push ( 'default' )
199+ // Only add 'default' if it's not already present
200+ if ( ! serdeAttrs . includes ( 'default' ) ) {
201+ serdeAttrs . push ( 'default' )
202+ }
193203 }
194204 } else if ( fieldDefn . optional ) {
195205 // Just optional: Option<T>
196206 fieldType = `Option<${ fieldType } >`
197207 if ( isMapRepr ) {
198208 serdeAttrs . push ( 'skip_serializing_if = "Option::is_none"' )
199209 } else if ( isTupleRepr ) {
200- serdeAttrs . push ( 'default' )
210+ // Only add 'default' if it's not already present
211+ if ( ! serdeAttrs . includes ( 'default' ) ) {
212+ serdeAttrs . push ( 'default' )
213+ }
201214 }
202215 } else if ( fieldDefn . nullable ) {
203216 // Just nullable: Option<T> but always serialize
@@ -359,12 +372,25 @@ export function generateRust (schema) {
359372 }
360373 } else if ( 'copy' in typeDefn ) {
361374 const { fromType } = typeDefn . copy
375+
376+ // Check for type-level annotations only when copying from primitive types
377+ /** @type { { [k in string]: string }[] } */
378+ let annotations = [ ]
379+ if ( [ 'Bool' , 'Int' , 'Float' , 'String' , 'Bytes' , 'Link' ] . includes ( fromType ) ) {
380+ // @ts -ignore - annotations exist in the parsed data even if not in type definition
381+ if ( typeof typeDefn . copy . annotations === 'object' && typeof typeDefn . copy . annotations . type === 'object' ) {
382+ // @ts -ignore
383+ // For copy types, only use @unsigned annotation, ignore @rusttype
384+ annotations = typeDefn . copy . annotations . type . filter ( a => ! ( 'rusttype' in a ) )
385+ }
386+ }
387+
362388 // Resolve fromType - it could be a primitive or custom type
363389 let resolvedType = fromType
364390
365391 // Check if it's a primitive IPLD type
366392 if ( [ 'Bool' , 'Int' , 'Float' , 'String' , 'Bytes' , 'Link' ] . includes ( fromType ) ) {
367- resolvedType = getRustType ( [ ] , fromType )
393+ resolvedType = getRustType ( annotations , fromType )
368394 resolvedType = fixRustType ( imports , resolvedType , false )
369395 }
370396
0 commit comments