vertigo_cli/build/
cargo_workspace.rs1use serde::Deserialize;
2use std::path::PathBuf;
3
4use crate::commons::{ErrorCode, command::CommandRun};
5
6#[derive(Clone, Debug, Deserialize)]
7pub struct Workspace {
8 packages: Vec<Package>,
9 target_directory: String,
10 workspace_members: Vec<String>,
11 workspace_root: String,
12}
13
14#[derive(Clone, Debug, Deserialize)]
15pub struct Package {
16 id: String,
17 name: String,
18 manifest_path: String,
19 targets: Vec<Target>,
20}
21
22#[derive(Clone, Debug, Deserialize)]
23pub struct Target {
24 kind: Vec<String>,
25}
26
27impl Workspace {
28 pub fn infer_package_name(&self) -> Option<String> {
29 for member_id in &self.workspace_members {
30 if let Some(package) = self
31 .packages
32 .iter()
33 .find(|package| &package.id == member_id)
34 && package.is_cdylib()
35 {
36 return Some(package.name.clone());
37 }
38 }
39 None
40 }
41
42 pub fn find_package_path(&self, package_name: &str) -> Option<PathBuf> {
43 self.packages
44 .iter()
45 .find(|package| package.name == package_name)
46 .map(|package| package.manifest_path.clone().into())
47 .and_then(|path: PathBuf| path.parent().map(|p| p.to_path_buf()))
48 }
49
50 pub fn get_target_dir(&self) -> PathBuf {
51 self.target_directory.clone().into()
52 }
53
54 pub fn get_root_dir(&self) -> &str {
55 &self.workspace_root
56 }
57}
58
59impl Package {
60 pub fn is_cdylib(&self) -> bool {
61 self.targets
62 .iter()
63 .any(|target| target.kind.iter().any(|kind| kind == "cdylib"))
64 }
65}
66
67pub fn get_workspace() -> Result<Workspace, ErrorCode> {
68 let metadata = CommandRun::new("cargo")
69 .add_param("metadata")
70 .add_param("--format-version=1")
71 .set_error_code(ErrorCode::CantOpenWorkspace)
72 .output()?;
73
74 match serde_json::from_str::<Workspace>(&metadata) {
75 Ok(mut ws) => {
76 ws.packages
78 .retain(|package| ws.workspace_members.contains(&package.id));
79 Ok(ws)
80 }
81 Err(err) => {
82 log::error!("Can't parse workspace: {err}");
83 Err(ErrorCode::CantParseWorkspace)
84 }
85 }
86}