ggen_cli_lib/cmds/
helpers.rs

1//! Shared helpers for command modules
2//!
3//! This module provides standardized helpers for common patterns across command modules:
4//! - Async execution with timeout
5//! - Logging operations
6//! - Error conversion
7//! - Duration tracking
8
9use clap_noun_verb::Result;
10use log::debug;
11use serde_json::Value;
12use std::future::Future;
13use std::time::{Duration, Instant};
14
15/// Default timeout for CLI operations
16const CLI_OP_TIMEOUT: Duration = Duration::from_secs(10);
17
18/// Default maximum tokens for AI operations
19pub const DEFAULT_MAX_TOKENS: i64 = 1024;
20
21/// Default temperature for AI operations
22pub const DEFAULT_TEMPERATURE: f64 = 0.7;
23
24/// Default search limit for marketplace operations
25pub const DEFAULT_SEARCH_LIMIT: usize = 50;
26
27/// Default search offset for marketplace operations
28pub const DEFAULT_SEARCH_OFFSET: usize = 0;
29
30/// Default registry capacity for marketplace operations
31pub const DEFAULT_REGISTRY_CAPACITY: u64 = 1000;
32
33/// Execute async operation with timeout and error handling
34///
35/// Standardized async execution pattern for CLI commands.
36/// Handles runtime creation, timeout, and error conversion.
37pub fn execute_async_op<T, Fut>(op_name: &str, fut: Fut) -> Result<T>
38where
39    Fut: Future<Output = Result<T>>,
40{
41    tokio::task::block_in_place(|| {
42        tokio::runtime::Handle::current().block_on(async {
43            match tokio::time::timeout(CLI_OP_TIMEOUT, fut).await {
44                Ok(result) => result,
45                Err(_) => Err(clap_noun_verb::NounVerbError::execution_error(format!(
46                    "Operation '{}' timed out after {}s",
47                    op_name,
48                    CLI_OP_TIMEOUT.as_secs()
49                ))),
50            }
51        })
52    })
53}
54
55/// Simplified log helper with default session/run IDs
56///
57/// Standardized logging pattern for CLI operations.
58/// Uses consistent session/run IDs for all operations.
59pub fn log_operation(location: &str, message: &str, data: Value) {
60    debug!(
61        target: "ggen::cli",
62        "location={location} message={message} payload={}",
63        data
64    );
65}
66
67/// Track operation duration
68///
69/// Returns a guard that measures duration when dropped.
70/// Use with `let _guard = track_duration("operation_name");`
71pub fn track_duration(_op_name: &str) -> DurationGuard {
72    DurationGuard {
73        start: Instant::now(),
74    }
75}
76
77/// Guard for tracking operation duration
78pub struct DurationGuard {
79    start: Instant,
80}
81
82impl DurationGuard {
83    /// Get elapsed duration
84    pub fn elapsed(&self) -> Duration {
85        self.start.elapsed()
86    }
87
88    /// Get elapsed duration in milliseconds
89    pub fn elapsed_ms(&self) -> u64 {
90        self.elapsed().as_millis() as u64
91    }
92}
93
94impl Drop for DurationGuard {
95    fn drop(&mut self) {
96        // Duration tracked automatically on drop
97    }
98}