1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use std::collections::HashMap;
4use std::path::{Path, PathBuf};
5
6#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
9pub struct Bond {
10 pub(crate) id: String,
11 pub(crate) name: Option<String>,
12 pub(crate) source: PathBuf,
13 pub(crate) target: PathBuf,
14 pub(crate) created_at: DateTime<Utc>,
15 pub(crate) metadata: Option<HashMap<String, String>>,
16}
17
18impl Bond {
19 pub fn new(source: PathBuf, target: PathBuf, name: Option<String>) -> Self {
21 Self {
22 id: uuid::Uuid::new_v4().to_string(),
23 name,
24 source,
25 target,
26 created_at: Utc::now(),
27 metadata: None,
28 }
29 }
30
31 pub fn created_at_rfc3339(&self) -> String {
33 self.created_at.to_rfc3339()
34 }
35 pub fn id(&self) -> &str {
37 &self.id
38 }
39 pub fn name(&self) -> Option<&str> {
41 self.name.as_deref()
42 }
43 pub fn source(&self) -> &Path {
45 &self.source
46 }
47 pub fn target(&self) -> &Path {
49 &self.target
50 }
51 pub fn created_at(&self) -> DateTime<Utc> {
53 self.created_at
54 }
55 pub fn metadata(&self) -> Option<&HashMap<String, String>> {
57 self.metadata.as_ref()
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64
65 #[test]
66 fn new_generates_unique_ids() {
67 let a = Bond::new(
68 PathBuf::from("/a"),
69 PathBuf::from("/b"),
70 Some("bond_a".to_string()),
71 );
72 let b = Bond::new(
73 PathBuf::from("/a"),
74 PathBuf::from("/b"),
75 Some("bond_b".to_string()),
76 );
77 assert_ne!(a.id, b.id); }
79
80 #[test]
81 fn created_at_rfc3339_roundtrips() {
82 let bond = Bond::new(
83 PathBuf::from("/a"),
84 PathBuf::from("/b"),
85 Some("bond".to_string()),
86 );
87 let rfc = bond.created_at_rfc3339();
88 let parsed = DateTime::parse_from_rfc3339(&rfc).unwrap();
90 assert_eq!(parsed.with_timezone(&Utc), bond.created_at);
91 }
92
93 #[test]
94 fn serializes_to_json() {
95 let bond = Bond::new(
96 PathBuf::from("/src"),
97 PathBuf::from("/tgt"),
98 Some("bond".to_string()),
99 );
100 let json = serde_json::to_string(&bond).unwrap();
101 let deserialized: Bond = serde_json::from_str(&json).unwrap();
102 assert_eq!(bond, deserialized);
103 }
104}