@@ -12,6 +12,9 @@ use syn::{
1212 PathArguments , Type , TypePath ,
1313} ;
1414
15+ type StructWithTraits = ( ItemStruct , bool , bool ) ;
16+ type EnumWithTraits = ( ItemEnum , bool , bool ) ;
17+
1518/// Generate a TypeScript file at `output_dst` from a directory of Rust source
1619/// files at `src_path`.
1720///
@@ -104,17 +107,17 @@ fn parse_rust_source_file(path: &str) -> io::Result<Vec<Item>> {
104107 Ok ( syntax_tree. items )
105108}
106109
107- fn get_items_implementing_encode ( items : Vec < Item > ) -> ( Vec < ItemStruct > , Vec < ItemEnum > ) {
110+ fn get_items_implementing_traits ( items : Vec < Item > ) -> ( Vec < StructWithTraits > , Vec < EnumWithTraits > ) {
108111 let mut structs = Vec :: new ( ) ;
109112 let mut enums = Vec :: new ( ) ;
110113
111- let has_encode = |attrs : & [ Attribute ] | -> bool {
114+ let has_trait = |attrs : & [ Attribute ] , trait_name : & str | -> bool {
112115 for attr in attrs {
113116 if attr. path ( ) . is_ident ( "derive" ) {
114117 match & attr. meta {
115118 Meta :: List ( list) => {
116119 for item in list. tokens . clone ( ) {
117- if item. to_string ( ) . contains ( "Encode" ) {
120+ if item. to_string ( ) . contains ( trait_name ) {
118121 return true ;
119122 }
120123 }
@@ -123,20 +126,23 @@ fn get_items_implementing_encode(items: Vec<Item>) -> (Vec<ItemStruct>, Vec<Item
123126 }
124127 }
125128 }
126-
127129 false
128130 } ;
129131
130132 for item in items {
131133 match item {
132134 Item :: Struct ( item_struct) => {
133- if has_encode ( & item_struct. attrs ) {
134- structs. push ( item_struct) ;
135+ let has_encode = has_trait ( & item_struct. attrs , "Encode" ) ;
136+ let has_decode = has_trait ( & item_struct. attrs , "Decode" ) ;
137+ if has_encode || has_decode {
138+ structs. push ( ( item_struct, has_encode, has_decode) ) ;
135139 }
136140 }
137141 Item :: Enum ( item_enum) => {
138- if has_encode ( & item_enum. attrs ) {
139- enums. push ( item_enum) ;
142+ let has_encode = has_trait ( & item_enum. attrs , "Encode" ) ;
143+ let has_decode = has_trait ( & item_enum. attrs , "Decode" ) ;
144+ if has_encode || has_decode {
145+ enums. push ( ( item_enum, has_encode, has_decode) ) ;
140146 }
141147 }
142148 _ => { }
@@ -161,9 +167,12 @@ fn generate_output_string_with_target(
161167
162168 for path in & input {
163169 let items = parse_rust_source_file ( path) ?;
164- let ( structs, enums) = get_items_implementing_encode ( items) ;
170+ let ( structs, enums) = get_items_implementing_traits ( items) ;
165171
166- for item in & structs {
172+ for ( item, has_encode, _) in & structs {
173+ if !has_encode {
174+ continue ;
175+ }
167176 let ( message_id, skip_attr) = get_message_attributes ( & item. attrs ) ;
168177 if should_skip_for_target ( & skip_attr, target) {
169178 continue ;
@@ -180,15 +189,15 @@ fn generate_output_string_with_target(
180189 // Filter structs and enums based on target
181190 let filtered_structs: Vec < _ > = structs
182191 . into_iter ( )
183- . filter ( |item| {
192+ . filter ( |( item, _ , _ ) | {
184193 let ( _, skip_attr) = get_message_attributes ( & item. attrs ) ;
185194 !should_skip_for_target ( & skip_attr, target)
186195 } )
187196 . collect ( ) ;
188197
189198 let filtered_enums: Vec < _ > = enums
190199 . into_iter ( )
191- . filter ( |item| {
200+ . filter ( |( item, _ , _ ) | {
192201 let skip_attr = get_enum_skip_attribute ( & item. attrs ) ;
193202 !should_skip_for_target ( & skip_attr, target)
194203 } )
@@ -198,12 +207,17 @@ fn generate_output_string_with_target(
198207 all_enums. extend ( filtered_enums) ;
199208 }
200209
201- for item in & all_enums {
210+ for ( item, _has_encode , has_decode ) in & all_enums {
202211 generate_typescript_enum_defs ( item. clone ( ) , output) ;
203- generate_typescript_enum_decoders ( item. clone ( ) , output) ;
212+ if * has_decode {
213+ generate_typescript_enum_decoders ( item. clone ( ) , output) ;
214+ }
204215 }
205216
206- for item in & all_enums {
217+ for ( item, has_encode, _) in & all_enums {
218+ if !has_encode {
219+ continue ;
220+ }
207221 let enum_name = item. ident . to_string ( ) ;
208222 if message_id_enum_names. contains ( & enum_name) {
209223 generate_typescript_message_id_encoder ( item. clone ( ) , output) ;
@@ -213,10 +227,14 @@ fn generate_output_string_with_target(
213227 }
214228 }
215229
216- for item in & all_structs {
230+ for ( item, has_encode , has_decode ) in & all_structs {
217231 generate_typescript_struct_defs ( item. clone ( ) , output) ;
218- generate_typescript_struct_decoders ( item. clone ( ) , output) ;
219- generate_typescript_struct_encoders ( item. clone ( ) , output, & message_id_enum_names) ;
232+ if * has_decode {
233+ generate_typescript_struct_decoders ( item. clone ( ) , output) ;
234+ }
235+ if * has_encode {
236+ generate_typescript_struct_encoders ( item. clone ( ) , output, & message_id_enum_names) ;
237+ }
220238 }
221239
222240 Ok ( ( ) )
@@ -802,10 +820,6 @@ export enum MessageId {
802820 Unknown = 255,
803821}
804822
805- export function decodeMessageId(bf: Bufferfish): MessageId {
806- return bf.readUint16() as MessageId
807- }
808-
809823export function encodeMessageId(bf: Bufferfish, value: MessageId): void {
810824 bf.writeUint16(value)
811825}
@@ -815,13 +829,6 @@ export interface JoinMessage {
815829 username: string
816830}
817831
818- export function decodeJoinMessage(bf: Bufferfish): JoinMessage {
819- return {
820- id: bf.readUint8() as number,
821- username: bf.readString() as string,
822- }
823- }
824-
825832export function encodeJoinMessage(bf: Bufferfish, value: JoinMessage): void {
826833 encodeMessageId(bf, MessageId.Join)
827834 bf.writeUint8(value.id)
@@ -834,13 +841,6 @@ export function encodeLeaveMessage(bf: Bufferfish): void {
834841
835842export type UnknownMessage = [number, number]
836843
837- export function decodeUnknownMessage(bf: Bufferfish): UnknownMessage {
838- return [
839- bf.readUint8() as number,
840- bf.readUint16() as number,
841- ]
842- }
843-
844844export function encodeUnknownMessage(bf: Bufferfish, value: UnknownMessage): void {
845845 encodeMessageId(bf, MessageId.Unknown)
846846 bf.writeUint8(value[0])
@@ -850,15 +850,18 @@ export function encodeUnknownMessage(bf: Bufferfish, value: UnknownMessage): voi
850850 let items = syn:: parse_file ( test_file)
851851 . unwrap_or_else ( |e| panic ! ( "Failed to parse: {e}" ) )
852852 . items ;
853- let ( structs, enums) = get_items_implementing_encode ( items) ;
853+ let ( structs, enums) = get_items_implementing_traits ( items) ;
854854
855855 let mut output = String :: new ( ) ;
856856 output. push_str ( "/* AUTOGENERATED BUFFERFISH FILE, DO NOT EDIT */\n " ) ;
857857 output. push_str ( "import { Bufferfish } from 'bufferfish'\n " ) ;
858858
859859 let mut message_id_enum_names = Vec :: new ( ) ;
860860
861- for item in & structs {
861+ for ( item, has_encode, _) in & structs {
862+ if !has_encode {
863+ continue ;
864+ }
862865 let ( message_id, _) = get_message_attributes ( & item. attrs ) ;
863866 if let Some ( message_id) = message_id
864867 && let Some ( enum_name) = extract_enum_name_from_message_id ( & message_id)
@@ -868,13 +871,18 @@ export function encodeUnknownMessage(bf: Bufferfish, value: UnknownMessage): voi
868871 }
869872 }
870873
871- for item in & enums {
874+ for ( item, _has_encode , has_decode ) in & enums {
872875 generate_typescript_enum_defs ( item. clone ( ) , & mut output) ;
873- generate_typescript_enum_decoders ( item. clone ( ) , & mut output) ;
876+ if * has_decode {
877+ generate_typescript_enum_decoders ( item. clone ( ) , & mut output) ;
878+ }
874879 }
875880
876881 let mut generated_encoders = std:: collections:: HashSet :: new ( ) ;
877- for item in & enums {
882+ for ( item, has_encode, _) in & enums {
883+ if !has_encode {
884+ continue ;
885+ }
878886 let enum_name = item. ident . to_string ( ) ;
879887 if message_id_enum_names. contains ( & enum_name) {
880888 generate_typescript_message_id_encoder ( item. clone ( ) , & mut output) ;
@@ -884,10 +892,18 @@ export function encodeUnknownMessage(bf: Bufferfish, value: UnknownMessage): voi
884892 }
885893 }
886894
887- for item in & structs {
895+ for ( item, has_encode , has_decode ) in & structs {
888896 generate_typescript_struct_defs ( item. clone ( ) , & mut output) ;
889- generate_typescript_struct_decoders ( item. clone ( ) , & mut output) ;
890- generate_typescript_struct_encoders ( item. clone ( ) , & mut output, & message_id_enum_names) ;
897+ if * has_decode {
898+ generate_typescript_struct_decoders ( item. clone ( ) , & mut output) ;
899+ }
900+ if * has_encode {
901+ generate_typescript_struct_encoders (
902+ item. clone ( ) ,
903+ & mut output,
904+ & message_id_enum_names,
905+ ) ;
906+ }
891907 }
892908
893909 if output. trim ( ) != expected_output. trim ( ) {
@@ -922,11 +938,11 @@ pub struct BothMessage {
922938 let items = syn:: parse_file ( test_file)
923939 . unwrap_or_else ( |e| panic ! ( "Failed to parse: {e}" ) )
924940 . items ;
925- let ( structs, _) = get_items_implementing_encode ( items) ;
941+ let ( structs, _) = get_items_implementing_traits ( items) ;
926942
927943 let client_structs: Vec < _ > = structs
928944 . iter ( )
929- . filter ( |item| {
945+ . filter ( |( item, _ , _ ) | {
930946 let ( _, skip_attr) = get_message_attributes ( & item. attrs ) ;
931947 !should_skip_for_target ( & skip_attr, Some ( "client" ) )
932948 } )
@@ -936,7 +952,7 @@ pub struct BothMessage {
936952
937953 let server_structs: Vec < _ > = structs
938954 . iter ( )
939- . filter ( |item| {
955+ . filter ( |( item, _ , _ ) | {
940956 let ( _, skip_attr) = get_message_attributes ( & item. attrs ) ;
941957 !should_skip_for_target ( & skip_attr, Some ( "server" ) )
942958 } )
0 commit comments