11//! Collector for routes and structs
22
3+ use std:: collections:: HashMap ;
34use std:: path:: Path ;
45
56use syn:: Item ;
@@ -11,10 +12,17 @@ use crate::{
1112 route:: { extract_doc_comment, extract_route_info} ,
1213} ;
1314
14- /// Collect routes and structs from a folder
15+ /// Collect routes and structs from a folder.
16+ ///
17+ /// Returns the metadata AND the parsed file ASTs, so downstream consumers
18+ /// (e.g., `openapi_generator`) can reuse them without re-reading files from disk.
1519#[ allow( clippy:: option_if_let_else) ]
16- pub fn collect_metadata ( folder_path : & Path , folder_name : & str ) -> MacroResult < CollectedMetadata > {
20+ pub fn collect_metadata (
21+ folder_path : & Path ,
22+ folder_name : & str ,
23+ ) -> MacroResult < ( CollectedMetadata , HashMap < String , syn:: File > ) > {
1724 let mut metadata = CollectedMetadata :: new ( ) ;
25+ let mut file_asts = HashMap :: new ( ) ;
1826
1927 let files = collect_files ( folder_path) . map_err ( |e| err_call_site ( format ! ( "vespera! macro: failed to scan route folder '{}': {}. Verify the folder exists and is readable." , folder_path. display( ) , e) ) ) ?;
2028
@@ -33,6 +41,10 @@ pub fn collect_metadata(folder_path: &Path, folder_name: &str) -> MacroResult<Co
3341
3442 let file_ast = syn:: parse_file ( & content) . map_err ( |e| err_call_site ( format ! ( "vespera! macro: syntax error in '{}': {}. Fix the Rust syntax errors in this file." , file. display( ) , e) ) ) ?;
3543
44+ // Store file AST for downstream reuse (keyed by display path to match RouteMetadata.file_path)
45+ let file_path_key = file. display ( ) . to_string ( ) ;
46+ file_asts. insert ( file_path_key, file_ast. clone ( ) ) ;
47+
3648 // Get module path
3749 let segments = file
3850 . strip_prefix ( folder_path)
@@ -91,7 +103,7 @@ pub fn collect_metadata(folder_path: &Path, folder_name: &str) -> MacroResult<Co
91103 }
92104 }
93105
94- Ok ( metadata)
106+ Ok ( ( metadata, file_asts ) )
95107}
96108
97109#[ cfg( test) ]
@@ -117,7 +129,7 @@ mod tests {
117129 let temp_dir = TempDir :: new ( ) . expect ( "Failed to create temp dir" ) ;
118130 let folder_name = "routes" ;
119131
120- let metadata = collect_metadata ( temp_dir. path ( ) , folder_name) . unwrap ( ) ;
132+ let ( metadata, _file_asts ) = collect_metadata ( temp_dir. path ( ) , folder_name) . unwrap ( ) ;
121133
122134 assert ! ( metadata. routes. is_empty( ) ) ;
123135 assert ! ( metadata. structs. is_empty( ) ) ;
@@ -236,7 +248,7 @@ pub fn get_users() -> String {
236248 create_temp_file ( & temp_dir, filename, content) ;
237249 }
238250
239- let metadata = collect_metadata ( temp_dir. path ( ) , folder_name) . unwrap ( ) ;
251+ let ( metadata, _file_asts ) = collect_metadata ( temp_dir. path ( ) , folder_name) . unwrap ( ) ;
240252
241253 let route = & metadata. routes [ 0 ] ;
242254 assert_eq ! ( route. method, expected_method) ;
@@ -259,7 +271,7 @@ pub fn get_users() -> String {
259271 let temp_dir = TempDir :: new ( ) . expect ( "Failed to create temp dir" ) ;
260272 let folder_name = "routes" ;
261273
262- let metadata = collect_metadata ( temp_dir. path ( ) , folder_name) . unwrap ( ) ;
274+ let ( metadata, _file_asts ) = collect_metadata ( temp_dir. path ( ) , folder_name) . unwrap ( ) ;
263275
264276 assert_eq ! ( metadata. routes. len( ) , 0 ) ;
265277
@@ -282,7 +294,7 @@ pub struct User {
282294" ,
283295 ) ;
284296
285- let metadata = collect_metadata ( temp_dir. path ( ) , folder_name) . unwrap ( ) ;
297+ let ( metadata, _file_asts ) = collect_metadata ( temp_dir. path ( ) , folder_name) . unwrap ( ) ;
286298
287299 assert_eq ! ( metadata. routes. len( ) , 0 ) ;
288300 assert_eq ! ( metadata. structs. len( ) , 0 ) ;
@@ -314,7 +326,7 @@ pub fn get_user() -> User {
314326"# ,
315327 ) ;
316328
317- let metadata = collect_metadata ( temp_dir. path ( ) , folder_name) . unwrap ( ) ;
329+ let ( metadata, _file_asts ) = collect_metadata ( temp_dir. path ( ) , folder_name) . unwrap ( ) ;
318330
319331 assert_eq ! ( metadata. routes. len( ) , 1 ) ;
320332
@@ -356,7 +368,7 @@ pub fn get_posts() -> String {
356368"# ,
357369 ) ;
358370
359- let metadata = collect_metadata ( temp_dir. path ( ) , folder_name) . unwrap ( ) ;
371+ let ( metadata, _file_asts ) = collect_metadata ( temp_dir. path ( ) , folder_name) . unwrap ( ) ;
360372
361373 assert_eq ! ( metadata. routes. len( ) , 3 ) ;
362374 assert_eq ! ( metadata. structs. len( ) , 0 ) ;
@@ -407,7 +419,7 @@ pub struct Post {
407419" ,
408420 ) ;
409421
410- let metadata = collect_metadata ( temp_dir. path ( ) , folder_name) . unwrap ( ) ;
422+ let ( metadata, _file_asts ) = collect_metadata ( temp_dir. path ( ) , folder_name) . unwrap ( ) ;
411423
412424 assert_eq ! ( metadata. routes. len( ) , 0 ) ;
413425
@@ -430,7 +442,7 @@ pub fn index() -> String {
430442"# ,
431443 ) ;
432444
433- let metadata = collect_metadata ( temp_dir. path ( ) , folder_name) . unwrap ( ) ;
445+ let ( metadata, _file_asts ) = collect_metadata ( temp_dir. path ( ) , folder_name) . unwrap ( ) ;
434446
435447 assert_eq ! ( metadata. routes. len( ) , 1 ) ;
436448 let route = & metadata. routes [ 0 ] ;
@@ -457,7 +469,7 @@ pub fn get_users() -> String {
457469"# ,
458470 ) ;
459471
460- let metadata = collect_metadata ( temp_dir. path ( ) , folder_name) . unwrap ( ) ;
472+ let ( metadata, _file_asts ) = collect_metadata ( temp_dir. path ( ) , folder_name) . unwrap ( ) ;
461473
462474 assert_eq ! ( metadata. routes. len( ) , 1 ) ;
463475 let route = & metadata. routes [ 0 ] ;
@@ -486,7 +498,7 @@ pub fn get_users() -> String {
486498
487499 create_temp_file ( & temp_dir, "readme.md" , "# Readme" ) ;
488500
489- let metadata = collect_metadata ( temp_dir. path ( ) , folder_name) . unwrap ( ) ;
501+ let ( metadata, _file_asts ) = collect_metadata ( temp_dir. path ( ) , folder_name) . unwrap ( ) ;
490502
491503 // Only .rs file should be processed
492504 assert_eq ! ( metadata. routes. len( ) , 1 ) ;
@@ -513,7 +525,7 @@ pub fn get_users() -> String {
513525
514526 create_temp_file ( & temp_dir, "invalid.rs" , "invalid rust syntax {" ) ;
515527
516- let metadata = collect_metadata ( temp_dir. path ( ) , folder_name) ;
528+ let metadata = collect_metadata ( temp_dir. path ( ) , folder_name) . map ( | ( m , _ ) | m ) ;
517529
518530 // Only valid file should be processed
519531 assert ! ( metadata. is_err( ) ) ;
@@ -537,7 +549,7 @@ pub fn get_users() -> String {
537549"# ,
538550 ) ;
539551
540- let metadata = collect_metadata ( temp_dir. path ( ) , folder_name) . unwrap ( ) ;
552+ let ( metadata, _file_asts ) = collect_metadata ( temp_dir. path ( ) , folder_name) . unwrap ( ) ;
541553
542554 assert_eq ! ( metadata. routes. len( ) , 1 ) ;
543555 let route = & metadata. routes [ 0 ] ;
@@ -584,7 +596,7 @@ pub fn options_handler() -> String { "options".to_string() }
584596"# ,
585597 ) ;
586598
587- let metadata = collect_metadata ( temp_dir. path ( ) , folder_name) . unwrap ( ) ;
599+ let ( metadata, _file_asts ) = collect_metadata ( temp_dir. path ( ) , folder_name) . unwrap ( ) ;
588600
589601 assert_eq ! ( metadata. routes. len( ) , 7 ) ;
590602
@@ -766,7 +778,7 @@ pub fn get_users() -> String {
766778 ) ;
767779
768780 // Collect metadata from the subdirectory
769- let metadata = collect_metadata ( & sub_dir, folder_name) . unwrap ( ) ;
781+ let ( metadata, _file_asts ) = collect_metadata ( & sub_dir, folder_name) . unwrap ( ) ;
770782
771783 // Should collect the route (strip_prefix succeeds in normal cases)
772784 assert_eq ! ( metadata. routes. len( ) , 1 ) ;
@@ -794,7 +806,7 @@ pub struct User {
794806" ,
795807 ) ;
796808
797- let metadata = collect_metadata ( temp_dir. path ( ) , folder_name) . unwrap ( ) ;
809+ let ( metadata, _file_asts ) = collect_metadata ( temp_dir. path ( ) , folder_name) . unwrap ( ) ;
798810
799811 // Struct without Schema derive should not be collected
800812 assert_eq ! ( metadata. structs. len( ) , 0 ) ;
@@ -820,7 +832,7 @@ pub struct User {
820832" ,
821833 ) ;
822834
823- let metadata = collect_metadata ( temp_dir. path ( ) , folder_name) . unwrap ( ) ;
835+ let ( metadata, _file_asts ) = collect_metadata ( temp_dir. path ( ) , folder_name) . unwrap ( ) ;
824836
825837 // Struct with only Debug/Clone derive (no Schema) should not be collected
826838 assert_eq ! ( metadata. structs. len( ) , 0 ) ;
0 commit comments