11use clap:: { Args , Parser , Subcommand } ;
2+ use functor_derive:: Functor ;
23use functora_cfg:: * ;
34use serde:: { Deserialize , Serialize } ;
45use serial_test:: serial;
@@ -18,16 +19,13 @@ struct Cfg {
1819}
1920
2021impl Cfg {
21- pub fn new (
22- cli : & Cli < IdClap < HashMap < String , Account > > > ,
23- ) -> Self {
22+ pub fn new ( cli : Cli < SubAccounts > ) -> Self {
2423 functora_cfg:: Cfg {
2524 default : & Cli :: def ( ) ,
26- file_path : |cli : & Cli <
27- IdClap < HashMap < String , Account > > ,
28- > | cli. toml . as_deref ( ) ,
25+ file_path : |cli| cli. toml . as_deref ( ) ,
2926 env_prefix : "FUNCTORA" ,
30- command_line : cli,
27+ command_line : & cli
28+ . fmap ( |x| IdClap ( x. hash_map ( ) ) ) ,
3129 }
3230 . eval ( )
3331 . unwrap ( )
@@ -45,7 +43,7 @@ impl Cfg {
4543 Deserialize ,
4644 Args ,
4745) ]
48- struct Account {
46+ pub struct Account {
4947 #[ arg( long) ]
5048 alias : String ,
5149 #[ arg( long) ]
@@ -54,11 +52,40 @@ struct Account {
5452 tags : Option < Vec < String > > ,
5553}
5654
55+ #[ derive(
56+ Eq ,
57+ PartialEq ,
58+ Ord ,
59+ PartialOrd ,
60+ Debug ,
61+ Clone ,
62+ Serialize ,
63+ Deserialize ,
64+ Subcommand ,
65+ ) ]
66+ #[ command( subcommand_precedence_over_arg = true ) ]
67+ pub enum SubAccounts {
68+ SubAccounts ( ReClap < Account , Self > ) ,
69+ }
70+
71+ impl SubAccounts {
72+ pub fn vec ( self ) -> Vec < Account > {
73+ let SubAccounts :: SubAccounts ( prev) = self ;
74+ prev. vec ( |SubAccounts :: SubAccounts ( next) | next)
75+ }
76+
77+ pub fn hash_map ( self ) -> HashMap < String , Account > {
78+ let SubAccounts :: SubAccounts ( prev) = self ;
79+ prev. hash_map ( |SubAccounts :: SubAccounts ( next) | next)
80+ }
81+ }
82+
5783#[ derive(
5884 Eq ,
5985 PartialEq ,
6086 Debug ,
6187 Clone ,
88+ Functor ,
6289 Serialize ,
6390 Deserialize ,
6491 Parser ,
84111 #[ command( flatten) ]
85112 main_account : Option < Account > ,
86113 #[ command( subcommand) ]
87- sub_accounts : T ,
114+ sub_accounts : Option < T > ,
88115}
89116
90117impl Cli < IdClap < HashMap < String , Account > > > {
@@ -99,22 +126,27 @@ impl Cli<IdClap<HashMap<String, Account>>> {
99126 balance : 42 ,
100127 tags : None ,
101128 } ) ,
102- sub_accounts : IdClap ( HashMap :: new ( ) ) ,
129+ sub_accounts : Some ( IdClap ( HashMap :: new ( ) ) ) ,
103130 }
104131 }
105132}
106133
107134#[ test]
108135#[ serial]
109136fn defaults_only ( ) {
110- let lhs = Cfg :: new ( & Cli {
111- toml : None ,
112- host : None ,
113- port : None ,
114- logs : None ,
115- main_account : None ,
116- sub_accounts : IdClap ( HashMap :: new ( ) ) ,
117- } ) ;
137+ let cli = Cli :: parse_from ( [ "test" ] ) ;
138+ let lhs = Cfg :: new ( cli) ;
139+ // let lhs = Cfg::new(Cli {
140+ // toml: None,
141+ // host: None,
142+ // port: None,
143+ // logs: None,
144+ // main_account: None,
145+ // sub_accounts: SubAccounts::SubAccounts(ReClap {
146+ // prev: None,
147+ // next: None,
148+ // }),
149+ // });
118150 let rhs = Cfg {
119151 host : "127.0.0.1" . into ( ) ,
120152 port : 8080 ,
@@ -150,9 +182,9 @@ fn with_file_override() {
150182 port : None ,
151183 logs : None ,
152184 main_account : None ,
153- sub_accounts : IdClap ( HashMap :: new ( ) ) ,
185+ sub_accounts : None ,
154186 } ;
155- let cfg: Cfg = Cfg :: new ( & cli) ;
187+ let cfg: Cfg = Cfg :: new ( cli) ;
156188 assert_eq ! ( cfg. host, "192.168.1.100" ) ;
157189 assert_eq ! ( cfg. port, 9090 ) ;
158190 assert_eq ! ( cfg. logs, true ) ;
@@ -178,7 +210,7 @@ fn env_override() {
178210 port : None ,
179211 logs : None ,
180212 main_account : None ,
181- sub_accounts : IdClap ( HashMap :: new ( ) ) ,
213+ sub_accounts : None ,
182214 } ;
183215 with_vars (
184216 vec ! [
@@ -196,7 +228,7 @@ fn env_override() {
196228 ) ,
197229 ] ,
198230 || {
199- let cfg: Cfg = Cfg :: new ( & cli) ;
231+ let cfg: Cfg = Cfg :: new ( cli) ;
200232 assert_eq ! ( cfg. host, "10.0.0.1" ) ;
201233 assert_eq ! ( cfg. port, 7070 ) ;
202234 assert_eq ! ( cfg. logs, true ) ;
@@ -232,9 +264,9 @@ fn cli_override() {
232264 port : Some ( 6060 ) ,
233265 logs : Some ( true ) ,
234266 main_account : None ,
235- sub_accounts : IdClap ( HashMap :: new ( ) ) ,
267+ sub_accounts : None ,
236268 } ;
237- let cfg: Cfg = Cfg :: new ( & cli) ;
269+ let cfg: Cfg = Cfg :: new ( cli) ;
238270 assert_eq ! ( cfg. host, "cli.host" ) ;
239271 assert_eq ! ( cfg. port, 6060 ) ;
240272 assert_eq ! ( cfg. logs, true ) ;
@@ -249,9 +281,9 @@ fn nested_struct() {
249281 port : None ,
250282 logs : None ,
251283 main_account : None ,
252- sub_accounts : IdClap ( HashMap :: new ( ) ) ,
284+ sub_accounts : None ,
253285 } ;
254- let cfg: Cfg = Cfg :: new ( & cli) ;
286+ let cfg: Cfg = Cfg :: new ( cli) ;
255287 assert_eq ! ( cfg. main_account. alias, "foo" ) ;
256288 assert_eq ! ( cfg. main_account. balance, 42 ) ;
257289}
0 commit comments