ready_set_rust/
workspace.rs1use std::path::{Path, PathBuf};
4
5use ready_set_sdk::{Error, Result};
6use toml_edit::DocumentMut;
7
8#[derive(Debug, Clone)]
10pub struct Workspace {
11 pub root: PathBuf,
13 pub manifest_path: PathBuf,
15 pub has_workspace_table: bool,
17 pub has_package_table: bool,
19}
20
21pub fn resolve(cwd: &Path) -> Result<Option<Workspace>> {
28 let mut nearest_manifest: Option<PathBuf> = None;
29 let mut cur: Option<&Path> = Some(cwd);
30
31 while let Some(dir) = cur {
32 let manifest = dir.join("Cargo.toml");
33 if manifest.is_file() && nearest_manifest.is_none() {
34 nearest_manifest = Some(manifest);
35 }
36 if dir.join(".git").exists() {
37 break;
38 }
39 cur = dir.parent();
40 }
41
42 let Some(manifest_path) = nearest_manifest else {
43 return Ok(None);
44 };
45
46 let raw = std::fs::read_to_string(&manifest_path)?;
47 let doc: DocumentMut = raw.parse().map_err(|e: toml_edit::TomlError| {
48 Error::TomlParse(format!("{}: {e}", manifest_path.display()))
49 })?;
50
51 let has_workspace_table = doc.get("workspace").is_some();
52 let has_package_table = doc.get("package").is_some();
53
54 if !has_workspace_table && !has_package_table {
55 return Ok(None);
56 }
57
58 let root = manifest_path
59 .parent()
60 .ok_or_else(|| Error::Other(format!("{} has no parent", manifest_path.display())))?
61 .to_path_buf();
62
63 Ok(Some(Workspace {
64 root,
65 manifest_path,
66 has_workspace_table,
67 has_package_table,
68 }))
69}