use cosh_tools::question::Question;
use cosh_tools::question::types::{QuestionInput, QuestionType};
fn ask(label: &str, result: Result<cosh_tools::question::types::QuestionOutput, String>) {
println!("== {label} ==");
match result {
Ok(out) => {
println!(
" accepted {} question(s), answers: {}",
out.questions.len(),
out.answers.len()
);
for q in &out.questions {
println!(
" - [{}] {} ({})",
q.id,
q.question,
serde_json::to_string(&q.question_type).unwrap()
);
if let Some(p) = &q.purpose {
println!(" purpose: {p}");
}
println!(" required: {}", q.required);
if let Some(rec) = &q.recommended {
println!(" recommended: {rec}");
}
}
}
Err(e) => println!(" rejected: {e}"),
}
println!();
}
fn main() {
let question = Question::new();
println!("== 1. ask_questions schema ==");
println!(
" name: {}, requires: {:?}\n",
question.description_ask["name"].as_str().unwrap(),
question.description_ask["inputSchema"]["required"]
);
let canonical: QuestionInput = serde_json::from_value(serde_json::json!({
"questions": [
{
"question": "Which authentication method should we use?",
"header": "Auth method",
"multiSelect": false,
"options": [
{"label": "OAuth 2.0 (Recommended)", "description": "Industry standard, supports multiple providers"},
{"label": "API key", "description": "Stateless, good for simple server-to-server calls"}
]
},
{
"question": "What should the project be called?",
"header": "Name",
"purpose": "To name the crate"
}
]
}))
.expect("canonical shape must decode");
ask("2. canonical market shape", question.ask(&canonical));
let out = question.ask(&canonical).unwrap();
println!("== 3. serialized output ==");
println!("{}", serde_json::to_string_pretty(&out).unwrap());
println!();
let string_options: QuestionInput = serde_json::from_value(serde_json::json!({
"questions": [{
"question": "Pick one?",
"options": "[\"A\", \"B\"]"
}]
}))
.expect("string-encoded options must decode");
ask("4a. string-encoded options", question.ask(&string_options));
let bare_strings: QuestionInput = serde_json::from_value(serde_json::json!({
"questions": [{
"question": "Which features?",
"multiple": true,
"options": ["Lint", "Format"]
}]
}))
.expect("bare-string options with the `multiple` alias must decode");
ask(
"4b. bare-string options + `multiple` alias",
question.ask(&bare_strings),
);
let header_only: QuestionInput = serde_json::from_value(serde_json::json!({
"questions": [{"header": "Pick mode"}]
}))
.expect("header-only item must decode");
ask("4c. header-only item", question.ask(&header_only));
ask(
"5a. no questions",
question.ask(&QuestionInput { questions: vec![] }),
);
ask(
"5b. choice question without options",
question.ask(
&serde_json::from_value::<QuestionInput>(serde_json::json!({
"questions": [{"question": "Pick some?", "multiSelect": true}]
}))
.unwrap(),
),
);
ask(
"5c. option colliding with the reserved custom-answer label",
question.ask(
&serde_json::from_value::<QuestionInput>(serde_json::json!({
"questions": [{
"question": "Pick one?",
"options": [
{"label": "Personalize your response"},
{"label": "B"}
]
}]
}))
.unwrap(),
),
);
let _ = QuestionType::Text; }