aboutsummaryrefslogtreecommitdiff
path: root/crates/rust-analyzer/src/cargo_target_spec.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-02-18 11:37:45 +0000
committerAleksey Kladov <[email protected]>2020-02-18 11:37:45 +0000
commit865759925be6b72f7ef39124ed0e4c86c0412a69 (patch)
tree0fc36373073a66c2bbd6c7cfae6cb734527d847f /crates/rust-analyzer/src/cargo_target_spec.rs
parentc855e36696afa54260773a6bc8a358df67d60dea (diff)
Rename folder
Diffstat (limited to 'crates/rust-analyzer/src/cargo_target_spec.rs')
-rw-r--r--crates/rust-analyzer/src/cargo_target_spec.rs118
1 files changed, 118 insertions, 0 deletions
diff --git a/crates/rust-analyzer/src/cargo_target_spec.rs b/crates/rust-analyzer/src/cargo_target_spec.rs
new file mode 100644
index 000000000..53751aafb
--- /dev/null
+++ b/crates/rust-analyzer/src/cargo_target_spec.rs
@@ -0,0 +1,118 @@
1//! See `CargoTargetSpec`
2
3use ra_ide::{FileId, RunnableKind, TestId};
4use ra_project_model::{self, ProjectWorkspace, TargetKind};
5
6use crate::{world::WorldSnapshot, Result};
7
8/// Abstract representation of Cargo target.
9///
10/// We use it to cook up the set of cli args we need to pass to Cargo to
11/// build/test/run the target.
12pub(crate) struct CargoTargetSpec {
13 pub(crate) package: String,
14 pub(crate) target: String,
15 pub(crate) target_kind: TargetKind,
16}
17
18impl CargoTargetSpec {
19 pub(crate) fn runnable_args(
20 spec: Option<CargoTargetSpec>,
21 kind: &RunnableKind,
22 ) -> Result<Vec<String>> {
23 let mut res = Vec::new();
24 match kind {
25 RunnableKind::Test { test_id } => {
26 res.push("test".to_string());
27 if let Some(spec) = spec {
28 spec.push_to(&mut res);
29 }
30 res.push("--".to_string());
31 res.push(test_id.to_string());
32 if let TestId::Path(_) = test_id {
33 res.push("--exact".to_string());
34 }
35 res.push("--nocapture".to_string());
36 }
37 RunnableKind::TestMod { path } => {
38 res.push("test".to_string());
39 if let Some(spec) = spec {
40 spec.push_to(&mut res);
41 }
42 res.push("--".to_string());
43 res.push(path.to_string());
44 res.push("--nocapture".to_string());
45 }
46 RunnableKind::Bench { test_id } => {
47 res.push("bench".to_string());
48 if let Some(spec) = spec {
49 spec.push_to(&mut res);
50 }
51 res.push("--".to_string());
52 res.push(test_id.to_string());
53 if let TestId::Path(_) = test_id {
54 res.push("--exact".to_string());
55 }
56 res.push("--nocapture".to_string());
57 }
58 RunnableKind::Bin => {
59 res.push("run".to_string());
60 if let Some(spec) = spec {
61 spec.push_to(&mut res);
62 }
63 }
64 }
65 Ok(res)
66 }
67
68 pub(crate) fn for_file(
69 world: &WorldSnapshot,
70 file_id: FileId,
71 ) -> Result<Option<CargoTargetSpec>> {
72 let &crate_id = match world.analysis().crate_for(file_id)?.first() {
73 Some(crate_id) => crate_id,
74 None => return Ok(None),
75 };
76 let file_id = world.analysis().crate_root(crate_id)?;
77 let path = world.file_id_to_path(file_id);
78 let res = world.workspaces.iter().find_map(|ws| match ws {
79 ProjectWorkspace::Cargo { cargo, .. } => {
80 let tgt = cargo.target_by_root(&path)?;
81 Some(CargoTargetSpec {
82 package: tgt.package(&cargo).name(&cargo).to_string(),
83 target: tgt.name(&cargo).to_string(),
84 target_kind: tgt.kind(&cargo),
85 })
86 }
87 ProjectWorkspace::Json { .. } => None,
88 });
89 Ok(res)
90 }
91
92 pub(crate) fn push_to(self, buf: &mut Vec<String>) {
93 buf.push("--package".to_string());
94 buf.push(self.package);
95 match self.target_kind {
96 TargetKind::Bin => {
97 buf.push("--bin".to_string());
98 buf.push(self.target);
99 }
100 TargetKind::Test => {
101 buf.push("--test".to_string());
102 buf.push(self.target);
103 }
104 TargetKind::Bench => {
105 buf.push("--bench".to_string());
106 buf.push(self.target);
107 }
108 TargetKind::Example => {
109 buf.push("--example".to_string());
110 buf.push(self.target);
111 }
112 TargetKind::Lib => {
113 buf.push("--lib".to_string());
114 }
115 TargetKind::Other => (),
116 }
117 }
118}