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.rs59
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(),
+ }
+}