rsbind_core/base/
artifact.rs1use crate::ast::contract::desc::{StructDesc, TraitDesc};
2use crate::errors::*;
3use crate::AstResult;
4use std::fs;
5use std::path::PathBuf;
6
7pub(crate) struct NativeCodeGen<'a, Extra>
8where
9 Extra: Clone,
10{
11 pub gen_dir: &'a PathBuf,
12 pub file_ext: String,
13 pub ast: &'a AstResult,
14 pub extra: Extra,
15 pub strategy: NativeGenStrategy<'a, Extra>,
16}
17
18pub(crate) struct GenContext<'a, Extra>
19where
20 Extra: Clone,
21{
22 pub ast: &'a AstResult,
23 pub extra: Extra,
24 pub callbacks: Vec<TraitDesc>,
25}
26
27pub(crate) struct NativeGenStrategy<'a, Extra>
28where
29 Extra: Clone,
30{
31 pub gen_bridge_callback: Box<dyn Fn(&GenContext<'a, Extra>, &TraitDesc) -> Result<String>>,
32 pub gen_callback: Box<dyn Fn(&GenContext<'a, Extra>, &TraitDesc) -> Result<String>>,
33 pub gen_bridge_trait: Box<dyn Fn(&GenContext<'a, Extra>, &TraitDesc) -> Result<String>>,
34 pub gen_wrapper_trait: Box<dyn Fn(&GenContext<'a, Extra>, &TraitDesc) -> Result<String>>,
35 pub gen_trait: Box<dyn Fn(&GenContext<'a, Extra>, &TraitDesc) -> Result<String>>,
36 pub gen_struct: Box<dyn Fn(&GenContext<'a, Extra>, &StructDesc) -> Result<String>>,
37 pub gen_manager: Box<dyn Fn(&GenContext<'a, Extra>) -> Result<String>>,
38}
39
40impl<'a, Extra> NativeCodeGen<'a, Extra>
41where
42 Extra: Clone,
43{
44 pub(crate) fn gen_files(&self) -> Result<()> {
45 let mut callbacks = vec![];
47 for desc in self.ast.traits.iter() {
48 let descs = desc.1;
49 for each in descs.iter() {
50 if each.is_callback {
51 callbacks.push(each.clone());
52 }
53 }
54 }
55
56 let ctx = GenContext {
57 ast: self.ast,
58 extra: self.extra.clone(),
59 callbacks: callbacks.clone(),
60 };
61
62 for each in callbacks.clone().iter() {
64 let callback_str = (*self.strategy.gen_callback)(&ctx, each)?;
65 let file_name = format!("{}.{}", &each.name, &self.file_ext);
66 let callback_path = self.gen_dir.clone().join(file_name);
67 fs::write(callback_path, callback_str)?;
68
69 let callback_str = (*self.strategy.gen_bridge_callback)(&ctx, each)?;
70 let file_name = format!("Internal{}.{}", &each.name, &self.file_ext);
71 let callback_path = self.gen_dir.clone().join(file_name);
72 fs::write(callback_path, callback_str)?;
73 }
74
75 for desc in self.ast.traits.iter() {
77 let descs = desc.1;
78 for each in descs.iter() {
79 if !each.is_callback {
80 let str = (*self.strategy.gen_bridge_trait)(&ctx, each)?;
81 let file_name = format!("Internal{}.{}", &each.name, &self.file_ext);
82 let path = self.gen_dir.clone().join(file_name);
83 fs::write(path, str)?;
84
85 let str = (*self.strategy.gen_wrapper_trait)(&ctx, each)?;
86 let file_name = format!("Rust{}.{}", &each.name, &self.file_ext);
87 let path = self.gen_dir.clone().join(file_name);
88 fs::write(path, str)?;
89
90 let str = (*self.strategy.gen_trait)(&ctx, each)?;
91 let file_name = format!("{}.{}", &each.name, &self.file_ext);
92 let path = self.gen_dir.clone().join(file_name);
93 fs::write(path, str)?;
94 }
95 }
96 }
97
98 for (_key, struct_descs) in self.ast.structs.iter() {
100 for struct_desc in struct_descs.iter() {
101 let struct_str = (*self.strategy.gen_struct)(&ctx, struct_desc)?;
102 let file_name = format!("{}.{}", &struct_desc.name, &self.file_ext);
103 let path = self.gen_dir.join(file_name);
104 fs::write(path, struct_str)?
105 }
106 }
107
108 let manager_result = (*self.strategy.gen_manager)(&ctx)?;
109 let path = self.gen_dir.join(format!("RustLib.{}", &self.file_ext));
110 fs::write(path, manager_result)?;
111
112 Ok(())
113 }
114}