@@ -80,6 +80,8 @@ fn generate_file_with_imports(
8080 proto_file . messages ,
8181 )
8282
83+ let service_stubs = generate_service_stubs ( proto_file . services )
84+
8385 // Combine all sections with proper spacing
8486 let sections =
8587 [
@@ -91,6 +93,7 @@ fn generate_file_with_imports(
9193 message_encoders ,
9294 message_decoders ,
9395 enum_helpers ,
96+ service_stubs ,
9497 ]
9598 |> list . filter ( fn ( section ) { ! string . is_empty ( section ) } )
9699
@@ -481,3 +484,136 @@ fn generate_any_definition() -> String {
481484 ]
482485 string . join ( lines , "\n " )
483486}
487+
488+ /// Generate service stub definitions for gRPC/HTTP services
489+ fn generate_service_stubs ( services : List ( parser . Service ) ) -> String {
490+ case services {
491+ [ ] -> ""
492+ _ -> {
493+ services
494+ |> list . map ( generate_single_service_stub )
495+ |> string . join ( "\n \n " )
496+ }
497+ }
498+ }
499+
500+ /// Generate stub for a single service
501+ fn generate_single_service_stub ( service : parser . Service ) -> String {
502+ let client_interface = generate_client_interface ( service )
503+ let server_interface = generate_server_interface ( service )
504+
505+ string . join (
506+ [
507+ "// Service: " <> service . name ,
508+ "" ,
509+ client_interface ,
510+ "" ,
511+ server_interface ,
512+ ] ,
513+ "\n " ,
514+ )
515+ }
516+
517+ /// Generate client interface for service
518+ fn generate_client_interface ( service : parser . Service ) -> String {
519+ let type_name = service . name <> "Client"
520+ let method_comments = generate_method_comments ( service . methods , "client" )
521+
522+ string . join (
523+ [
524+ "/// Client interface for " <> service . name <> " service" ,
525+ "/// This trait defines the client-side methods for calling the service" ,
526+ "pub type " <> type_name <> " {" ,
527+ " " <> type_name <> "(" ,
528+ " // TODO: Add client implementation fields (e.g., HTTP client, endpoint URL)" ,
529+ " endpoint: String," ,
530+ " )" ,
531+ "}" ,
532+ "" ,
533+ method_comments ,
534+ "// TODO: Implement actual client method calls" ,
535+ ] ,
536+ "\n " ,
537+ )
538+ }
539+
540+ /// Generate server interface for service
541+ fn generate_server_interface ( service : parser . Service ) -> String {
542+ let type_name = service . name <> "Server"
543+ let method_comments = generate_method_comments ( service . methods , "server" )
544+
545+ string . join (
546+ [
547+ "/// Server interface for " <> service . name <> " service" ,
548+ "/// Implement this trait to handle incoming service requests" ,
549+ "pub type " <> type_name <> " {" ,
550+ " " <> type_name <> "(" ,
551+ " // TODO: Add server implementation fields" ,
552+ " )" ,
553+ "}" ,
554+ "" ,
555+ method_comments ,
556+ "// TODO: Implement server method handlers and request routing" ,
557+ ] ,
558+ "\n " ,
559+ )
560+ }
561+
562+ /// Generate method signature comments
563+ fn generate_method_comments (
564+ methods : List ( parser . Method ) ,
565+ interface_type : String ,
566+ ) -> String {
567+ let comment_prefix = case interface_type {
568+ "client" -> "// Method signatures for " <> interface_type <> ":"
569+ "server" -> "// Method signatures for " <> interface_type <> ":"
570+ _ -> "// Method signatures:"
571+ }
572+
573+ let method_lines =
574+ list . map ( methods , fn ( method ) {
575+ let streaming_info =
576+ get_streaming_comment (
577+ method . client_streaming ,
578+ method . server_streaming ,
579+ interface_type ,
580+ )
581+ " // "
582+ <> method . name
583+ <> "("
584+ <> method . input_type
585+ <> ") -> "
586+ <> method . output_type
587+ <> " "
588+ <> streaming_info
589+ } )
590+
591+ string . join ( [ comment_prefix , .. method_lines ] , "\n " )
592+ }
593+
594+ /// Get streaming type comment for method
595+ fn get_streaming_comment (
596+ client_streaming : Bool ,
597+ server_streaming : Bool ,
598+ interface_type : String ,
599+ ) -> String {
600+ let base_type = case interface_type {
601+ "server" ->
602+ "// "
603+ <> case client_streaming , server_streaming {
604+ False , False -> "Unary handler"
605+ False , True -> "Server streaming handler"
606+ True , False -> "Client streaming handler"
607+ True , True -> "Bidirectional streaming handler"
608+ }
609+ _ ->
610+ "// "
611+ <> case client_streaming , server_streaming {
612+ False , False -> "Unary call"
613+ False , True -> "Server streaming"
614+ True , False -> "Client streaming"
615+ True , True -> "Bidirectional streaming"
616+ }
617+ }
618+ base_type
619+ }
0 commit comments