pub fn generate_code(files: &[impl AsRef<Path>], includes: &[impl AsRef<Path>]) -> io::Result<()> {
    // Open q target file.
    let q_output = OpenOptions::new()
        .read(false)
        .write(true)
        .truncate(true)
        .create(true)
        .open(TARGET_Q_FILE_NAME)?;
    let mut q_file_writer = BufWriter::new(q_output);

    // Write a header of q file.
    q_file_writer.write_all(Q_FILE_HEADER.as_bytes())?;

    // Open Rust target file.
    let rust_output = OpenOptions::new()
        .read(false)
        .write(true)
        .truncate(true)
        .create(true)
        .open(TARGET_RUST_FILE_NAME)?;
    let mut rust_file_writer = BufWriter::new(rust_output);

    // Write headers.
    rust_file_writer.write_all(RUST_FILE_HEADER.as_bytes())?;

    // Write definition of error buffer.
    rust_file_writer.write_all(ERROR_BUFFER.as_bytes())?;

    // Read inputs and check service related information.
    files
        .iter()
        .map(|file| {
            // Package name. Only one package name exists per file.
            let mut package = String::new();
            // String to parse service definition.
            let mut service_definition = String::new();
            // String to parse enum definition.
            let mut enum_definition = String::new();
            // Track service definition scope.
            let mut in_service_definition = false;
            // Track enum message definition scope.
            let mut in_enum_definition = false;
            // Try to open file and parse.
            let found = includes
                .iter()
                .map(|include_path| {
                    if let Ok(input) = OpenOptions::new()
                        .read(true)
                        .write(false)
                        .create(false)
                        .open(include_path.as_ref().join(file))
                    {
                        let mut line = String::new();
                        let mut reader = BufReader::new(input);
                        // Read each line and find package name, service name and associated messages.
                        while let Ok(num_bytes) = reader.read_line(&mut line) {
                            if num_bytes == 0 {
                                // Reached EOF
                                break;
                            }
                            if line.trim().starts_with("package") {
                                let mut analyzer = SemanticAnalyzer::new(line.as_str())?;
                                let ast = analyzer.parse()?;
                                ast_to_code(
                                    &mut rust_file_writer,
                                    &mut q_file_writer,
                                    ast,
                                    &mut package,
                                )?;
                                line.clear();
                            } else if line.trim().starts_with("service") {
                                in_service_definition = true;
                                service_definition += line.as_str();
                                line.clear();
                            } else if line.trim().starts_with("rpc") {
                                service_definition += line.as_str();
                                line.clear();
                            } else if line.trim().starts_with("enum") {
                                in_enum_definition = true;
                                enum_definition += line.as_str();
                                line.clear();
                            } else if line.trim().starts_with("}") {
                                if in_service_definition {
                                    // Closing brace of a service definition
                                    service_definition += line.as_str();
                                    // Analyze and generate code.
                                    let mut analyzer =
                                        SemanticAnalyzer::new(service_definition.as_str())?;
                                    let ast = analyzer.parse()?;
                                    ast_to_code(
                                        &mut rust_file_writer,
                                        &mut q_file_writer,
                                        ast,
                                        &mut package,
                                    )?;
                                    // Escape from service
                                    service_definition.clear();
                                    in_service_definition = false;
                                } else if in_enum_definition {
                                    // Closing brace of a enum definition
                                    enum_definition += line.as_str();
                                    // Analyze and generate code.
                                    let mut analyzer =
                                        SemanticAnalyzer::new(enum_definition.as_str())?;
                                    let ast = analyzer.parse()?;
                                    ast_to_code(
                                        &mut rust_file_writer,
                                        &mut q_file_writer,
                                        ast,
                                        &mut package,
                                    )?;
                                    // Escape from enum
                                    enum_definition.clear();
                                    in_enum_definition = false;
                                } else {
                                    // Nothing to do
                                }
                                line.clear();
                            } else {
                                if in_enum_definition
                                    && line.contains("=")
                                    && line.trim().ends_with(";")
                                {
                                    // Enum field definition `field = number;`
                                    enum_definition += line.as_str();
                                }
                                line.clear();
                            }
                        }
                        // File was found
                        Ok(true)
                    } else {
                        // File not found
                        Ok(false)
                    }
                })
                .collect::<io::Result<Vec<bool>>>()?;

            if found.iter().any(|result| *result) {
                Ok(())
            } else {
                Err(Error::new(
                    ErrorKind::NotFound,
                    format!(
                        "{} was not found in any include directories",
                        file.as_ref().to_str().unwrap()
                    ),
                ))
            }
        })
        .collect::<io::Result<()>>()?;

    Ok(())
}
/// Generate Rust code of gRPC client methods called from q.
Generate Rust code of gRPC client methods called from q.
Generate Rust code of gRPC client methods called from q .
pub fn generate_code(files: &[impl AsRef<Path>], includes: &[impl AsRef<Path>]) -> io::Result<()> {
    // Open q target file.
    let q_output = OpenOptions::new()
        .read(false)
        .write(true)
        .truncate(true)
        .create(true)
        .open(TARGET_Q_FILE_NAME)?;
    let mut q_file_writer = BufWriter::new(q_output);
    // Write a header of q file.
    q_file_writer.write_all(Q_FILE_HEADER.as_bytes())?;
    // Open Rust target file.
    let rust_output = OpenOptions::new()
        .read(false)
        .write(true)
        .truncate(true)
        .create(true)
        .open(TARGET_RUST_FILE_NAME)?;
    let mut rust_file_writer = BufWriter::new(rust_output);
    // Write headers.
    rust_file_writer.write_all(RUST_FILE_HEADER.as_bytes())?;
    // Write definition of error buffer.
    rust_file_writer.write_all(ERROR_BUFFER.as_bytes())?;
    // Read inputs and check service related information.
    files
        .iter()
        .map(|file| {
            // Package name. Only one package name exists per file.
            let mut package = String::new();
            // String to parse service definition.
            let mut service_definition = String::new();
            // String to parse enum definition.
            let mut enum_definition = String::new();
            // Track service definition scope.
            let mut in_service_definition = false;
            // Track enum message definition scope.
            let mut in_enum_definition = false;
            // Try to open file and parse.
            let found = includes
                .iter()
                .map(|include_path| {
                    if let Ok(input) = OpenOptions::new()
                        .read(true)
                        .write(false)
                        .create(false)
                        .open(include_path.as_ref().join(file))
                    {
                        let mut line = String::new();
                        let mut reader = BufReader::new(input);
                        // Read each line and find package name, service name and associated messages.
                        while let Ok(num_bytes) = reader.read_line(&mut line) {
                            if num_bytes == 0 {
                                // Reached EOF
                                break;
                            }
                            if line.trim().starts_with("package") {
                                let mut analyzer = SemanticAnalyzer::new(line.as_str())?;
                                let ast = analyzer.parse()?;
                                ast_to_code(
                                    &mut rust_file_writer,
                                    &mut q_file_writer,
                                    ast,
                                    &mut package,
                                )?;
                                line.clear();
                            } else if line.trim().starts_with("service") {
                                in_service_definition = true;
                                service_definition += line.as_str();
                                line.clear();
                            } else if line.trim().starts_with("rpc") {
                                service_definition += line.as_str();
                                line.clear();
                            } else if line.trim().starts_with("enum") {
                                in_enum_definition = true;
                                enum_definition += line.as_str();
                                line.clear();
                            } else if line.trim().starts_with("}") {
                                if in_service_definition {
                                    // Closing brace of a service definition
                                    service_definition += line.as_str();
                                    // Analyze and generate code.
                                    let mut analyzer =
                                        SemanticAnalyzer::new(service_definition.as_str())?;
                                    let ast = analyzer.parse()?;
                                    ast_to_code(
                                        &mut rust_file_writer,
                                        &mut q_file_writer,
                                        ast,
                                        &mut package,
                                    )?;
                                    // Escape from service
                                    service_definition.clear();
                                    in_service_definition = false;
                                } else if in_enum_definition {
                                    // Closing brace of a enum definition
                                    enum_definition += line.as_str();
                                    // Analyze and generate code.
                                    let mut analyzer =
                                        SemanticAnalyzer::new(enum_definition.as_str())?;
                                    let ast = analyzer.parse()?;
                                    ast_to_code(
                                        &mut rust_file_writer,
                                        &mut q_file_writer,
                                        ast,
                                        &mut package,
                                    )?;
                                    // Escape from enum
                                    enum_definition.clear();
                                    in_enum_definition = false;
                                } else {
                                    // Nothing to do
                                }
                                line.clear();
                            } else {
                                if in_enum_definition
                                    && line.contains("=")
                                    && line.trim().ends_with(";")
                                {
                                    // Enum field definition `field = number;`
                                    enum_definition += line.as_str();
                                }
                                line.clear();
                            }
                        }
                        // File was found
                        Ok(true)
                    } else {
                        // File not found
                        Ok(false)
                    }
                })
                .collect::<io::Result<Vec<bool>>>()?;
            if found.iter().any(|result| *result) {
                Ok(())
            } else {
                Err(Error::new(
                    ErrorKind::NotFound,
                    format!(
                        "{} was not found in any include directories",
                        file.as_ref().to_str().unwrap()
                    ),
                ))
            }
        })
        .collect::<io::Result<()>>()?;
    Ok(())
}
pub fn generate_code ( files : & [ impl AsRef < Path > ] , includes : & [ impl AsRef < Path > ] ) -> io :: Result < ( ) > { // Open q target file. let q_output = OpenOptions :: new ( ) . read ( false ) . write ( true ) . truncate ( true ) . create ( true ) . open ( TARGET_Q_FILE_NAME ) ? ; let mut q_file_writer = BufWriter :: new ( q_output ) ; // Write a header of q file. q_file_writer . write_all ( Q_FILE_HEADER . as_bytes ( ) ) ? ; // Open Rust target file. let rust_output = OpenOptions :: new ( ) . read ( false ) . write ( true ) . truncate ( true ) . create ( true ) . open ( TARGET_RUST_FILE_NAME ) ? ; let mut rust_file_writer = BufWriter :: new ( rust_output ) ; // Write headers. rust_file_writer . write_all ( RUST_FILE_HEADER . as_bytes ( ) ) ? ; // Write definition of error buffer. rust_file_writer . write_all ( ERROR_BUFFER . as_bytes ( ) ) ? ; // Read inputs and check service related information. files . iter ( ) . map ( | file | { // Package name. Only one package name exists per file. let mut package = String :: new ( ) ; // String to parse service definition. let mut service_definition = String :: new ( ) ; // String to parse enum definition. let mut enum_definition = String :: new ( ) ; // Track service definition scope. let mut in_service_definition = false ; // Track enum message definition scope. let mut in_enum_definition = false ; // Try to open file and parse. let found = includes . iter ( ) . map ( | include_path | { if let Ok ( input ) = OpenOptions :: new ( ) . read ( true ) . write ( false ) . create ( false ) . open ( include_path . as_ref ( ) . join ( file ) ) { let mut line = String :: new ( ) ; let mut reader = BufReader :: new ( input ) ; // Read each line and find package name, service name and associated messages. while let Ok ( num_bytes ) = reader . read_line ( & mut line ) { if num_bytes == 0 { // Reached EOF break ; } if line . trim ( ) . starts_with ( " " ) { let mut analyzer = SemanticAnalyzer :: new ( line . as_str ( ) ) ? ; let ast = analyzer . parse ( ) ? ; ast_to_code ( & mut rust_file_writer , & mut q_file_writer , ast , & mut package , ) ? ; line . clear ( ) ; } else if line . trim ( ) . starts_with ( " " ) { in_service_definition = true ; service_definition += line . as_str ( ) ; line . clear ( ) ; } else if line . trim ( ) . starts_with ( " " ) { service_definition += line . as_str ( ) ; line . clear ( ) ; } else if line . trim ( ) . starts_with ( " " ) { in_enum_definition = true ; enum_definition += line . as_str ( ) ; line . clear ( ) ; } else if line . trim ( ) . starts_with ( " " ) { if in_service_definition { // Closing brace of a service definition service_definition += line . as_str ( ) ; // Analyze and generate code. let mut analyzer = SemanticAnalyzer :: new ( service_definition . as_str ( ) ) ? ; let ast = analyzer . parse ( ) ? ; ast_to_code ( & mut rust_file_writer , & mut q_file_writer , ast , & mut package , ) ? ; // Escape from service service_definition . clear ( ) ; in_service_definition = false ; } else if in_enum_definition { // Closing brace of a enum definition enum_definition += line . as_str ( ) ; // Analyze and generate code. let mut analyzer = SemanticAnalyzer :: new ( enum_definition . as_str ( ) ) ? ; let ast = analyzer . parse ( ) ? ; ast_to_code ( & mut rust_file_writer , & mut q_file_writer , ast , & mut package , ) ? ; // Escape from enum enum_definition . clear ( ) ; in_enum_definition = false ; } else { // Nothing to do } line . clear ( ) ; } else { if in_enum_definition && line . contains ( " " ) && line . trim ( ) . ends_with ( " " ) { // Enum field definition `field = number;` enum_definition += line . as_str ( ) ; } line . clear ( ) ; } } // File was found Ok ( true ) } else { // File not found Ok ( false ) } } ) . collect :: < io :: Result < Vec < bool > > > ( ) ? ; if found . iter ( ) . any ( | result | * result ) { Ok ( ( ) ) } else { Err ( Error :: new ( ErrorKind :: NotFound , format ! ( " " file as_ref ( ) to_str ( ) unwrap ( ) ) , ) ) } } ) . collect :: < io :: Result < ( ) > > ( ) ? ; Ok ( ( ) ) }
Generate Rust code of gRPC client methods called from q.
Generate Rust code of gRPC client methods called from q .
files
&[impl AsRef<Path>]
includes
&[impl AsRef<Path>]
files
&[impl AsRef<Path>]
includes
&[impl AsRef<Path>]