ferment_sys/lang/rust/
mod.rs

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