ferment_sys/lang/rust/
mod.rs

1use 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}