1use clap::{Args, Parser};
2
3#[test]
4fn generic_struct_flatten() {
5    #[derive(Args, PartialEq, Debug)]
6    struct Inner {
7        pub answer: isize,
8    }
9
10    #[derive(Parser, PartialEq, Debug)]
11    struct Outer<T: Args> {
12        #[command(flatten)]
13        pub inner: T,
14    }
15
16    assert_eq!(
17        Outer {
18            inner: Inner { answer: 42 }
19        },
20        Outer::parse_from(["--answer", "42"])
21    )
22}
23
24#[test]
25fn generic_struct_flatten_w_where_clause() {
26    #[derive(Args, PartialEq, Debug)]
27    struct Inner {
28        pub answer: isize,
29    }
30
31    #[derive(Parser, PartialEq, Debug)]
32    struct Outer<T>
33    where
34        T: Args,
35    {
36        #[command(flatten)]
37        pub inner: T,
38    }
39
40    assert_eq!(
41        Outer {
42            inner: Inner { answer: 42 }
43        },
44        Outer::parse_from(["--answer", "42"])
45    )
46}
47
48#[test]
49fn generic_enum() {
50    #[derive(Args, PartialEq, Debug)]
51    struct Inner {
52        pub answer: isize,
53    }
54
55    #[derive(Parser, PartialEq, Debug)]
56    enum GenericEnum<T: Args> {
57        Start(T),
58        Stop,
59    }
60
61    assert_eq!(
62        GenericEnum::Start(Inner { answer: 42 }),
63        GenericEnum::parse_from(["test", "start", "42"])
64    )
65}
66
67#[test]
68fn generic_enum_w_where_clause() {
69    #[derive(Args, PartialEq, Debug)]
70    struct Inner {
71        pub answer: isize,
72    }
73
74    #[derive(Parser, PartialEq, Debug)]
75    enum GenericEnum<T>
76    where
77        T: Args,
78    {
79        Start(T),
80        Stop,
81    }
82
83    assert_eq!(
84        GenericEnum::Start(Inner { answer: 42 }),
85        GenericEnum::parse_from(["test", "start", "42"])
86    )
87}
88
89#[test]
90fn generic_w_fromstr_trait_bound() {
91    use std::str::FromStr;
92
93    #[derive(Parser, PartialEq, Debug)]
94    struct Opt<T>
95    where
96        T: FromStr + Send + Sync + Clone + 'static,
97        <T as FromStr>::Err: std::error::Error + Sync + Send + 'static,
98    {
99        answer: T,
100    }
101
102    assert_eq!(
103        Opt::<isize> { answer: 42 },
104        Opt::<isize>::parse_from(["--answer", "42"])
105    )
106}
107
108#[test]
109fn generic_wo_trait_bound() {
110    use std::time::Duration;
111
112    #[derive(Parser, PartialEq, Debug)]
113    struct Opt<T> {
114        answer: isize,
115        #[arg(skip)]
116        took: Option<T>,
117    }
118
119    assert_eq!(
120        Opt::<Duration> {
121            answer: 42,
122            took: None
123        },
124        Opt::<Duration>::parse_from(["--answer", "42"])
125    )
126}
127
128#[test]
129fn generic_where_clause_w_trailing_comma() {
130    use std::str::FromStr;
131
132    #[derive(Parser, PartialEq, Debug)]
133    struct Opt<T>
134    where
135        T: FromStr + Send + Sync + Clone + 'static,
136        <T as FromStr>::Err: std::error::Error + Sync + Send + 'static,
137    {
138        pub answer: T,
139    }
140
141    assert_eq!(
142        Opt::<isize> { answer: 42 },
143        Opt::<isize>::parse_from(["--answer", "42"])
144    )
145}
146