coman/core/
collection_manager.rs

1//! Collection Manager - Core business logic for managing API collections
2//!
3//! This module provides a clean API for managing collections and endpoints
4//! without any CLI dependencies.
5
6use crate::core::errors::{CollectionError, CollectionResult};
7use crate::helper;
8use crate::models::collection::Collection;
9
10/// Manager for API collections
11///
12/// Provides methods for CRUD operations on collections and endpoints.
13#[derive(Clone)]
14pub struct CollectionManager {
15    file_path: Option<String>,
16}
17
18impl Default for CollectionManager {
19    fn default() -> Self {
20        Self::new(None)
21    }
22}
23
24impl CollectionManager {
25    /// Create a new CollectionManager
26    ///
27    /// # Arguments
28    ///
29    /// * `file_path` - Optional custom file path. If None, uses default location.
30    pub fn new(file_path: Option<String>) -> Self {
31        if let Some(ref path) = file_path {
32            std::env::set_var("COMAN_JSON", path);
33        }
34        Self { file_path }
35    }
36
37    /// Get the file path being used
38    pub fn get_file_path(&self) -> String {
39        self.file_path
40            .clone()
41            .unwrap_or_else(|| helper::get_file_path().to_string())
42    }
43
44    /// Load all collections from the storage file
45    pub fn load_collections(&self) -> CollectionResult<Vec<Collection>> {
46        match helper::read_json_from_file() {
47            Ok(c) => Ok(c),
48            Err(e) => {
49                if let Some(io_err) = e.downcast_ref::<std::io::Error>() {
50                    if io_err.kind() == std::io::ErrorKind::NotFound {
51                        Ok(Vec::new())
52                    } else {
53                        Err(CollectionError::Other(e.to_string()))
54                    }
55                } else {
56                    Err(CollectionError::Other(e.to_string()))
57                }
58            }
59        }
60    }
61
62    /// Save collections to the storage file
63    pub fn save_collections(&self, collections: &[Collection]) -> CollectionResult<()> {
64        let vec: Vec<Collection> = collections.to_vec();
65        helper::write_json_to_file(&vec).map_err(|e| CollectionError::Other(e.to_string()))
66    }
67}
68
69#[cfg(test)]
70mod tests {
71
72    use super::*;
73    use serial_test::serial;
74
75    fn setup_test_manager() -> CollectionManager {
76        std::env::set_var("COMAN_JSON", "test.json");
77        CollectionManager::new(Some("test.json".to_string()))
78    }
79
80    #[test]
81    #[serial]
82    fn test_load_collections() {
83        let manager = setup_test_manager();
84        let result = manager.load_collections();
85        assert!(result.is_ok());
86    }
87
88    #[test]
89    #[serial]
90    fn test_get_collection() {
91        let manager = setup_test_manager();
92        // This test assumes there's a collection in test.json
93        let result = manager.load_collections();
94        assert!(result.is_ok());
95
96        let collections = result.unwrap();
97
98        if let Some(col) = collections.first() {
99            let result = manager.get_collection(&col.name);
100            assert!(result.is_ok());
101            let fetched_col = result.unwrap();
102            assert_eq!(fetched_col.name, col.name);
103        }
104    }
105
106    #[test]
107    #[serial]
108    fn test_save_collections() {
109        let manager = setup_test_manager();
110        // This test assumes there's a collection in test.json
111        let result = manager.load_collections();
112        assert!(result.is_ok());
113
114        let result = manager.save_collections(result.unwrap().as_slice());
115        assert!(result.is_ok());
116    }
117}