| 128 | } |
| 129 | |
| 130 | fn ask_question(q: &QuestionDef) -> Result<Vec<String>, ToolError> { |
| 131 | println!(); |
| 132 | |
| 133 | if let Some(ref header) = q.header { |
| 134 | println!("┌─ {} ─────────────────", header); |
| 135 | } else { |
| 136 | println!("┌─ Question ─────────────────"); |
| 137 | } |
| 138 | println!("│"); |
| 139 | println!("│ {}", q.question); |
| 140 | println!("│"); |
| 141 | |
| 142 | if q.options.is_empty() { |
| 143 | println!("└─ Type your answer: "); |
| 144 | print!("> "); |
| 145 | io::stdout() |
| 146 | .flush() |
| 147 | .map_err(|e| ToolError::ExecutionError(e.to_string()))?; |
| 148 | |
| 149 | let stdin = io::stdin(); |
| 150 | let mut answer = String::new(); |
| 151 | stdin |
| 152 | .lock() |
| 153 | .read_line(&mut answer) |
| 154 | .map_err(|e| ToolError::ExecutionError(e.to_string()))?; |
| 155 | |
| 156 | return Ok(vec![answer.trim().to_string()]); |
| 157 | } |
| 158 | |
| 159 | println!("│ Options:"); |
| 160 | for (i, opt) in q.options.iter().enumerate() { |
| 161 | let num = i + 1; |
| 162 | if let Some(ref desc) = opt.description { |
| 163 | println!("│ {}. {} - {}", num, opt.label, desc); |
| 164 | } else { |
| 165 | println!("│ {}. {}", num, opt.label); |
| 166 | } |
| 167 | } |
| 168 | println!("│"); |
| 169 | |
| 170 | if q.multiple { |
| 171 | println!("└─ Enter choices (comma-separated, e.g., 1,3): "); |
| 172 | } else { |
| 173 | println!("└─ Enter your choice: "); |
| 174 | } |
| 175 | |
| 176 | print!("> "); |
| 177 | io::stdout() |
| 178 | .flush() |
| 179 | .map_err(|e| ToolError::ExecutionError(e.to_string()))?; |
| 180 | |
| 181 | let stdin = io::stdin(); |
| 182 | let mut input = String::new(); |
| 183 | stdin |
| 184 | .lock() |
| 185 | .read_line(&mut input) |
| 186 | .map_err(|e| ToolError::ExecutionError(e.to_string()))?; |
| 187 | |