fn ast_to_code(
    rust_file_writer: &mut BufWriter<File>,
    q_file_writer: &mut BufWriter<File>,
    ast: Node,
    package: &mut String,
) -> io::Result<()> {
    match ast {
        Node::Package(pkg) => {
            // Store package name
            *package = pkg;
            Ok(())
        }
        Node::Service {
            name,
            messages,
            rpcs,
        } => {
            if package.is_empty() {
                Err(Error::new(
                    ErrorKind::InvalidData,
                    "package name is not set",
                ))
            } else {
                let snake_case_service = camel_to_snake(name.as_str());
                // Write import lines.
                let import = format!(
                    import_template!(),
                    package = package.as_str(),
                    snake_case_service = snake_case_service.as_str(),
                    service = name.as_str(),
                    messages = messages.join(",")
                );
                rust_file_writer.write_all(import.as_bytes())?;

                // Write method code.
                for rpc in rpcs {
                    let method = match (rpc.request.as_str(), rpc.response.as_str()) {
                        ("google.protobuf.Empty", "google.protobuf.Empty") => {
                            format!(
                                empty_input_method_template!(),
                                method = rpc.method.to_lowercase(),
                                client_name = format!("{}Client", name),
                                response_handler = EMPTY_RESPONSE_HANDLER
                            )
                        }
                        ("google.protobuf.Empty", _) => {
                            let response_handler = format!(
                                non_empty_response_handler!(),
                                fq_response_type =
                                    [package.as_str(), rpc.response.as_str()].join("."),
                                response_type = rpc.response
                            );
                            format!(
                                empty_input_method_template!(),
                                method = rpc.method.to_lowercase(),
                                client_name = format!("{}Client", name),
                                response_handler = response_handler
                            )
                        }
                        (_, "google.protobuf.Empty") => {
                            format!(
                                method_template!(),
                                method = rpc.method.to_lowercase(),
                                client_name = format!("{}Client", name),
                                fq_request_type =
                                    [package.as_str(), rpc.request.as_str()].join("."),
                                request_type = rpc.request,
                                response_handler = EMPTY_RESPONSE_HANDLER
                            )
                        }
                        _ => {
                            let response_handler = format!(
                                non_empty_response_handler!(),
                                fq_response_type =
                                    [package.as_str(), rpc.response.as_str()].join("."),
                                response_type = rpc.response
                            );
                            format!(
                                method_template!(),
                                method = rpc.method.to_lowercase(),
                                client_name = format!("{}Client", name),
                                fq_request_type =
                                    [package.as_str(), rpc.request.as_str()].join("."),
                                request_type = rpc.request,
                                response_handler = response_handler
                            )
                        }
                    };
                    rust_file_writer.write_all(method.as_bytes())?;

                    // Write a line to load Rust function.
                    let method_load_line =
                        format!(method_load_template!(), method = rpc.method.to_lowercase());
                    q_file_writer.write_all(method_load_line.as_bytes())?;
                }
                Ok(())
            }
        }
        Node::Enum { name, elements } => {
            // Write enum definition
            let elements = elements.join("`");
            let enum_definition = format!(enum_template!(), source = name, elements = elements);
            q_file_writer.write_all(enum_definition.as_bytes())
        }
    }
}
/// Consume AST and convert it to code.
Consume AST and convert it to code.
Consume AST and convert it to code .
fn ast_to_code(
    rust_file_writer: &mut BufWriter<File>,
    q_file_writer: &mut BufWriter<File>,
    ast: Node,
    package: &mut String,
) -> io::Result<()> {
    match ast {
        Node::Package(pkg) => {
            // Store package name
            *package = pkg;
            Ok(())
        }
        Node::Service {
            name,
            messages,
            rpcs,
        } => {
            if package.is_empty() {
                Err(Error::new(
                    ErrorKind::InvalidData,
                    "package name is not set",
                ))
            } else {
                let snake_case_service = camel_to_snake(name.as_str());
                // Write import lines.
                let import = format!(
                    import_template!(),
                    package = package.as_str(),
                    snake_case_service = snake_case_service.as_str(),
                    service = name.as_str(),
                    messages = messages.join(",")
                );
                rust_file_writer.write_all(import.as_bytes())?;
                // Write method code.
                for rpc in rpcs {
                    let method = match (rpc.request.as_str(), rpc.response.as_str()) {
                        ("google.protobuf.Empty", "google.protobuf.Empty") => {
                            format!(
                                empty_input_method_template!(),
                                method = rpc.method.to_lowercase(),
                                client_name = format!("{}Client", name),
                                response_handler = EMPTY_RESPONSE_HANDLER
                            )
                        }
                        ("google.protobuf.Empty", _) => {
                            let response_handler = format!(
                                non_empty_response_handler!(),
                                fq_response_type =
                                    [package.as_str(), rpc.response.as_str()].join("."),
                                response_type = rpc.response
                            );
                            format!(
                                empty_input_method_template!(),
                                method = rpc.method.to_lowercase(),
                                client_name = format!("{}Client", name),
                                response_handler = response_handler
                            )
                        }
                        (_, "google.protobuf.Empty") => {
                            format!(
                                method_template!(),
                                method = rpc.method.to_lowercase(),
                                client_name = format!("{}Client", name),
                                fq_request_type =
                                    [package.as_str(), rpc.request.as_str()].join("."),
                                request_type = rpc.request,
                                response_handler = EMPTY_RESPONSE_HANDLER
                            )
                        }
                        _ => {
                            let response_handler = format!(
                                non_empty_response_handler!(),
                                fq_response_type =
                                    [package.as_str(), rpc.response.as_str()].join("."),
                                response_type = rpc.response
                            );
                            format!(
                                method_template!(),
                                method = rpc.method.to_lowercase(),
                                client_name = format!("{}Client", name),
                                fq_request_type =
                                    [package.as_str(), rpc.request.as_str()].join("."),
                                request_type = rpc.request,
                                response_handler = response_handler
                            )
                        }
                    };
                    rust_file_writer.write_all(method.as_bytes())?;
                    // Write a line to load Rust function.
                    let method_load_line =
                        format!(method_load_template!(), method = rpc.method.to_lowercase());
                    q_file_writer.write_all(method_load_line.as_bytes())?;
                }
                Ok(())
            }
        }
        Node::Enum { name, elements } => {
            // Write enum definition
            let elements = elements.join("`");
            let enum_definition = format!(enum_template!(), source = name, elements = elements);
            q_file_writer.write_all(enum_definition.as_bytes())
        }
    }
}
fn ast_to_code ( rust_file_writer : & mut BufWriter < File > , q_file_writer : & mut BufWriter < File > , ast : Node , package : & mut String , ) -> io :: Result < ( ) > { match ast { Node :: Package ( pkg ) => { // Store package name * package = pkg ; Ok ( ( ) ) } Node :: Service { name , messages , rpcs , } => { if package . is_empty ( ) { Err ( Error :: new ( ErrorKind :: InvalidData , " " , ) ) } else { let snake_case_service = camel_to_snake ( name . as_str ( ) ) ; // Write import lines. let import = format ! ( import_template ( ) package package as_str ( ) snake_case_service snake_case_service as_str ( ) service name as_str ( ) messages messages join ( " " ) ) ; rust_file_writer . write_all ( import . as_bytes ( ) ) ? ; // Write method code. for rpc in rpcs { let method = match ( rpc . request . as_str ( ) , rpc . response . as_str ( ) ) { ( " " , " " ) => { format ! ( empty_input_method_template ( ) method rpc method to_lowercase ( ) client_name format ( " " name ) response_handler EMPTY_RESPONSE_HANDLER ) } ( " " , _ ) => { let response_handler = format ! ( non_empty_response_handler ( ) fq_response_type [ package as_str ( ) rpc response as_str ( ) ] join ( " " ) response_type rpc response ) ; format ! ( empty_input_method_template ( ) method rpc method to_lowercase ( ) client_name format ( " " name ) response_handler response_handler ) } ( _ , " " ) => { format ! ( method_template ( ) method rpc method to_lowercase ( ) client_name format ( " " name ) fq_request_type [ package as_str ( ) rpc request as_str ( ) ] join ( " " ) request_type rpc request response_handler EMPTY_RESPONSE_HANDLER ) } _ => { let response_handler = format ! ( non_empty_response_handler ( ) fq_response_type [ package as_str ( ) rpc response as_str ( ) ] join ( " " ) response_type rpc response ) ; format ! ( method_template ( ) method rpc method to_lowercase ( ) client_name format ( " " name ) fq_request_type [ package as_str ( ) rpc request as_str ( ) ] join ( " " ) request_type rpc request response_handler response_handler ) } } ; rust_file_writer . write_all ( method . as_bytes ( ) ) ? ; // Write a line to load Rust function. let method_load_line = format ! ( method_load_template ( ) method rpc method to_lowercase ( ) ) ; q_file_writer . write_all ( method_load_line . as_bytes ( ) ) ? ; } Ok ( ( ) ) } } Node :: Enum { name , elements } => { // Write enum definition let elements = elements . join ( " " ) ; let enum_definition = format ! ( enum_template ( ) source name elements elements ) ; q_file_writer . write_all ( enum_definition . as_bytes ( ) ) } } }
Consume AST and convert it to code.
Consume AST and convert it to code .
rust_file_writer
&mut BufWriter<File>
q_file_writer
&mut BufWriter<File>
ast
Node
package
&mut String
rust_file_writer
&mut BufWriter<File>
q_file_writer
&mut BufWriter<File>
ast
Node
package
&mut String