timeout_completion_demo/
timeout_completion_demo.rs

1//! Demonstrates timeout handling for slow completion operations
2//!
3//! This example shows how to use completion timeouts to ensure
4//! that slow operations don't hang the shell completion experience.
5
6#![allow(clippy::or_fun_call)]
7
8use flag_rs::completion_timeout::{DEFAULT_COMPLETION_TIMEOUT, make_timeout_completion};
9use flag_rs::{CommandBuilder, CompletionResult, Flag, FlagType};
10use std::thread;
11use std::time::Duration;
12
13/// Simulates a slow API call or database query
14fn slow_completion(prefix: &str, delay_ms: u64) -> Vec<String> {
15    thread::sleep(Duration::from_millis(delay_ms));
16
17    vec![
18        "slow-result-1",
19        "slow-result-2",
20        "slow-result-3",
21        "slow-match-1",
22        "slow-match-2",
23    ]
24    .into_iter()
25    .filter(|item| item.starts_with(prefix))
26    .map(String::from)
27    .collect()
28}
29
30fn main() {
31    let app = CommandBuilder::new("cloud-cli")
32        .short("Cloud CLI with timeout-protected completions")
33        .flag(
34            Flag::new("region")
35                .short('r')
36                .usage("Cloud region")
37                .value_type(FlagType::String)
38                .default(flag_rs::FlagValue::String("us-east-1".to_string())),
39        )
40        .subcommand(
41            CommandBuilder::new("instances")
42                .short("Manage cloud instances")
43                .subcommand(
44                    CommandBuilder::new("list")
45                        .short("List instances (fast completion)")
46                        .arg_completion(|_ctx, prefix| {
47                            // Fast completion - no timeout needed
48                            let instances = vec![
49                                "web-server-001",
50                                "web-server-002",
51                                "db-primary",
52                                "db-replica",
53                                "cache-node-1",
54                                "cache-node-2",
55                            ];
56
57                            Ok(CompletionResult::new().extend(
58                                instances
59                                    .into_iter()
60                                    .filter(|i| i.starts_with(prefix))
61                                    .map(String::from),
62                            ))
63                        })
64                        .build(),
65                )
66                .subcommand(
67                    CommandBuilder::new("describe")
68                        .short("Describe instance (slow completion with timeout)")
69                        .arg_completion({
70                            // Wrap slow completion with timeout
71                            make_timeout_completion(
72                                Duration::from_millis(500), // 500ms timeout
73                                |ctx, prefix| {
74                                    eprintln!("Fetching instance details from API...");
75
76                                    // Simulate slow API call (1 second)
77                                    let instances = slow_completion(prefix, 1000);
78
79                                    let mut result = CompletionResult::new();
80                                    for instance in instances {
81                                        result = result.add_with_description(
82                                            instance.clone(),
83                                            format!(
84                                                "Instance in region {}",
85                                                ctx.flag("region")
86                                                    .unwrap_or(&"us-east-1".to_string())
87                                            ),
88                                        );
89                                    }
90
91                                    if prefix.is_empty() {
92                                        result = result.add_help_text(
93                                            "Fetching live instance data from cloud API...",
94                                        );
95                                    }
96
97                                    Ok(result)
98                                },
99                            )
100                        })
101                        .build(),
102                )
103                .subcommand(
104                    CommandBuilder::new("create")
105                        .short("Create instance (very slow completion)")
106                        .arg_completion({
107                            // Use default timeout (2 seconds)
108                            make_timeout_completion(DEFAULT_COMPLETION_TIMEOUT, |_ctx, prefix| {
109                                eprintln!("Checking available instance types...");
110
111                                // Simulate very slow operation (3 seconds)
112                                let types = slow_completion(prefix, 3000);
113
114                                Ok(CompletionResult::new()
115                                    .extend(types)
116                                    .add_help_text("Available instance types"))
117                            })
118                        })
119                        .build(),
120                )
121                .build(),
122        )
123        .build();
124
125    println!("=== Timeout Completion Demo ===\n");
126    println!("This demo shows how timeouts protect against slow completion operations.\n");
127    println!("To test timeout handling:");
128    println!("1. Set up bash completion:");
129    println!(
130        "   source <({} completion bash)",
131        std::env::args().next().unwrap_or_default()
132    );
133    println!();
134    println!("2. Test different completion speeds:");
135    println!();
136    println!("   Fast (no timeout needed):");
137    println!(
138        "   {} instances list <TAB>",
139        std::env::args().next().unwrap_or_default()
140    );
141    println!();
142    println!("   Slow (500ms timeout, 1s operation - will timeout):");
143    println!(
144        "   {} instances describe <TAB>",
145        std::env::args().next().unwrap_or_default()
146    );
147    println!();
148    println!("   Very slow (2s timeout, 3s operation - will timeout):");
149    println!(
150        "   {} instances create <TAB>",
151        std::env::args().next().unwrap_or_default()
152    );
153    println!();
154    println!("When a timeout occurs, you'll see:");
155    println!("- A warning message about the timeout");
156    println!("- Any partial results that were available");
157    println!("- Suggestion to use a more specific prefix");
158    println!("\n---\n");
159
160    let args: Vec<String> = std::env::args().skip(1).collect();
161    if let Err(e) = app.execute(args) {
162        eprintln!("{}", e);
163        std::process::exit(1);
164    }
165}