1+ use std:: env;
12use std:: path:: Path ;
23use std:: { collections:: HashMap , io:: BufRead , path:: PathBuf } ;
34
45use heck:: { ToPascalCase , ToSnakeCase } ;
56use proc_macro2:: TokenStream ;
6- use protobuf:: reflect:: MessageDescriptor ;
7- use protobuf_codegen:: { Customize , CustomizeCallback } ;
87use quote:: format_ident;
98use quote:: quote;
109use quote:: ToTokens ;
1110use regex:: Regex ;
1211use syn:: Ident ;
1312
13+ #[ derive( Debug ) ]
1414struct Rpc {
1515 pub name : String ,
1616 pub input : String ,
1717 pub output : String ,
1818}
1919
20+ #[ derive( Debug ) ]
2021struct Plugin {
2122 pub plugin_name : String ,
2223
@@ -45,98 +46,67 @@ impl Plugin {
4546 }
4647}
4748
48- struct AddHash ;
49-
50- impl CustomizeCallback for AddHash {
51- fn message ( & self , message : & MessageDescriptor ) -> Customize {
52- let mut customize = Customize :: default ( ) ;
53- if message. name ( ) == "MatPair" || message. name ( ) == "Coord" {
54- customize = customize. before ( "#[derive(Hash, Eq)]" ) ;
55- }
56- customize
57- }
58- }
59-
6049fn main ( ) {
6150 println ! ( "cargo:rerun-if-changed=build.rs" ) ;
6251 println ! ( "cargo:rerun-if-env-changed=DFHACK_REGEN" ) ;
6352
64- let proto_include_dir = dfhack_proto_srcs :: include_dir ( ) ;
65- let protos = dfhack_proto_srcs :: protos ( ) ;
53+ if std :: env :: var ( "DFHACK_REGEN" ) . is_ok ( ) {
54+ let protoc = get_protoc ( ) ;
6655
67- assert ! ( !protos. is_empty( ) , "No protobuf file for code generation." ) ;
56+ let proto_include_dir = dfhack_proto_srcs:: include_dir ( ) ;
57+ let protos = dfhack_proto_srcs:: protos ( ) ;
6858
69- // Generate in the sources if DFHACK_REGEN is set
70- // in OUT_DIR otherwise.
71- // TODO It should always be OUT_DIR, then expose macros.
72- let out_path = match std:: env:: var ( "DFHACK_REGEN" ) {
73- Ok ( _) => {
74- let dst = PathBuf :: from ( "src/generated" ) ;
75- if dst. exists ( ) {
76- std:: fs:: remove_dir_all ( & dst) . unwrap ( ) ;
77- }
78- std:: fs:: create_dir_all ( & dst) . unwrap ( ) ;
79- dst
59+ assert ! ( !protos. is_empty( ) , "No protobuf file for code generation." ) ;
60+
61+ // Generate in the sources if DFHACK_REGEN is set
62+ let out_path = PathBuf :: from ( format ! ( "{}/src/generated" , env!( "CARGO_MANIFEST_DIR" ) ) ) ;
63+ if out_path. exists ( ) {
64+ std:: fs:: remove_dir_all ( & out_path) . unwrap ( ) ;
8065 }
81- Err ( _) => PathBuf :: from ( std:: env:: var ( "OUT_DIR" ) . unwrap ( ) ) ,
82- } ;
66+ std:: fs:: create_dir_all ( & out_path) . unwrap ( ) ;
67+ // Generate the protobuf message files
68+ generate_messages_rs ( & protoc, & protos, proto_include_dir, & out_path) ;
8369
84- // Generate the protobuf message files
85- generate_messages_rs ( & protos, proto_include_dir, & out_path) ;
70+ // Generate the plugin stubs
71+ generate_stubs_rs ( & protos, & out_path)
72+ }
73+ }
8674
87- // Generate the plugin stubs
88- generate_stubs_rs ( & protos, & out_path)
75+ fn get_protoc ( ) -> PathBuf {
76+ let protoc_version = "33.5" ;
77+ let out_dir = env:: var ( "OUT_DIR" ) . unwrap ( ) ;
78+ protoc_fetcher:: protoc ( protoc_version, Path :: new ( & out_dir) ) . unwrap ( )
8979}
9080
91- fn generate_messages_rs ( protos : & Vec < PathBuf > , include_dir : & str , out_path : & Path ) {
81+ fn generate_messages_rs ( protoc : & PathBuf , protos : & [ PathBuf ] , include_dir : & str , out_path : & Path ) {
9282 let mut out_path = out_path. to_path_buf ( ) ;
9383 out_path. push ( "messages" ) ;
9484 std:: fs:: create_dir_all ( & out_path) . unwrap ( ) ;
95- messages_protoc_codegen ( protos, include_dir, & out_path) ;
96- messages_generate_mod_rs ( protos, & out_path) ;
85+ messages_protoc_codegen ( protoc, protos, include_dir, & out_path) ;
9786}
9887
9988// Call the protoc code generation
100- fn messages_protoc_codegen ( protos : & Vec < PathBuf > , include_dir : & str , out_path : & Path ) {
101- protobuf_codegen:: Codegen :: new ( )
102- . customize ( Customize :: default ( ) . lite_runtime ( false ) )
103- . customize_callback ( AddHash )
104- . pure ( )
105- . include ( include_dir)
106- . inputs ( protos)
89+ fn messages_protoc_codegen (
90+ protoc : & PathBuf ,
91+ protos : & [ PathBuf ] ,
92+ include_dir : & str ,
93+ out_path : & Path ,
94+ ) {
95+ let mut mod_path = out_path. to_path_buf ( ) ;
96+ mod_path. push ( "includes.rs" ) ;
97+ println ! ( "{}" , mod_path. display( ) ) ;
98+ prost_build:: Config :: new ( )
99+ . enable_type_names ( )
100+ . type_attribute ( "." , "#[derive(serde::Serialize)]" )
101+ . protoc_executable ( protoc)
107102 . out_dir ( out_path)
108- . run_from_script ( ) ;
109- }
110-
111- fn messages_generate_mod_rs ( protos : & Vec < PathBuf > , out_path : & Path ) {
112- let mut file = quote ! ( ) ;
113-
114- for proto in protos {
115- let mod_name = proto
116- . with_extension ( "" )
117- . file_name ( )
118- . unwrap ( )
119- . to_str ( )
120- . unwrap ( )
121- . to_string ( ) ;
122-
123- let mod_name: Ident = format_ident ! ( "{}" , mod_name) ;
124-
125- file. extend ( quote ! {
126- mod #mod_name;
127- pub use self :: #mod_name:: * ;
128- } ) ;
129- }
130- // Write mod.rs
131- let mut mod_rs_path = out_path. to_path_buf ( ) ;
132- mod_rs_path. push ( "mod.rs" ) ;
133- let tree = syn:: parse2 ( file) . unwrap ( ) ;
134- let formatted = prettyplease:: unparse ( & tree) ;
135-
136- std:: fs:: write ( mod_rs_path, formatted) . unwrap ( ) ;
103+ . include_file ( & mod_path)
104+ . compile_protos ( protos, & [ include_dir] )
105+ . unwrap ( ) ;
106+ //panic!("{}", mod_path.display());
137107}
138108
139- fn generate_stubs_rs ( protos : & Vec < PathBuf > , out_path : & Path ) {
109+ fn generate_stubs_rs ( protos : & [ PathBuf ] , out_path : & Path ) {
140110 let plugins = read_protos_rpcs ( protos) ;
141111 let mut out_path = out_path. to_path_buf ( ) ;
142112 out_path. push ( "stubs" ) ;
@@ -162,8 +132,7 @@ fn generate_stubs_mod_rs(plugins: &Vec<Plugin>, file: &mut TokenStream) {
162132
163133 file. extend ( quote ! {
164134 use crate :: messages:: * ;
165- #[ cfg( feature = "reflection" ) ]
166- use protobuf:: MessageFull ;
135+ use prost:: Name ;
167136 } ) ;
168137
169138 let mut reflection_vec_building = quote ! ( ) ;
@@ -181,7 +150,7 @@ fn generate_stubs_mod_rs(plugins: &Vec<Plugin>, file: &mut TokenStream) {
181150 let member_ident = plugin. member_ident . clone ( ) ;
182151 plugins_impl. extend ( quote ! {
183152 #[ doc = #doc]
184- pub fn #member_ident( & mut self ) -> crate :: stubs:: #struct_ident<TChannel > {
153+ pub fn #member_ident( & ' a mut self ) -> crate :: stubs:: #struct_ident<' a , TChannel > {
185154 crate :: stubs:: #struct_ident:: new( & mut self . channel)
186155 }
187156 } ) ;
@@ -199,11 +168,10 @@ fn generate_stubs_mod_rs(plugins: &Vec<Plugin>, file: &mut TokenStream) {
199168 }
200169 }
201170
202- impl <TChannel : crate :: Channel > Stubs <TChannel > {
171+ impl <' a , TChannel : crate :: Channel > Stubs <TChannel > {
203172 #plugins_impl
204173 }
205174
206- #[ cfg( feature = "reflection" ) ]
207175 impl <TChannel : crate :: Channel > crate :: reflection:: StubReflection for Stubs <TChannel > {
208176 fn list_methods( ) -> Vec <crate :: reflection:: RemoteProcedureDescriptor > {
209177 let mut methods = Vec :: new( ) ;
@@ -262,7 +230,7 @@ fn generate_stub_rs(plugin: &Plugin, file: &mut TokenStream) {
262230 & mut self ,
263231 } ;
264232 prep = quote ! {
265- let request = EmptyMessage :: new ( ) ;
233+ let request = EmptyMessage :: default ( ) ;
266234 }
267235 }
268236
@@ -281,8 +249,7 @@ fn generate_stub_rs(plugin: &Plugin, file: &mut TokenStream) {
281249 value: i32 ,
282250 } ;
283251 prep = quote ! {
284- let mut request = IntMessage :: new( ) ;
285- request. set_value( value) ;
252+ let request = IntMessage { value } ;
286253 }
287254 }
288255
@@ -291,7 +258,7 @@ fn generate_stub_rs(plugin: &Plugin, file: &mut TokenStream) {
291258 i32
292259 } ;
293260 post = quote ! {
294- let _response = crate :: Reply { reply: _response. value( ) , fragments: _response. fragments } ;
261+ let _response = crate :: Reply { reply: _response. value, fragments: _response. fragments } ;
295262 }
296263 }
297264
@@ -301,8 +268,7 @@ fn generate_stub_rs(plugin: &Plugin, file: &mut TokenStream) {
301268 value: bool ,
302269 } ;
303270 prep = quote ! {
304- let mut request = SingleBool :: new( ) ;
305- request. set_Value( value) ;
271+ let request = SingleBool { value: Some ( value) } ;
306272 }
307273 }
308274
@@ -311,7 +277,7 @@ fn generate_stub_rs(plugin: &Plugin, file: &mut TokenStream) {
311277 bool
312278 } ;
313279 post = quote ! {
314- let _response = crate :: Reply { reply: _response. Value ( ) , fragments: _response. fragments } ;
280+ let _response = crate :: Reply { reply: _response. value ( ) , fragments: _response. fragments } ;
315281 }
316282 }
317283
@@ -320,7 +286,7 @@ fn generate_stub_rs(plugin: &Plugin, file: &mut TokenStream) {
320286 String
321287 } ;
322288 post = quote ! {
323- let _response = crate :: Reply { reply: _response. value( ) . to_string ( ) , fragments: _response. fragments } ;
289+ let _response = crate :: Reply { reply: _response. value. clone ( ) , fragments: _response. fragments } ;
324290 }
325291 }
326292
@@ -331,8 +297,8 @@ fn generate_stub_rs(plugin: &Plugin, file: &mut TokenStream) {
331297 ) -> Result <crate :: Reply <#return_token>, TChannel :: TError > {
332298 #prep
333299 let _response: crate :: Reply <#output_ident> = self . channel. request(
334- #plugin_name. to_string ( ) ,
335- #function_name. to_string ( ) ,
300+ #plugin_name,
301+ #function_name,
336302 request,
337303 ) ?;
338304 #post
@@ -342,14 +308,10 @@ fn generate_stub_rs(plugin: &Plugin, file: &mut TokenStream) {
342308
343309 reflection_vec. extend ( quote ! {
344310 crate :: reflection:: RemoteProcedureDescriptor {
345- name: #function_name. to_string( ) ,
346- plugin_name: #plugin_name. to_string( ) ,
347- input_type: #input_ident:: descriptor( )
348- . full_name( )
349- . to_string( ) ,
350- output_type: #output_ident:: descriptor( )
351- . full_name( )
352- . to_string( ) ,
311+ name: #function_name,
312+ plugin_name: #plugin_name,
313+ input_type: #input_ident:: full_name( ) ,
314+ output_type: #output_ident:: full_name( ) ,
353315 } ,
354316 } ) ;
355317 }
@@ -359,7 +321,6 @@ fn generate_stub_rs(plugin: &Plugin, file: &mut TokenStream) {
359321 #plugin_impl
360322 }
361323
362- #[ cfg( feature = "reflection" ) ]
363324 impl <TChannel : crate :: Channel > crate :: reflection:: StubReflection for #struct_ident<' _, TChannel > {
364325 fn list_methods( ) -> Vec <crate :: reflection:: RemoteProcedureDescriptor > {
365326 vec![
@@ -370,7 +331,7 @@ fn generate_stub_rs(plugin: &Plugin, file: &mut TokenStream) {
370331 } ) ;
371332}
372333
373- fn read_protos_rpcs ( protos : & Vec < PathBuf > ) -> Vec < Plugin > {
334+ fn read_protos_rpcs ( protos : & [ PathBuf ] ) -> Vec < Plugin > {
374335 let mut plugins = HashMap :: < String , Plugin > :: new ( ) ;
375336
376337 for proto in protos {
0 commit comments