dynamic_cli/plugin/builtin/
version.rs1use crate::config::schema::CommandsConfig;
11use crate::executor::CommandHandler;
12use crate::plugin::system::SystemVersionHandler;
13use crate::plugin::Plugin;
14
15pub struct VersionPlugin {
46 config: Option<CommandsConfig>,
48}
49
50impl VersionPlugin {
51 pub fn new() -> Self {
62 Self { config: None }
63 }
64
65 pub fn with_config(mut self, config: CommandsConfig) -> Self {
91 self.config = Some(config);
92 self
93 }
94}
95
96impl Default for VersionPlugin {
97 fn default() -> Self {
98 Self::new()
99 }
100}
101
102impl Plugin for VersionPlugin {
103 fn name(&self) -> &str {
104 "version"
105 }
106
107 fn version(&self) -> &str {
108 env!("CARGO_PKG_VERSION")
109 }
110
111 fn description(&self) -> &str {
112 "Standalone version command (split out of SystemPlugin, #44)"
113 }
114
115 fn handlers(&self) -> Vec<(String, Box<dyn CommandHandler>)> {
116 vec![(
117 "system_version".to_string(),
118 Box::new(SystemVersionHandler::new(self.config.clone())),
119 )]
120 }
121}
122
123#[cfg(test)]
128mod tests {
129 use super::*;
130 use crate::config::schema::{CommandsConfig, Metadata};
131 use crate::context::ExecutionContext;
132 use crate::parser::ParsedArgs;
133 use std::any::Any;
134 use std::collections::HashMap;
135
136 #[derive(Default)]
137 struct TestContext;
138
139 impl ExecutionContext for TestContext {
140 fn as_any(&self) -> &dyn Any {
141 self
142 }
143 fn as_any_mut(&mut self) -> &mut dyn Any {
144 self
145 }
146 }
147
148 fn test_config() -> CommandsConfig {
149 CommandsConfig {
150 metadata: Metadata {
151 version: "2.0.0".to_string(),
152 prompt: "testapp".to_string(),
153 prompt_suffix: " > ".to_string(),
154 },
155 commands: vec![],
156 global_options: vec![],
157 }
158 }
159
160 #[test]
161 fn test_version_plugin_metadata() {
162 let p = VersionPlugin::new();
163 assert_eq!(p.name(), "version");
164 assert!(!p.version().is_empty());
165 assert!(!p.description().is_empty());
166 }
167
168 #[test]
169 fn test_version_plugin_default() {
170 let p = VersionPlugin::default();
171 assert_eq!(p.name(), "version");
172 }
173
174 #[test]
175 fn test_version_plugin_handler_name() {
176 let handlers = VersionPlugin::new().handlers();
177 assert_eq!(handlers.len(), 1);
178 assert_eq!(handlers[0].0, "system_version");
179 }
180
181 #[test]
182 fn test_version_plugin_with_config() {
183 let plugin = VersionPlugin::new().with_config(test_config());
184 assert!(plugin.config.is_some());
185 assert_eq!(plugin.config.unwrap().metadata.version, "2.0.0");
186 }
187
188 #[test]
189 fn test_version_handler_executes_with_config() {
190 let plugin = VersionPlugin::new().with_config(test_config());
191 let handlers = plugin.handlers();
192 let (_, handler) = &handlers[0];
193 let mut ctx = TestContext;
194 assert!(handler
195 .execute(&mut ctx, &ParsedArgs::from_scalars(HashMap::new()))
196 .is_ok());
197 }
198
199 #[test]
200 fn test_version_handler_executes_without_config() {
201 let handlers = VersionPlugin::new().handlers();
202 let (_, handler) = &handlers[0];
203 let mut ctx = TestContext;
204 assert!(handler
205 .execute(&mut ctx, &ParsedArgs::from_scalars(HashMap::new()))
206 .is_ok());
207 }
208
209 #[test]
210 fn test_version_plugin_is_send_sync() {
211 fn assert_send_sync<T: Send + Sync>(_: T) {}
212 assert_send_sync(VersionPlugin::new());
213 }
214}