1pub mod extract;
2pub mod metadata;
3pub mod module;
4pub mod target;
5
6use anyhow::Result;
7use cargo_metadata::{CargoOpt, MetadataCommand};
8use std::fs::read_to_string;
9
10pub fn concat_source(cargo_toml: &str, target: Option<&String>) -> Result<String> {
11 let metadata = MetadataCommand::new()
12 .manifest_path(cargo_toml)
13 .features(CargoOpt::AllFeatures)
14 .exec()?;
15 let source_path = target::get_target_source_path(&metadata, target)?;
16 log::info!("Target found: {:?}", source_path);
17
18 let source_code = read_to_string(&source_path)?;
19 let source_file = syn::parse_file(&source_code)?;
20
21 let libs = extract::extract_modules(&source_file)
22 .into_iter()
23 .map(|ident| ident.to_string())
24 .collect::<Vec<_>>();
25 log::info!("Extracted modules: {:?}", libs);
26 let mut paths = vec![];
27 for lib_name in libs {
28 if lib_name.as_str() == "std" || lib_name.as_str() == "crate" {
29 continue;
30 }
31
32 match metadata::get_module_lib_file(&metadata, &lib_name) {
33 Ok(lib_path) => paths.push((lib_name, lib_path)),
34 Err(e) => log::warn!("{:?}", e),
35 }
36 }
37
38 let mut file_content = quote::quote!(#source_file).to_string();
39
40 for (lib_name, lib_path) in paths {
41 let ident = quote::format_ident!("{}", lib_name);
42 let file = module::concat_module(lib_path, true)?;
43 file_content.push_str(quote::quote! {mod #ident {#file}}.to_string().as_str());
44 }
45 Ok(file_content)
46}