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