aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_project_model/src/cargo_workspace.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_project_model/src/cargo_workspace.rs')
-rw-r--r--crates/ra_project_model/src/cargo_workspace.rs105
1 files changed, 41 insertions, 64 deletions
diff --git a/crates/ra_project_model/src/cargo_workspace.rs b/crates/ra_project_model/src/cargo_workspace.rs
index 10ecfa951..43dbd096a 100644
--- a/crates/ra_project_model/src/cargo_workspace.rs
+++ b/crates/ra_project_model/src/cargo_workspace.rs
@@ -1,6 +1,9 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use std::path::{Path, PathBuf}; 3use std::{
4 ops,
5 path::{Path, PathBuf},
6};
4 7
5use anyhow::{Context, Result}; 8use anyhow::{Context, Result};
6use cargo_metadata::{CargoOpt, Message, MetadataCommand, PackageId}; 9use cargo_metadata::{CargoOpt, Message, MetadataCommand, PackageId};
@@ -24,6 +27,20 @@ pub struct CargoWorkspace {
24 workspace_root: PathBuf, 27 workspace_root: PathBuf,
25} 28}
26 29
30impl ops::Index<Package> for CargoWorkspace {
31 type Output = PackageData;
32 fn index(&self, index: Package) -> &PackageData {
33 &self.packages[index]
34 }
35}
36
37impl ops::Index<Target> for CargoWorkspace {
38 type Output = TargetData;
39 fn index(&self, index: Target) -> &TargetData {
40 &self.targets[index]
41 }
42}
43
27#[derive(Deserialize, Clone, Debug, PartialEq, Eq)] 44#[derive(Deserialize, Clone, Debug, PartialEq, Eq)]
28#[serde(rename_all = "camelCase", default)] 45#[serde(rename_all = "camelCase", default)]
29pub struct CargoFeatures { 46pub struct CargoFeatures {
@@ -61,15 +78,15 @@ pub struct Target(RawId);
61impl_arena_id!(Target); 78impl_arena_id!(Target);
62 79
63#[derive(Debug, Clone)] 80#[derive(Debug, Clone)]
64struct PackageData { 81pub struct PackageData {
65 name: String, 82 pub name: String,
66 manifest: PathBuf, 83 pub manifest: PathBuf,
67 targets: Vec<Target>, 84 pub targets: Vec<Target>,
68 is_member: bool, 85 pub is_member: bool,
69 dependencies: Vec<PackageDependency>, 86 pub dependencies: Vec<PackageDependency>,
70 edition: Edition, 87 pub edition: Edition,
71 features: Vec<String>, 88 pub features: Vec<String>,
72 out_dir: Option<PathBuf>, 89 pub out_dir: Option<PathBuf>,
73} 90}
74 91
75#[derive(Debug, Clone)] 92#[derive(Debug, Clone)]
@@ -79,12 +96,12 @@ pub struct PackageDependency {
79} 96}
80 97
81#[derive(Debug, Clone)] 98#[derive(Debug, Clone)]
82struct TargetData { 99pub struct TargetData {
83 pkg: Package, 100 pub package: Package,
84 name: String, 101 pub name: String,
85 root: PathBuf, 102 pub root: PathBuf,
86 kind: TargetKind, 103 pub kind: TargetKind,
87 is_proc_macro: bool, 104 pub is_proc_macro: bool,
88} 105}
89 106
90#[derive(Debug, Clone, Copy, PartialEq, Eq)] 107#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -115,52 +132,9 @@ impl TargetKind {
115 } 132 }
116} 133}
117 134
118impl Package { 135impl PackageData {
119 pub fn name(self, ws: &CargoWorkspace) -> &str { 136 pub fn root(&self) -> &Path {
120 ws.packages[self].name.as_str() 137 self.manifest.parent().unwrap()
121 }
122 pub fn root(self, ws: &CargoWorkspace) -> &Path {
123 ws.packages[self].manifest.parent().unwrap()
124 }
125 pub fn edition(self, ws: &CargoWorkspace) -> Edition {
126 ws.packages[self].edition
127 }
128 pub fn features(self, ws: &CargoWorkspace) -> &[String] {
129 &ws.packages[self].features
130 }
131 pub fn targets<'a>(self, ws: &'a CargoWorkspace) -> impl Iterator<Item = Target> + 'a {
132 ws.packages[self].targets.iter().cloned()
133 }
134 #[allow(unused)]
135 pub fn is_member(self, ws: &CargoWorkspace) -> bool {
136 ws.packages[self].is_member
137 }
138 pub fn dependencies<'a>(
139 self,
140 ws: &'a CargoWorkspace,
141 ) -> impl Iterator<Item = &'a PackageDependency> + 'a {
142 ws.packages[self].dependencies.iter()
143 }
144 pub fn out_dir(self, ws: &CargoWorkspace) -> Option<&Path> {
145 ws.packages[self].out_dir.as_ref().map(PathBuf::as_path)
146 }
147}
148
149impl Target {
150 pub fn package(self, ws: &CargoWorkspace) -> Package {
151 ws.targets[self].pkg
152 }
153 pub fn name(self, ws: &CargoWorkspace) -> &str {
154 ws.targets[self].name.as_str()
155 }
156 pub fn root(self, ws: &CargoWorkspace) -> &Path {
157 ws.targets[self].root.as_path()
158 }
159 pub fn kind(self, ws: &CargoWorkspace) -> TargetKind {
160 ws.targets[self].kind
161 }
162 pub fn is_proc_macro(self, ws: &CargoWorkspace) -> bool {
163 ws.targets[self].is_proc_macro
164 } 138 }
165} 139}
166 140
@@ -219,7 +193,7 @@ impl CargoWorkspace {
219 for meta_tgt in meta_pkg.targets { 193 for meta_tgt in meta_pkg.targets {
220 let is_proc_macro = meta_tgt.kind.as_slice() == ["proc-macro"]; 194 let is_proc_macro = meta_tgt.kind.as_slice() == ["proc-macro"];
221 let tgt = targets.alloc(TargetData { 195 let tgt = targets.alloc(TargetData {
222 pkg, 196 package: pkg,
223 name: meta_tgt.name, 197 name: meta_tgt.name,
224 root: meta_tgt.src_path.clone(), 198 root: meta_tgt.src_path.clone(),
225 kind: TargetKind::new(meta_tgt.kind.as_slice()), 199 kind: TargetKind::new(meta_tgt.kind.as_slice()),
@@ -265,7 +239,10 @@ impl CargoWorkspace {
265 } 239 }
266 240
267 pub fn target_by_root(&self, root: &Path) -> Option<Target> { 241 pub fn target_by_root(&self, root: &Path) -> Option<Target> {
268 self.packages().filter_map(|pkg| pkg.targets(self).find(|it| it.root(self) == root)).next() 242 self.packages()
243 .filter_map(|pkg| self[pkg].targets.iter().find(|&&it| self[it].root == root))
244 .next()
245 .copied()
269 } 246 }
270 247
271 pub fn workspace_root(&self) -> &Path { 248 pub fn workspace_root(&self) -> &Path {