ferment_sys/lang/rust/
mod.rs1use std::fmt::{Display, Formatter};
2use std::path::PathBuf;
3use std::sync::{Arc, RwLock};
4use cargo_metadata::MetadataCommand;
5use proc_macro2::Ident;
6use quote::format_ident;
7use syn::Attribute;
8use crate::context::GlobalContext;
9use crate::error;
10use crate::tree::{FileTreeProcessor, ScopeTreeExportItem};
11
12#[derive(Debug, Clone, Eq, PartialEq, Hash)]
13pub struct Crate {
14 pub name: String,
15 pub root_path: PathBuf,
16}
17
18impl Display for Crate {
19 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
20 f.write_str(format!("Crate: {} ({:?})", self.name, self.root_path).as_str())
21 }
22}
23impl Crate {
24 pub fn current_with_name(name: &str) -> Self {
25 Self { name: name.to_string(), root_path: std::path::Path::new("src").to_path_buf() }
26 }
27 pub fn new(name: &str, root_path: PathBuf) -> Self {
28 Self { name: name.to_string(), root_path }
29 }
30 pub fn ident(&self) -> Ident {
31 format_ident!("{}", self.name)
32 }
33 pub fn root_path(&self) -> PathBuf {
34 self.root_path.join("lib.rs")
35 }
36
37 pub fn process(&self, attrs: Vec<Attribute>, context: &Arc<RwLock<GlobalContext>>) -> Result<ScopeTreeExportItem, error::Error> {
38 FileTreeProcessor::process_crate_tree(self, attrs, context)
39 }
40}
41
42pub(crate) fn find_crates_paths(crate_names: Vec<&str>) -> Vec<Crate> {
43 let metadata = MetadataCommand::new().exec().unwrap();
44 crate_names.into_iter()
45 .filter_map(|crate_name| {
46 metadata.packages
47 .iter()
48 .find_map(|p| {
49 if p.name.as_str() == crate_name {
50 if let Some(target) = p.targets.first() {
51 return Some(
52 Crate::new(
53 p.name
54 .replace("-", "_")
55 .as_str(),
56 PathBuf::from(target.src_path.parent()
57 .unwrap())))
58 }
59 }
60 None
61 })
62 })
63 .collect()
64}