use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct WorkspaceEntry {
pub path: String,
pub name: Option<String>,
pub team: Option<String>,
pub tags: Option<Vec<String>>,
pub policy_overrides: Option<toml::Value>,
}
#[derive(Debug, Clone)]
pub struct ResolvedWorkspace {
pub canonical_path: std::path::PathBuf,
pub name: String,
pub team: Option<String>,
pub tags: Vec<String>,
pub status: WorkspaceStatus,
}
#[derive(Debug, Clone, PartialEq)]
pub enum WorkspaceStatus {
Available,
Unavailable(String),
Scanning,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn workspace_entry_round_trip() {
let entry = WorkspaceEntry {
path: "$HOME/repos/payment-service".to_string(),
name: Some("payment-service".to_string()),
team: Some("payments".to_string()),
tags: Some(vec!["production".to_string(), "pci".to_string()]),
policy_overrides: None,
};
let json = serde_json::to_string(&entry).expect("serialize");
let decoded: WorkspaceEntry = serde_json::from_str(&json).expect("deserialize");
assert_eq!(decoded.path, entry.path);
assert_eq!(decoded.name, entry.name);
assert_eq!(decoded.team, entry.team);
assert_eq!(decoded.tags, entry.tags);
}
#[test]
fn workspace_entry_minimal_fields() {
let json = r#"{"path": "/home/user/foo"}"#;
let entry: WorkspaceEntry = serde_json::from_str(json).expect("deserialize");
assert_eq!(entry.path, "/home/user/foo");
assert!(entry.name.is_none());
assert!(entry.team.is_none());
assert!(entry.tags.is_none());
assert!(entry.policy_overrides.is_none());
}
#[test]
fn workspace_status_equality() {
assert_eq!(WorkspaceStatus::Available, WorkspaceStatus::Available);
assert_eq!(
WorkspaceStatus::Unavailable("no such path".to_string()),
WorkspaceStatus::Unavailable("no such path".to_string()),
);
assert_ne!(WorkspaceStatus::Available, WorkspaceStatus::Scanning);
}
#[test]
fn resolved_workspace_debug_clone() {
let rw = ResolvedWorkspace {
canonical_path: std::path::PathBuf::from("/home/user/foo"),
name: "foo".to_string(),
team: None,
tags: vec![],
status: WorkspaceStatus::Available,
};
let cloned = rw.clone();
assert_eq!(cloned.name, "foo");
let _ = format!("{:?}", rw);
}
}