monoio_rust2go_cli/
lib.rs1use std::io::Cursor;
2
3use clap::Parser;
4use monoio_rust2go_common::raw_file::RawRsFile;
5
6#[derive(Parser, Debug, Default, Clone)]
7#[command(author, version, about, long_about = None)]
8pub struct Args {
9 #[arg(short, long)]
11 pub src: String,
12
13 #[arg(short, long)]
15 pub dst: String,
16
17 #[arg(long, default_value = "false")]
19 pub without_main: bool,
20
21 #[arg(long, default_value = "false")]
23 pub go118: bool,
24
25 #[arg(long, default_value = "false")]
27 pub no_fmt: bool,
28}
29
30pub fn generate(args: &Args) {
31 let file_content = std::fs::read_to_string(&args.src).expect("Unable to read file");
33 let raw_file = RawRsFile::new(file_content);
34
35 let (name_mapping, ref_content) = raw_file
37 .convert_structs_to_ref()
38 .expect("Unable to convert to ref");
39 std::fs::write(&args.dst, ref_content.to_string()).expect("Unable to write file");
40
41 let mut cbuilder = cbindgen::Builder::new()
43 .with_language(cbindgen::Language::C)
44 .with_src(&args.dst)
45 .with_header("// Generated by rust2go. Please DO NOT edit this C part manually.");
46 for name in name_mapping.values() {
47 cbuilder = cbuilder.include_item(name.to_string());
48 }
49 let mut output = Vec::<u8>::new();
50 cbuilder
51 .generate()
52 .expect("Unable to generate bindings")
53 .write(Cursor::new(&mut output));
54
55 let mut output = String::from_utf8(output).expect("Unable to convert to string");
57
58 let traits = raw_file.convert_trait().unwrap();
59 traits
60 .iter()
61 .for_each(|t| output.push_str(&t.generate_c_callbacks()));
62
63 let import_reflect = if args.go118 { "\n\"reflect\"" } else { "" };
64 let mut go_content = format!(
65 "package main\n\n/*\n{output}*/\nimport \"C\"\nimport ({import_reflect}\n\"unsafe\"\n\"runtime\"\n)\n"
66);
67 let levels = raw_file.convert_structs_levels().unwrap();
68 traits.iter().for_each(|t| {
69 go_content.push_str(&t.generate_go_interface());
70 go_content.push_str(&t.generate_go_exports(&levels));
71 });
72 go_content.push_str(
73 &raw_file
74 .convert_structs_to_go(&levels, args.go118)
75 .expect("Unable to generate go structs"),
76 );
77 if !args.without_main {
78 go_content.push_str("func main() {}\n");
79 }
80
81 std::fs::write(&args.dst, go_content).expect("Unable to write file");
82
83 if !args.no_fmt {
84 std::process::Command::new("go")
85 .arg("fmt")
86 .arg(&args.dst)
87 .status()
88 .unwrap();
89 }
90}