Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide/src/fetch_crates.rs')
| -rw-r--r-- | crates/ide/src/fetch_crates.rs | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/crates/ide/src/fetch_crates.rs b/crates/ide/src/fetch_crates.rs new file mode 100644 index 0000000000..c0bc4103c2 --- /dev/null +++ b/crates/ide/src/fetch_crates.rs @@ -0,0 +1,59 @@ +use ide_db::{ + base_db::{CrateOrigin, SourceDatabase, SourceDatabaseExt}, + RootDatabase, +}; + +#[derive(Debug)] +pub struct CrateInfo { + pub name: String, + pub version: String, + pub path: String, +} + +pub(crate) fn fetch_crates(db: &RootDatabase) -> Vec<CrateInfo> { + let crate_graph = db.crate_graph(); + crate_graph + .iter() + .map(|crate_id| &crate_graph[crate_id]) + .filter(|&data| !matches!(data.origin, CrateOrigin::Local { .. })) + .map(|data| { + let crate_name = crate_name(data); + let version = data.version.clone().unwrap_or_else(|| "".to_owned()); + let crate_path = crate_path(db, data, &crate_name); + + CrateInfo { name: crate_name, version, path: crate_path } + }) + .collect() +} + +fn crate_name(data: &ide_db::base_db::CrateData) -> String { + data.display_name + .clone() + .map(|it| it.canonical_name().to_owned()) + .unwrap_or("unknown".to_string()) +} + +fn crate_path(db: &RootDatabase, data: &ide_db::base_db::CrateData, crate_name: &str) -> String { + let source_root_id = db.file_source_root(data.root_file_id); + let source_root = db.source_root(source_root_id); + let source_root_path = source_root.path_for_file(&data.root_file_id); + match source_root_path.cloned() { + Some(mut root_path) => { + let mut crate_path = "".to_string(); + while let Some(vfs_path) = root_path.parent() { + match vfs_path.name_and_extension() { + Some((name, _)) => { + if name.starts_with(crate_name) { + crate_path = vfs_path.to_string(); + break; + } + } + None => break, + } + root_path = vfs_path; + } + crate_path + } + None => "".to_owned(), + } +} |