use serde::{Deserialize, Serialize}; use serde_json::Value; use time::OffsetDateTime; use crate::ids::WorkspaceId; #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] pub enum WorkspaceStatus { Active, Archived, } #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] pub struct Workspace { pub id: WorkspaceId, pub slug: String, pub display_name: String, pub status: WorkspaceStatus, pub settings: Value, #[serde(with = "time::serde::rfc3339")] pub created_at: OffsetDateTime, #[serde(with = "time::serde::rfc3339")] pub updated_at: OffsetDateTime, } #[cfg(test)] mod tests { use serde_json::json; use time::{OffsetDateTime, format_description::well_known::Rfc3339}; use super::{Workspace, WorkspaceStatus}; use crate::ids::WorkspaceId; #[test] fn workspace_serializes_timestamps_as_rfc3339() { let workspace = Workspace { id: WorkspaceId::new("ws_01"), slug: "primary".to_owned(), display_name: "Primary".to_owned(), status: WorkspaceStatus::Active, settings: json!({"region":"eu"}), created_at: OffsetDateTime::parse("2026-03-25T12:00:00Z", &Rfc3339).unwrap(), updated_at: OffsetDateTime::parse("2026-03-25T12:05:00Z", &Rfc3339).unwrap(), }; let value = serde_json::to_value(&workspace).unwrap(); assert_eq!(value["created_at"], json!("2026-03-25T12:00:00Z")); assert_eq!(value["updated_at"], json!("2026-03-25T12:05:00Z")); } #[test] fn workspace_deserializes_timestamps_from_rfc3339() { let workspace: Workspace = serde_json::from_value(json!({ "id": "ws_01", "slug": "primary", "display_name": "Primary", "status": "active", "settings": {"region":"eu"}, "created_at": "2026-03-25T12:00:00Z", "updated_at": "2026-03-25T12:05:00Z" })) .unwrap(); assert_eq!( workspace.created_at, OffsetDateTime::parse("2026-03-25T12:00:00Z", &Rfc3339).unwrap() ); assert_eq!( workspace.updated_at, OffsetDateTime::parse("2026-03-25T12:05:00Z", &Rfc3339).unwrap() ); } }