diff options
Diffstat (limited to 'crates/ra_lsp_server/src/cargo_target_spec.rs')
-rw-r--r-- | crates/ra_lsp_server/src/cargo_target_spec.rs | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/crates/ra_lsp_server/src/cargo_target_spec.rs b/crates/ra_lsp_server/src/cargo_target_spec.rs new file mode 100644 index 000000000..a66f14b82 --- /dev/null +++ b/crates/ra_lsp_server/src/cargo_target_spec.rs | |||
@@ -0,0 +1,100 @@ | |||
1 | use crate::{ | ||
2 | project_model::TargetKind, | ||
3 | server_world::ServerWorld, | ||
4 | Result | ||
5 | }; | ||
6 | |||
7 | use ra_ide_api::{FileId, RunnableKind}; | ||
8 | |||
9 | pub(crate) fn runnable_args( | ||
10 | world: &ServerWorld, | ||
11 | file_id: FileId, | ||
12 | kind: &RunnableKind, | ||
13 | ) -> Result<Vec<String>> { | ||
14 | let spec = CargoTargetSpec::for_file(world, file_id)?; | ||
15 | let mut res = Vec::new(); | ||
16 | match kind { | ||
17 | RunnableKind::Test { name } => { | ||
18 | res.push("test".to_string()); | ||
19 | if let Some(spec) = spec { | ||
20 | spec.push_to(&mut res); | ||
21 | } | ||
22 | res.push("--".to_string()); | ||
23 | res.push(name.to_string()); | ||
24 | res.push("--nocapture".to_string()); | ||
25 | } | ||
26 | RunnableKind::TestMod { path } => { | ||
27 | res.push("test".to_string()); | ||
28 | if let Some(spec) = spec { | ||
29 | spec.push_to(&mut res); | ||
30 | } | ||
31 | res.push("--".to_string()); | ||
32 | res.push(path.to_string()); | ||
33 | res.push("--nocapture".to_string()); | ||
34 | } | ||
35 | RunnableKind::Bin => { | ||
36 | res.push("run".to_string()); | ||
37 | if let Some(spec) = spec { | ||
38 | spec.push_to(&mut res); | ||
39 | } | ||
40 | } | ||
41 | } | ||
42 | Ok(res) | ||
43 | } | ||
44 | |||
45 | pub struct CargoTargetSpec { | ||
46 | pub package: String, | ||
47 | pub target: String, | ||
48 | pub target_kind: TargetKind, | ||
49 | } | ||
50 | |||
51 | impl CargoTargetSpec { | ||
52 | pub fn for_file(world: &ServerWorld, file_id: FileId) -> Result<Option<CargoTargetSpec>> { | ||
53 | let &crate_id = match world.analysis().crate_for(file_id)?.first() { | ||
54 | Some(crate_id) => crate_id, | ||
55 | None => return Ok(None), | ||
56 | }; | ||
57 | let file_id = world.analysis().crate_root(crate_id)?; | ||
58 | let path = world | ||
59 | .vfs | ||
60 | .read() | ||
61 | .file2path(ra_vfs::VfsFile(file_id.0.into())); | ||
62 | let res = world.workspaces.iter().find_map(|ws| { | ||
63 | let tgt = ws.cargo.target_by_root(&path)?; | ||
64 | let res = CargoTargetSpec { | ||
65 | package: tgt.package(&ws.cargo).name(&ws.cargo).to_string(), | ||
66 | target: tgt.name(&ws.cargo).to_string(), | ||
67 | target_kind: tgt.kind(&ws.cargo), | ||
68 | }; | ||
69 | Some(res) | ||
70 | }); | ||
71 | Ok(res) | ||
72 | } | ||
73 | |||
74 | pub fn push_to(self, buf: &mut Vec<String>) { | ||
75 | buf.push("--package".to_string()); | ||
76 | buf.push(self.package); | ||
77 | match self.target_kind { | ||
78 | TargetKind::Bin => { | ||
79 | buf.push("--bin".to_string()); | ||
80 | buf.push(self.target); | ||
81 | } | ||
82 | TargetKind::Test => { | ||
83 | buf.push("--test".to_string()); | ||
84 | buf.push(self.target); | ||
85 | } | ||
86 | TargetKind::Bench => { | ||
87 | buf.push("--bench".to_string()); | ||
88 | buf.push(self.target); | ||
89 | } | ||
90 | TargetKind::Example => { | ||
91 | buf.push("--example".to_string()); | ||
92 | buf.push(self.target); | ||
93 | } | ||
94 | TargetKind::Lib => { | ||
95 | buf.push("--lib".to_string()); | ||
96 | } | ||
97 | TargetKind::Other => (), | ||
98 | } | ||
99 | } | ||
100 | } | ||