1use crate::{DefaultValue, ResponsePath, ResponseValue};
2
3#[derive(Debug, Clone, PartialEq)]
5pub struct Question {
6 path: ResponsePath,
8
9 ask: String,
11
12 kind: QuestionKind,
14
15 default: DefaultValue,
17}
18
19impl Question {
20 pub fn new(path: impl Into<ResponsePath>, ask: impl Into<String>, kind: QuestionKind) -> Self {
22 Self {
23 path: path.into(),
24 ask: ask.into(),
25 kind,
26 default: DefaultValue::None,
27 }
28 }
29
30 pub fn path(&self) -> &ResponsePath {
32 &self.path
33 }
34
35 pub fn ask(&self) -> &str {
37 &self.ask
38 }
39
40 pub fn kind(&self) -> &QuestionKind {
42 &self.kind
43 }
44
45 pub fn kind_mut(&mut self) -> &mut QuestionKind {
47 &mut self.kind
48 }
49
50 pub fn default(&self) -> &DefaultValue {
52 &self.default
53 }
54
55 pub fn set_suggestion(&mut self, value: impl Into<ResponseValue>) {
57 self.default = DefaultValue::Suggested(value.into());
58 }
59
60 pub fn set_assumption(&mut self, value: impl Into<ResponseValue>) {
62 self.default = DefaultValue::Assumed(value.into());
63 }
64
65 pub fn clear_default(&mut self) {
67 self.default = DefaultValue::None;
68 }
69
70 pub fn is_assumed(&self) -> bool {
72 self.default.is_assumed()
73 }
74}
75
76#[derive(Debug, Clone, PartialEq)]
78pub enum QuestionKind {
79 Unit,
81
82 Input(InputQuestion),
84
85 Multiline(MultilineQuestion),
87
88 Masked(MaskedQuestion),
90
91 Int(IntQuestion),
93
94 Float(FloatQuestion),
96
97 Confirm(ConfirmQuestion),
99
100 List(ListQuestion),
102
103 AnyOf(AnyOfQuestion),
105
106 AllOf(AllOfQuestion),
108
109 OneOf(OneOfQuestion),
111}
112
113impl QuestionKind {
114 pub fn is_unit(&self) -> bool {
116 self == &Self::Unit
117 }
118
119 pub fn is_basic(&self) -> bool {
120 matches!(
121 self,
122 Self::Input(_)
123 | Self::Multiline(_)
124 | Self::Masked(_)
125 | Self::Int(_)
126 | Self::Float(_)
127 | Self::Confirm(_)
128 | Self::List(_)
129 )
130 }
131
132 pub fn is_structural(&self) -> bool {
134 matches!(self, Self::AllOf(_) | Self::OneOf(_) | Self::AnyOf(_))
135 }
136}
137
138#[derive(Debug, Clone, PartialEq)]
140pub struct Variant {
141 pub name: String,
143
144 pub kind: QuestionKind,
150}
151
152impl Variant {
153 pub fn new(name: impl Into<String>, kind: QuestionKind) -> Self {
155 Self {
156 name: name.into(),
157 kind,
158 }
159 }
160
161 pub fn unit(name: impl Into<String>) -> Self {
163 Self::new(name, QuestionKind::Unit)
164 }
165}
166
167#[derive(Debug, Clone, PartialEq)]
169pub struct AnyOfQuestion {
170 pub variants: Vec<Variant>,
172
173 pub defaults: Vec<usize>,
175}
176
177impl AnyOfQuestion {
178 pub fn new(variants: Vec<Variant>) -> Self {
180 Self {
181 variants,
182 defaults: Vec::new(),
183 }
184 }
185
186 pub fn with_defaults(variants: Vec<Variant>, defaults: Vec<usize>) -> Self {
188 Self { variants, defaults }
189 }
190}
191
192#[derive(Debug, Clone, PartialEq)]
196pub struct AllOfQuestion {
197 pub questions: Vec<Question>,
199}
200
201impl AllOfQuestion {
202 pub fn new(questions: Vec<Question>) -> Self {
204 Self { questions }
205 }
206
207 pub fn empty() -> Self {
209 Self {
210 questions: Vec::new(),
211 }
212 }
213
214 pub fn questions(&self) -> &[Question] {
216 &self.questions
217 }
218
219 pub fn questions_mut(&mut self) -> &mut Vec<Question> {
221 &mut self.questions
222 }
223}
224
225#[derive(Debug, Clone, PartialEq)]
230pub struct OneOfQuestion {
231 pub variants: Vec<Variant>,
233
234 pub default: Option<usize>,
236}
237
238impl OneOfQuestion {
239 pub fn new(variants: Vec<Variant>) -> Self {
241 Self {
242 variants,
243 default: None,
244 }
245 }
246
247 pub fn with_default(variants: Vec<Variant>, default: usize) -> Self {
249 Self {
250 variants,
251 default: Some(default),
252 }
253 }
254
255 pub fn variants(&self) -> &[Variant] {
257 &self.variants
258 }
259
260 pub fn variants_mut(&mut self) -> &mut Vec<Variant> {
262 &mut self.variants
263 }
264}
265
266#[derive(Debug, Clone, Default, PartialEq)]
268pub struct InputQuestion {
269 pub default: Option<String>,
271
272 pub validate: Option<String>,
274}
275
276impl InputQuestion {
277 pub fn new() -> Self {
279 Self::default()
280 }
281
282 pub fn with_default(default: impl Into<String>) -> Self {
284 Self {
285 default: Some(default.into()),
286 validate: None,
287 }
288 }
289
290 pub fn with_validator(validate: Option<String>) -> Self {
292 Self {
293 default: None,
294 validate,
295 }
296 }
297}
298
299#[derive(Debug, Clone, Default, PartialEq)]
301pub struct MultilineQuestion {
302 pub default: Option<String>,
304
305 pub validate: Option<String>,
307}
308
309impl MultilineQuestion {
310 pub fn new() -> Self {
312 Self::default()
313 }
314
315 pub fn with_validator(validate: Option<String>) -> Self {
317 Self {
318 default: None,
319 validate,
320 }
321 }
322}
323
324#[derive(Debug, Clone, Default, PartialEq)]
326pub struct MaskedQuestion {
327 pub mask: Option<char>,
329
330 pub validate: Option<String>,
332}
333
334impl MaskedQuestion {
335 pub fn new() -> Self {
337 Self::default()
338 }
339
340 pub fn with_mask(mask: char) -> Self {
342 Self {
343 mask: Some(mask),
344 validate: None,
345 }
346 }
347
348 pub fn with_validator(validate: Option<String>) -> Self {
350 Self {
351 mask: None,
352 validate,
353 }
354 }
355}
356
357#[derive(Debug, Clone, Default, PartialEq)]
359pub struct IntQuestion {
360 pub default: Option<i64>,
362
363 pub min: Option<i64>,
365
366 pub max: Option<i64>,
368
369 pub validate: Option<String>,
371}
372
373impl IntQuestion {
374 pub fn new() -> Self {
376 Self::default()
377 }
378
379 pub fn with_bounds(min: Option<i64>, max: Option<i64>) -> Self {
381 Self {
382 default: None,
383 min,
384 max,
385 validate: None,
386 }
387 }
388
389 pub fn with_bounds_and_validator(
391 min: Option<i64>,
392 max: Option<i64>,
393 validate: Option<String>,
394 ) -> Self {
395 Self {
396 default: None,
397 min,
398 max,
399 validate,
400 }
401 }
402}
403
404#[derive(Debug, Clone, Default, PartialEq)]
406pub struct FloatQuestion {
407 pub default: Option<f64>,
409
410 pub min: Option<f64>,
412
413 pub max: Option<f64>,
415
416 pub validate: Option<String>,
418}
419
420impl FloatQuestion {
421 pub fn new() -> Self {
423 Self::default()
424 }
425
426 pub fn with_bounds(min: Option<f64>, max: Option<f64>) -> Self {
428 Self {
429 default: None,
430 min,
431 max,
432 validate: None,
433 }
434 }
435
436 pub fn with_bounds_and_validator(
438 min: Option<f64>,
439 max: Option<f64>,
440 validate: Option<String>,
441 ) -> Self {
442 Self {
443 default: None,
444 min,
445 max,
446 validate,
447 }
448 }
449}
450
451#[derive(Debug, Clone, Default, PartialEq)]
453pub struct ConfirmQuestion {
454 pub default: bool,
456}
457
458impl ConfirmQuestion {
459 pub fn new() -> Self {
461 Self::default()
462 }
463
464 pub fn with_default(default: bool) -> Self {
466 Self { default }
467 }
468}
469
470#[derive(Debug, Clone, PartialEq, Default)]
472pub enum ListElementKind {
473 #[default]
475 String,
476 Int { min: Option<i64>, max: Option<i64> },
478 Float { min: Option<f64>, max: Option<f64> },
480}
481
482#[derive(Debug, Clone, Default, PartialEq)]
486pub struct ListQuestion {
487 pub element_kind: ListElementKind,
489
490 pub min_items: Option<usize>,
492
493 pub max_items: Option<usize>,
495
496 pub validate: Option<String>,
498}
499
500impl ListQuestion {
501 pub fn new() -> Self {
503 Self::default()
504 }
505
506 pub fn strings() -> Self {
508 Self {
509 element_kind: ListElementKind::String,
510 ..Default::default()
511 }
512 }
513
514 pub fn ints() -> Self {
516 Self {
517 element_kind: ListElementKind::Int {
518 min: None,
519 max: None,
520 },
521 ..Default::default()
522 }
523 }
524
525 pub fn ints_with_bounds(min: Option<i64>, max: Option<i64>) -> Self {
527 Self {
528 element_kind: ListElementKind::Int { min, max },
529 ..Default::default()
530 }
531 }
532
533 pub fn floats() -> Self {
535 Self {
536 element_kind: ListElementKind::Float {
537 min: None,
538 max: None,
539 },
540 ..Default::default()
541 }
542 }
543
544 pub fn floats_with_bounds(min: Option<f64>, max: Option<f64>) -> Self {
546 Self {
547 element_kind: ListElementKind::Float { min, max },
548 ..Default::default()
549 }
550 }
551
552 pub fn with_item_bounds(mut self, min: Option<usize>, max: Option<usize>) -> Self {
554 self.min_items = min;
555 self.max_items = max;
556 self
557 }
558
559 pub fn with_validator(mut self, validate: impl Into<String>) -> Self {
561 self.validate = Some(validate.into());
562 self
563 }
564}
565
566pub const SELECTED_VARIANT_KEY: &str = "selected_variant";
569
570pub const SELECTED_VARIANTS_KEY: &str = "selected_variants";