1use serde::{Deserialize, Serialize};
9use std::path::PathBuf;
10
11#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
14pub struct Workspace {
15 pub root: PathBuf,
16 pub members: Vec<PathBuf>,
18 pub adapter: String,
20 #[serde(default)]
24 pub shared_metadata: indexmap::IndexMap<String, String>,
25}
26
27impl Workspace {
28 #[must_use]
31 pub fn new(
32 root: impl Into<PathBuf>,
33 members: Vec<PathBuf>,
34 adapter: impl Into<String>,
35 ) -> Self {
36 Self {
37 root: root.into(),
38 members,
39 adapter: adapter.into(),
40 shared_metadata: indexmap::IndexMap::new(),
41 }
42 }
43
44 #[must_use]
47 pub fn single_package(root: impl Into<PathBuf>, adapter: impl Into<String>) -> Self {
48 let root = root.into();
49 Self::new(root.clone(), vec![root], adapter)
50 }
51
52 #[must_use]
54 pub fn is_multi_package(&self) -> bool {
55 self.members.len() > 1
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62
63 #[test]
64 fn single_package_workspace_isnt_multi() {
65 let w = Workspace::single_package("/x", "cargo");
66 assert!(!w.is_multi_package());
67 }
68
69 #[test]
70 fn multi_member_workspace_is_multi() {
71 let w = Workspace::new(
72 "/x",
73 vec![PathBuf::from("a"), PathBuf::from("b")],
74 "cargo",
75 );
76 assert!(w.is_multi_package());
77 }
78
79 #[test]
80 fn round_trip_through_serde() {
81 let w = Workspace::new(
82 "/x",
83 vec![PathBuf::from("a"), PathBuf::from("b")],
84 "cargo",
85 );
86 let j = serde_json::to_string(&w).unwrap();
87 let parsed: Workspace = serde_json::from_str(&j).unwrap();
88 assert_eq!(w, parsed);
89 }
90}