airsprotocols_mcpserver_filesystem/filesystem/
operations.rs1use std::path::PathBuf;
5
6use chrono::{DateTime, Utc};
8use serde::{Deserialize, Serialize};
9
10use crate::mcp::OperationType;
12
13#[derive(Debug, Clone, Serialize, Deserialize)]
15pub struct FileOperation {
16 pub operation_type: OperationType,
18 pub path: PathBuf,
20 pub timestamp: DateTime<Utc>,
22 pub operation_id: String,
24}
25
26impl FileOperation {
27 pub fn new(operation_type: OperationType, path: PathBuf) -> Self {
29 Self {
30 operation_type,
31 path,
32 timestamp: Utc::now(), operation_id: uuid::Uuid::new_v4().to_string(),
34 }
35 }
36
37 pub fn description(&self) -> String {
39 format!(
40 "{:?} operation on '{}'",
41 self.operation_type,
42 self.path.display()
43 )
44 }
45}
46
47#[cfg(test)]
48#[allow(clippy::unwrap_used)]
49mod tests {
50 use super::*;
51
52 #[test]
53 fn test_file_operation_creation() {
54 let path = PathBuf::from("/test/path.txt");
55 let op = FileOperation::new(OperationType::Read, path.clone());
56
57 assert_eq!(op.operation_type, OperationType::Read);
58 assert_eq!(op.path, path);
59 assert!(!op.operation_id.is_empty());
60 let now = Utc::now();
62 let diff = now.signed_duration_since(op.timestamp);
63 assert!(diff.num_seconds() < 1);
64 }
65
66 #[test]
67 fn test_operation_description() {
68 let path = PathBuf::from("/test/file.txt");
69 let op = FileOperation::new(OperationType::Write, path);
70
71 let desc = op.description();
72 assert!(desc.contains("Write"));
73 assert!(desc.contains("/test/file.txt"));
74 }
75
76 #[test]
77 fn test_operation_serialization() {
78 let path = PathBuf::from("/test/serialize.txt");
79 let op = FileOperation::new(OperationType::List, path);
80
81 let serialized = serde_json::to_string(&op).unwrap();
82 let deserialized: FileOperation = serde_json::from_str(&serialized).unwrap();
83
84 assert_eq!(op.operation_type, deserialized.operation_type);
85 assert_eq!(op.path, deserialized.path);
86 assert_eq!(op.operation_id, deserialized.operation_id);
87 }
88}