ferment_sys/lang/rust/
mod.rs1mod 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}