1use std::any::TypeId;
2use std::ffi::OsStr;
3use std::ffi::OsString;
4use std::io::Stdin;
5use std::path::PathBuf;
6
7use crate::ctx::Ctx;
8use crate::map::ErasedTy;
9use crate::opt::Action;
10use crate::opt::AnyOpt;
11use crate::opt::Cid;
12use crate::opt::Cmd;
13use crate::opt::ConfigValue;
14use crate::opt::Index;
15use crate::opt::Main;
16use crate::opt::MutOpt;
17use crate::opt::Pos;
18use crate::opt::Style;
19use crate::trace;
20use crate::typeid;
21use crate::value::ValInitializer;
22use crate::value::ValValidator;
23use crate::Error;
24
25use super::AnyValue;
26use super::RawValParser;
27use super::Stop;
28use super::ValStorer;
29
30pub trait Infer {
32 type Val: ErasedTy;
33
34 fn infer_act() -> Action {
35 Action::App
36 }
37
38 fn infer_force() -> bool {
39 false
40 }
41
42 fn infer_ctor() -> String {
43 crate::set::ctor_default_name()
44 }
45
46 fn infer_index() -> Option<Index> {
47 None
48 }
49
50 fn infer_style() -> Vec<Style> {
51 vec![Style::Argument]
52 }
53
54 fn infer_ignore_name() -> bool {
55 false
56 }
57
58 fn infer_ignore_alias() -> bool {
59 false
60 }
61
62 fn infer_ignore_index() -> bool {
63 true
64 }
65
66 fn infer_validator() -> Option<ValValidator<Self::Val>> {
67 None
68 }
69
70 fn infer_initializer() -> Option<ValInitializer> {
71 Some(ValInitializer::fallback())
72 }
73
74 fn infer_type_id() -> TypeId {
75 typeid::<Self::Val>()
76 }
77
78 fn infer_map(val: Self::Val) -> Self;
79
80 fn infer_mutable(&mut self, val: Self::Val)
81 where
82 Self: Sized,
83 {
84 *self = Self::infer_map(val);
85 }
86
87 fn infer_tweak_info<C>(_cfg: &mut C) -> Result<(), Error>
88 where
89 Self: Sized + 'static,
90 Self::Val: RawValParser,
91 C: ConfigValue + Default,
92 {
93 Ok(())
94 }
95
96 fn infer_fill_info<C>(cfg: &mut C) -> Result<(), Error>
97 where
98 Self: Sized + 'static,
99 Self::Val: RawValParser,
100 C: ConfigValue + Default,
101 {
102 let act = Self::infer_act();
103 let style = Self::infer_style();
104 let index = Self::infer_index();
105 let ignore_name = Self::infer_ignore_name();
106 let ignore_alias = Self::infer_ignore_alias();
107 let ignore_index = Self::infer_ignore_index();
108 let force = Self::infer_force();
109 let ctor = Self::infer_ctor();
110 let type_id = Self::infer_type_id();
111 let initializer = Self::infer_initializer();
112 let storer = if let Some(validator) = Self::infer_validator() {
113 Some(ValStorer::from(validator))
114 } else {
115 Some(ValStorer::fallback::<Self::Val>())
116 };
117
118 Self::infer_tweak_info(cfg)?;
119 (!cfg.has_ctor()).then(|| cfg.set_ctor(ctor));
120 (!cfg.has_index()).then(|| index.map(|idx| cfg.set_index(idx)));
121 (!cfg.has_type()).then(|| cfg.set_type_id(type_id));
122 (!cfg.has_action()).then(|| cfg.set_action(act));
123 (!cfg.has_style()).then(|| cfg.set_style(style));
124 (!cfg.has_force()).then(|| cfg.set_force(force));
125 (!cfg.has_action()).then(|| cfg.set_action(act));
126 if let Some(storer) = storer {
127 (!cfg.has_storer()).then(|| cfg.set_storer(storer));
128 }
129 if let Some(initializer) = initializer {
130 (!cfg.has_initializer()).then(|| cfg.set_initializer(initializer));
131 }
132 cfg.set_ignore_name(ignore_name);
133 cfg.set_ignore_alias(ignore_alias);
134 cfg.set_ignore_index(ignore_index);
135 Ok(())
136 }
137}
138
139impl Infer for bool {
140 type Val = bool;
141
142 fn infer_act() -> Action {
143 Action::Set
144 }
145
146 fn infer_style() -> Vec<Style> {
147 vec![Style::Combined, Style::Boolean]
148 }
149
150 fn infer_initializer() -> Option<ValInitializer> {
152 Some(ValInitializer::new_value(false))
153 }
154
155 fn infer_map(val: Self::Val) -> Self {
156 val
157 }
158}
159
160impl Infer for Cmd {
161 type Val = bool;
162
163 fn infer_act() -> Action {
164 Action::Set
165 }
166
167 fn infer_force() -> bool {
168 true
169 }
170
171 fn infer_index() -> Option<Index> {
172 Some(Index::forward(1))
173 }
174
175 fn infer_style() -> Vec<Style> {
176 vec![Style::Cmd]
177 }
178
179 fn infer_ignore_index() -> bool {
180 false
181 }
182
183 fn infer_initializer() -> Option<ValInitializer> {
184 Some(ValInitializer::new_value(false))
185 }
186
187 fn infer_type_id() -> TypeId {
188 typeid::<Self>()
189 }
190
191 fn infer_map(val: Self::Val) -> Self {
192 Cmd::new(val)
193 }
194
195 fn infer_mutable(&mut self, val: Self::Val) {
196 self.0 = val;
197 }
198}
199
200impl<T> Infer for Pos<T>
201where
202 T: Infer + ErasedTy,
203{
204 type Val = T::Val;
205
206 fn infer_type_id() -> TypeId {
207 typeid::<Self>()
208 }
209
210 fn infer_style() -> Vec<Style> {
211 vec![Style::Pos]
212 }
213
214 fn infer_ignore_name() -> bool {
215 true
216 }
217
218 fn infer_ignore_alias() -> bool {
219 true
220 }
221
222 fn infer_ignore_index() -> bool {
223 false
224 }
225
226 fn infer_map(val: Self::Val) -> Self {
227 Pos::new(<T as Infer>::infer_map(val))
228 }
229
230 fn infer_mutable(&mut self, val: Self::Val) {
231 self.0.infer_mutable(val);
232 }
233
234 fn infer_tweak_info<C>(cfg: &mut C) -> Result<(), Error>
249 where
250 Self: Sized + 'static,
251 Self::Val: RawValParser,
252 C: ConfigValue + Default,
253 {
254 if !cfg.has_storer() {
255 let type_id = std::any::TypeId::of::<T>();
256 let bool_type = std::any::TypeId::of::<bool>();
257
258 trace!(
259 "tweak the storer for Pos<bool> for {:?}?: type = {:?}",
260 cfg.name(),
261 std::any::type_name::<T>()
262 );
263 if type_id == bool_type {
265 cfg.set_storer(ValStorer::new(Box::new(
266 |raw: Option<&OsStr>, _: &Ctx, act: &Action, handler: &mut AnyValue| {
267 let val = raw.is_some();
268
269 trace!("in pos<bool> value storer, parsing {:?} -> {:?}", raw, val);
270 act.store1(Some(val), handler);
271 Ok(())
272 },
273 )));
274 }
275 }
276 Ok(())
277 }
278}
279
280impl<T> Infer for Main<T>
281where
282 T: Infer + ErasedTy,
283{
284 type Val = T::Val;
285
286 fn infer_act() -> Action {
287 Action::Null
288 }
289
290 fn infer_index() -> Option<Index> {
291 Some(Index::anywhere())
292 }
293
294 fn infer_style() -> Vec<Style> {
295 vec![Style::Main]
296 }
297
298 fn infer_ignore_name() -> bool {
299 true
300 }
301
302 fn infer_ignore_alias() -> bool {
303 true
304 }
305
306 fn infer_ignore_index() -> bool {
307 false
308 }
309
310 fn infer_type_id() -> TypeId {
311 typeid::<Self>()
312 }
313
314 fn infer_map(val: Self::Val) -> Self {
315 Main::new(<T as Infer>::infer_map(val))
316 }
317
318 fn infer_mutable(&mut self, val: Self::Val) {
319 self.0.infer_mutable(val);
320 }
321}
322
323impl<T: ErasedTy + RawValParser> Infer for MutOpt<T> {
324 type Val = T;
325
326 fn infer_map(val: Self::Val) -> Self {
327 MutOpt::new(val)
328 }
329
330 fn infer_mutable(&mut self, val: Self::Val) {
331 self.0 = val;
332 }
333}
334
335impl<T> Infer for AnyOpt<T>
336where
337 T: Infer + ErasedTy,
338{
339 type Val = T::Val;
340
341 fn infer_act() -> Action {
342 Action::Null
343 }
344
345 fn infer_style() -> Vec<Style> {
346 vec![
347 Style::Argument,
348 Style::Boolean,
349 Style::Combined,
350 Style::Pos,
351 Style::Cmd,
352 Style::Main,
353 ]
354 }
355
356 fn infer_ignore_index() -> bool {
357 false
358 }
359
360 fn infer_type_id() -> TypeId {
361 typeid::<Self>()
362 }
363
364 fn infer_map(val: Self::Val) -> Self {
365 AnyOpt::new(<T as Infer>::infer_map(val))
366 }
367
368 fn infer_mutable(&mut self, val: Self::Val) {
369 self.0.infer_mutable(val);
370 }
371}
372
373impl Infer for Stdin {
374 type Val = Stdin;
375
376 fn infer_act() -> Action {
377 Action::Set
378 }
379
380 fn infer_style() -> Vec<Style> {
381 vec![Style::Boolean]
382 }
383
384 fn infer_ignore_alias() -> bool {
385 true
386 }
387
388 fn infer_map(val: Self::Val) -> Self {
389 val
390 }
391
392 fn infer_tweak_info<C>(cfg: &mut C) -> Result<(), Error>
394 where
395 Self: Sized + 'static,
396 Self::Val: RawValParser,
397 C: ConfigValue + Default,
398 {
399 if let Some(name) = cfg.name() {
400 cfg.add_alias(name.to_string());
401 }
402 cfg.set_name("-");
403 Ok(())
404 }
405}
406
407impl Infer for Stop {
408 type Val = Stop;
409
410 fn infer_act() -> Action {
411 Action::Set
412 }
413
414 fn infer_style() -> Vec<Style> {
415 vec![Style::Boolean]
416 }
417
418 fn infer_ignore_alias() -> bool {
419 true
420 }
421
422 fn infer_map(val: Self::Val) -> Self {
423 val
424 }
425
426 fn infer_tweak_info<C>(cfg: &mut C) -> Result<(), Error>
428 where
429 Self: Sized + 'static,
430 Self::Val: RawValParser,
431 C: ConfigValue + Default,
432 {
433 if let Some(name) = cfg.name() {
434 cfg.add_alias(name.to_string());
435 }
436 cfg.set_name("--");
437 Ok(())
438 }
439}
440
441macro_rules! impl_infer_for {
442 ($name:path) => {
443 impl Infer for $name {
444 type Val = $name;
445
446 fn infer_map(val: Self::Val) -> Self {
447 val
448 }
449 }
450 };
451 (&$a:lifetime $name:path) => {
452 impl<$a> Infer for &$a $name {
453 type Val = $name;
454 }
455 };
456 (&$a:lifetime $name:path, $inner_type:path) => {
457 impl<$a> Infer for &$a $name {
458 type Val = $inner_type;
459 }
460 };
461 ($name:path, $force:literal { type Val = $val_type:ty; $( fn $fn_name:ident() -> $ret_type:ty $fn_block:block )+ }) => {
462 impl Infer for $name {
463 type Val = $val_type;
464
465 $(
466 fn $fn_name() -> $ret_type $fn_block
467 )+
468 }
469 };
470}
471
472impl_infer_for!(f64);
473impl_infer_for!(f32);
474
475impl_infer_for!(i8);
476impl_infer_for!(i16);
477impl_infer_for!(i32);
478impl_infer_for!(i64);
479
480impl_infer_for!(u8);
481impl_infer_for!(u16);
482impl_infer_for!(u32);
483impl_infer_for!(u64);
484
485impl_infer_for!(i128);
486impl_infer_for!(u128);
487
488impl_infer_for!(isize);
489impl_infer_for!(usize);
490impl_infer_for!(String);
491impl_infer_for!(PathBuf);
492impl_infer_for!(OsString);
493
494#[derive(Debug, Clone, Copy)]
495pub struct Placeholder;
496
497impl Infer for Placeholder {
498 type Val = ();
499
500 fn infer_type_id() -> TypeId {
501 typeid::<Self>()
502 }
503
504 fn infer_map(_: Self::Val) -> Self {
505 Placeholder
506 }
507
508 fn infer_mutable(&mut self, _: Self::Val) {}
509
510 fn infer_fill_info<C>(cfg: &mut C) -> Result<(), Error>
511 where
512 Self: Sized + 'static,
513 Self::Val: RawValParser,
514 C: ConfigValue + Default,
515 {
516 let ctor = cfg
518 .ctor()
519 .ok_or_else(|| crate::error!("incomplete configuration: missing `ctor`"))?;
520 let cid = Cid::from(ctor);
521
522 trace!("in default, fill info in Placeholder");
523 match cid {
524 Cid::Int => <i64>::infer_fill_info(cfg),
525 Cid::Str => <String>::infer_fill_info(cfg),
526 Cid::Flt => <f64>::infer_fill_info(cfg),
527 Cid::Uint => <u64>::infer_fill_info(cfg),
528 Cid::Bool => bool::infer_fill_info(cfg),
529 Cid::Cmd => Cmd::infer_fill_info(cfg),
530 Cid::Pos => <Pos<bool>>::infer_fill_info(cfg),
531 Cid::Main => Main::<()>::infer_fill_info(cfg),
532 Cid::Any => AnyOpt::<()>::infer_fill_info(cfg),
533 Cid::Raw => <OsString>::infer_fill_info(cfg),
534 _ => Ok(()),
535 }
536 }
537}
538
539impl Infer for () {
540 type Val = ();
541
542 fn infer_map(val: Self::Val) -> Self {
543 val
544 }
545}
546
547impl<T: Infer> Infer for Option<T> {
548 type Val = <T as Infer>::Val;
549
550 fn infer_act() -> Action {
551 <T as Infer>::infer_act()
552 }
553
554 fn infer_force() -> bool {
555 false
556 }
557
558 fn infer_ctor() -> String {
559 <T as Infer>::infer_ctor()
560 }
561
562 fn infer_index() -> Option<Index> {
563 <T as Infer>::infer_index()
564 }
565
566 fn infer_style() -> Vec<Style> {
567 <T as Infer>::infer_style()
568 }
569
570 fn infer_ignore_name() -> bool {
571 <T as Infer>::infer_ignore_name()
572 }
573
574 fn infer_ignore_alias() -> bool {
575 <T as Infer>::infer_ignore_alias()
576 }
577
578 fn infer_ignore_index() -> bool {
579 <T as Infer>::infer_ignore_index()
580 }
581
582 fn infer_validator() -> Option<ValValidator<Self::Val>> {
583 <T as Infer>::infer_validator()
584 }
585
586 fn infer_initializer() -> Option<ValInitializer> {
587 <T as Infer>::infer_initializer()
588 }
589
590 fn infer_type_id() -> TypeId {
591 <T as Infer>::infer_type_id()
592 }
593
594 fn infer_map(val: Self::Val) -> Self {
595 Some(<T as Infer>::infer_map(val))
596 }
597
598 fn infer_mutable(&mut self, val: Self::Val) {
599 if let Some(value) = self {
600 value.infer_mutable(val);
601 } else {
602 *self = Self::infer_map(val);
603 }
604 }
605
606 fn infer_tweak_info<C>(cfg: &mut C) -> Result<(), Error>
607 where
608 Self: Sized + 'static,
609 Self::Val: RawValParser,
610 C: ConfigValue + Default,
611 {
612 <T as Infer>::infer_tweak_info(cfg)
613 }
614
615 fn infer_fill_info<C>(cfg: &mut C) -> Result<(), Error>
616 where
617 Self: Sized + 'static,
618 Self::Val: RawValParser,
619 C: ConfigValue + Default,
620 {
621 <T as Infer>::infer_fill_info(cfg)
622 }
623}
624
625impl<Err, T: Infer> Infer for Result<T, Err> {
626 type Val = <T as Infer>::Val;
627
628 fn infer_act() -> Action {
629 <T as Infer>::infer_act()
630 }
631
632 fn infer_force() -> bool {
633 false
634 }
635
636 fn infer_ctor() -> String {
637 <T as Infer>::infer_ctor()
638 }
639
640 fn infer_index() -> Option<Index> {
641 <T as Infer>::infer_index()
642 }
643
644 fn infer_style() -> Vec<Style> {
645 <T as Infer>::infer_style()
646 }
647
648 fn infer_ignore_name() -> bool {
649 <T as Infer>::infer_ignore_name()
650 }
651
652 fn infer_ignore_alias() -> bool {
653 <T as Infer>::infer_ignore_alias()
654 }
655
656 fn infer_ignore_index() -> bool {
657 <T as Infer>::infer_ignore_index()
658 }
659
660 fn infer_validator() -> Option<ValValidator<Self::Val>> {
661 <T as Infer>::infer_validator()
662 }
663
664 fn infer_initializer() -> Option<ValInitializer> {
665 <T as Infer>::infer_initializer()
666 }
667
668 fn infer_type_id() -> TypeId {
669 <T as Infer>::infer_type_id()
670 }
671
672 fn infer_map(val: Self::Val) -> Self {
673 Ok(<T as Infer>::infer_map(val))
674 }
675
676 fn infer_mutable(&mut self, val: Self::Val) {
677 if let Ok(value) = self {
678 value.infer_mutable(val);
679 } else {
680 *self = Self::infer_map(val);
681 }
682 }
683
684 fn infer_tweak_info<C>(cfg: &mut C) -> Result<(), Error>
685 where
686 Self: Sized + 'static,
687 Self::Val: RawValParser,
688 C: ConfigValue + Default,
689 {
690 <T as Infer>::infer_tweak_info(cfg)
691 }
692
693 fn infer_fill_info<C>(cfg: &mut C) -> Result<(), Error>
694 where
695 Self: Sized + 'static,
696 Self::Val: RawValParser,
697 C: ConfigValue + Default,
698 {
699 <T as Infer>::infer_fill_info(cfg)
700 }
701}
702
703impl<T: Infer> Infer for Vec<T> {
704 type Val = <T as Infer>::Val;
705
706 fn infer_act() -> Action {
707 Action::App
708 }
709
710 fn infer_force() -> bool {
711 true
712 }
713
714 fn infer_ctor() -> String {
715 <T as Infer>::infer_ctor()
716 }
717
718 fn infer_index() -> Option<Index> {
719 <T as Infer>::infer_index()
720 }
721
722 fn infer_style() -> Vec<Style> {
723 <T as Infer>::infer_style()
724 }
725
726 fn infer_ignore_name() -> bool {
727 <T as Infer>::infer_ignore_name()
728 }
729
730 fn infer_ignore_alias() -> bool {
731 <T as Infer>::infer_ignore_alias()
732 }
733
734 fn infer_ignore_index() -> bool {
735 <T as Infer>::infer_ignore_index()
736 }
737
738 fn infer_validator() -> Option<ValValidator<Self::Val>> {
739 <T as Infer>::infer_validator()
740 }
741
742 fn infer_initializer() -> Option<ValInitializer> {
743 <T as Infer>::infer_initializer()
744 }
745
746 fn infer_type_id() -> TypeId {
747 <T as Infer>::infer_type_id()
748 }
749
750 fn infer_map(val: Self::Val) -> Self {
751 vec![<T as Infer>::infer_map(val)]
752 }
753
754 fn infer_mutable(&mut self, val: Self::Val) {
755 self.push(<T as Infer>::infer_map(val));
756 }
757
758 fn infer_tweak_info<C>(cfg: &mut C) -> Result<(), Error>
759 where
760 Self: Sized + 'static,
761 Self::Val: RawValParser,
762 C: ConfigValue + Default,
763 {
764 <T as Infer>::infer_tweak_info(cfg)
765 }
766
767 fn infer_fill_info<C>(cfg: &mut C) -> Result<(), Error>
768 where
769 Self: Sized + 'static,
770 Self::Val: RawValParser,
771 C: ConfigValue + Default,
772 {
773 <T as Infer>::infer_fill_info(cfg)
774 }
775}