datasynth_core/plugins/
timestamp_enricher.rs1use crate::error::SynthError;
6use crate::traits::plugin::{GeneratedRecord, TransformPlugin};
7
8pub struct TimestampEnricher;
11
12impl TimestampEnricher {
13 pub fn new() -> Self {
15 Self
16 }
17}
18
19impl Default for TimestampEnricher {
20 fn default() -> Self {
21 Self::new()
22 }
23}
24
25impl TransformPlugin for TimestampEnricher {
26 fn name(&self) -> &str {
27 "timestamp_enricher"
28 }
29
30 fn transform(&self, records: Vec<GeneratedRecord>) -> Result<Vec<GeneratedRecord>, SynthError> {
31 let now = crate::clock::now().to_rfc3339();
32 let version = serde_json::Value::String("1.0.0".to_string());
33
34 let enriched = records
35 .into_iter()
36 .map(|mut record| {
37 record
38 .fields
39 .insert("_generated_at".to_string(), serde_json::json!(now));
40 record
41 .fields
42 .insert("_plugin_version".to_string(), version.clone());
43 record
44 })
45 .collect();
46
47 Ok(enriched)
48 }
49}
50
51#[cfg(test)]
52mod tests {
53 use super::*;
54
55 #[test]
56 fn test_timestamp_enricher_adds_fields() {
57 let enricher = TimestampEnricher::new();
58
59 let records = vec![
60 GeneratedRecord::new("invoice").with_field("id", serde_json::json!("INV001")),
61 GeneratedRecord::new("invoice").with_field("id", serde_json::json!("INV002")),
62 ];
63
64 let result = enricher
65 .transform(records)
66 .expect("transform should succeed");
67 assert_eq!(result.len(), 2);
68
69 for record in &result {
70 assert!(
71 record.fields.contains_key("_generated_at"),
72 "should have _generated_at field"
73 );
74 assert_eq!(
75 record.get_str("_plugin_version"),
76 Some("1.0.0"),
77 "should have _plugin_version = 1.0.0"
78 );
79 assert!(
81 record.get_str("id").is_some(),
82 "original id field should be preserved"
83 );
84 }
85 }
86
87 #[test]
88 fn test_timestamp_enricher_empty_input() {
89 let enricher = TimestampEnricher::new();
90 let result = enricher
91 .transform(vec![])
92 .expect("transform should succeed");
93 assert!(result.is_empty());
94 }
95
96 #[test]
97 fn test_timestamp_enricher_preserves_existing_fields() {
98 let enricher = TimestampEnricher::new();
99
100 let records = vec![GeneratedRecord::new("order")
101 .with_field("customer", serde_json::json!("CUST001"))
102 .with_field("amount", serde_json::json!(1500.0))];
103
104 let result = enricher
105 .transform(records)
106 .expect("transform should succeed");
107 let record = &result[0];
108
109 assert_eq!(record.get_str("customer"), Some("CUST001"));
110 assert_eq!(record.get("amount").and_then(|v| v.as_f64()), Some(1500.0));
111 assert!(record.fields.contains_key("_generated_at"));
112 assert_eq!(record.get_str("_plugin_version"), Some("1.0.0"));
113 }
114}