ferment_sys/lang/rust/
mod.rs

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