coman/cli/
manager.rs

1//! CLI commands for managing collections and endpoints
2//!
3//! This module provides the command-line interface for managing API collections,
4//! delegating the actual work to the core CollectionManager.
5
6use clap::Subcommand;
7use std::fmt;
8
9use crate::core::collection_manager::CollectionManager;
10use crate::models::collection::Method;
11
12use super::request::RequestCommands;
13use super::request_data::RequestData;
14
15#[derive(Clone, Subcommand)]
16pub enum ManagerCommands {
17    #[clap(about = "List collections and endpoints")]
18    List {
19        #[clap(short = 'c', long = "col", default_value = "", required = false)]
20        col: String,
21
22        #[clap(short = 'e', long = "endpoint", default_value = "", required = false)]
23        endpoint: String,
24
25        #[clap(short = 'q', long = "quiet", default_value = "false")]
26        quiet: bool,
27
28        #[clap(short, long, default_value = "false")]
29        verbose: bool,
30    },
31    #[clap(about = "Update a collection or endpoint headers and body")]
32    Update {
33        collection: String,
34
35        #[clap(short = 'e', long, default_value = "", required = false)]
36        endpoint: String,
37
38        #[clap(short = 'u', long, default_value = "", required = false)]
39        url: String,
40
41        #[clap(
42            short = 'H',
43            long = "header",
44            value_parser = RequestData::parse_header,
45            value_name = "KEY:VALUE",
46            num_args = 1..,
47            required = false
48        )]
49        headers: Vec<(String, String)>,
50
51        #[clap(short = 'b', long, default_value = "", required = false)]
52        body: String,
53    },
54    #[clap(about = "Delete a collection or endpoint")]
55    Delete {
56        collection: String,
57
58        #[clap(short = 'e', long, default_value = "", required = false)]
59        endpoint: String,
60
61        #[clap(short, long, default_value = "false")]
62        yes: bool,
63    },
64    #[clap(about = "Copy a collection or endpoint")]
65    Copy {
66        collection: String,
67
68        #[clap(short = 'e', long, default_value = "", required = false)]
69        endpoint: String,
70
71        #[clap(short = 'c', long, default_value = "false", required = false)]
72        to_col: bool,
73
74        new_name: String,
75    },
76    #[clap(about = "Add a new collection")]
77    Col {
78        name: String,
79        url: String,
80
81        #[clap(
82            short = 'H',
83            long = "header",
84            value_parser = RequestData::parse_header,
85            value_name = "KEY:VALUE",
86            num_args = 1..,
87            required = false
88        )]
89        headers: Vec<(String, String)>,
90    },
91    #[clap(about = "Add a new endpoint to a collection")]
92    Endpoint {
93        collection: String,
94        name: String,
95        path: String,
96
97        #[clap(short = 'm', long, default_value = "GET")]
98        method: String,
99
100        #[clap(
101            short = 'H',
102            long = "header",
103            value_parser = RequestData::parse_header,
104            value_name = "KEY:VALUE",
105            num_args = 1..,
106            required = false
107        )]
108        headers: Vec<(String, String)>,
109
110        #[clap(short = 'b', long, default_value = "", required = false)]
111        body: String,
112    },
113}
114
115impl fmt::Display for ManagerCommands {
116    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117        match self {
118            ManagerCommands::List {
119                col,
120                endpoint,
121                quiet,
122                verbose,
123            } => write!(
124                f,
125                "List Command: col: '{}', endpoint: '{}', quiet: {}, verbose: {}",
126                col, endpoint, quiet, verbose
127            ),
128            ManagerCommands::Update {
129                collection,
130                endpoint,
131                url: _,
132                headers,
133                body,
134            } => {
135                write!(
136                    f,
137                    "Update Command: collection: '{}', endpoint: '{}', headers: {:?}, body: '{}'",
138                    collection, endpoint, headers, body
139                )
140            }
141            ManagerCommands::Delete {
142                collection,
143                endpoint,
144                yes,
145            } => {
146                write!(
147                    f,
148                    "Delete Command: collection: '{}', endpoint: '{}', yes: {}",
149                    collection, endpoint, yes
150                )
151            }
152            ManagerCommands::Copy {
153                collection,
154                endpoint,
155                to_col,
156                new_name,
157            } => {
158                write!(
159                    f,
160                    "Copy Command: collection: '{}', endpoint: '{}', To Col {}, new_name: '{}'",
161                    collection, endpoint, to_col, new_name
162                )
163            }
164            ManagerCommands::Col { name, url, headers } => {
165                write!(
166                    f,
167                    "Col Command: name: '{}', url: '{}', headers: {:?}",
168                    name, url, headers
169                )
170            }
171            ManagerCommands::Endpoint {
172                collection,
173                name,
174                path,
175                method,
176                headers,
177                body,
178            } => {
179                write!(f, "Endpoint Command: collection: '{}', name: '{}', path: '{}', method: '{}', headers: {:?}, body: '{}'",
180                    collection, name, path, method, headers, body)
181            }
182        }
183    }
184}
185
186impl ManagerCommands {
187    /// Get the default collection manager
188    pub fn get_manager() -> CollectionManager {
189        CollectionManager::default()
190    }
191
192    /// Get a RequestCommands for running an endpoint from a collection
193    pub fn get_endpoint_command(collection: &str, endpoint: &str) -> Option<RequestCommands> {
194        let manager = Self::get_manager();
195        let col = manager.get_collection(collection).ok()?;
196        let req = manager.get_endpoint(collection, endpoint).ok()?;
197
198        let data = RequestData {
199            url: format!("{}{}", col.url, req.endpoint),
200            headers: manager
201                .get_endpoint_headers(collection, endpoint)
202                .unwrap_or_default(),
203            body: req.body.clone().unwrap_or_default(),
204        };
205
206        Some(match req.method {
207            Method::Get => RequestCommands::Get { data },
208            Method::Post => RequestCommands::Post { data },
209            Method::Delete => RequestCommands::Delete { data },
210            Method::Patch => RequestCommands::Patch { data },
211            Method::Put => RequestCommands::Put { data },
212        })
213    }
214}