@@ -9,6 +9,37 @@ use std::collections::HashMap;
99use std:: env;
1010use std:: str:: FromStr ;
1111
12+ #[ derive( Debug ) ]
13+ pub struct ConfVal < T > {
14+ pub build : Option < T > ,
15+ pub target : Option < T > ,
16+ }
17+
18+ impl < T > ConfVal < T > {
19+ pub fn new ( build : Option < T > , target : Option < T > ) -> Self {
20+ Self { build, target }
21+ }
22+
23+ pub fn map < U , F : Fn ( T ) -> U > ( self , f : F ) -> ConfVal < U > {
24+ ConfVal {
25+ build : self . build . map ( & f) ,
26+ target : self . target . map ( & f) ,
27+ }
28+ }
29+ }
30+
31+ impl < T > Default for ConfVal < T > {
32+ fn default ( ) -> Self {
33+ Self :: new ( None , None )
34+ }
35+ }
36+
37+ impl < T : PartialEq > PartialEq < ( Option < T > , Option < T > ) > for ConfVal < T > {
38+ fn eq ( & self , other : & ( Option < T > , Option < T > ) ) -> bool {
39+ self . build == other. 0 && self . target == other. 1
40+ }
41+ }
42+
1243#[ derive( Debug ) ]
1344struct Environment ( & ' static str , Option < HashMap < & ' static str , & ' static str > > ) ;
1445
@@ -33,11 +64,11 @@ impl Environment {
3364 var : & str ,
3465 target : & Target ,
3566 convert : impl Fn ( & str ) -> T ,
36- ) -> ( Option < T > , Option < T > ) {
67+ ) -> ConfVal < T > {
3768 let build_values = self . get_build_var ( var) . map ( |ref s| convert ( s) ) ;
3869 let target_values = self . get_target_var ( target, var) . map ( |ref s| convert ( s) ) ;
3970
40- ( build_values, target_values)
71+ ConfVal :: new ( build_values, target_values)
4172 }
4273
4374 fn target_path ( target : & Target , key : & str ) -> String {
@@ -60,11 +91,11 @@ impl Environment {
6091 self . get_var ( & self . build_var_name ( & Self :: target_path ( target, key) ) )
6192 }
6293
63- fn xargo ( & self , target : & Target ) -> ( Option < bool > , Option < bool > ) {
94+ fn xargo ( & self , target : & Target ) -> ConfVal < bool > {
6495 self . get_values_for ( "XARGO" , target, bool_from_envvar)
6596 }
6697
67- fn build_std ( & self , target : & Target ) -> ( Option < BuildStd > , Option < BuildStd > ) {
98+ fn build_std ( & self , target : & Target ) -> ConfVal < BuildStd > {
6899 self . get_values_for ( "BUILD_STD" , target, |v| {
69100 if let Some ( value) = try_bool_from_envvar ( v) {
70101 BuildStd :: Bool ( value)
@@ -74,15 +105,15 @@ impl Environment {
74105 } )
75106 }
76107
77- fn zig ( & self , target : & Target ) -> ( Option < bool > , Option < bool > ) {
108+ fn zig ( & self , target : & Target ) -> ConfVal < bool > {
78109 self . get_values_for ( "ZIG" , target, bool_from_envvar)
79110 }
80111
81- fn zig_version ( & self , target : & Target ) -> ( Option < String > , Option < String > ) {
112+ fn zig_version ( & self , target : & Target ) -> ConfVal < String > {
82113 self . get_values_for ( "ZIG_VERSION" , target, ToOwned :: to_owned)
83114 }
84115
85- fn zig_image ( & self , target : & Target ) -> Result < ( Option < PossibleImage > , Option < PossibleImage > ) > {
116+ fn zig_image ( & self , target : & Target ) -> Result < ConfVal < PossibleImage > > {
86117 let get_build = |env : & Environment , var : & str | env. get_build_var ( var) ;
87118 let get_target = |env : & Environment , var : & str | env. get_target_var ( target, var) ;
88119 let env_build = get_possible_image (
@@ -100,23 +131,23 @@ impl Environment {
100131 get_target,
101132 ) ?;
102133
103- Ok ( ( env_build, env_target) )
134+ Ok ( ConfVal :: new ( env_build, env_target) )
104135 }
105136
106137 fn image ( & self , target : & Target ) -> Result < Option < PossibleImage > > {
107138 let get_target = |env : & Environment , var : & str | env. get_target_var ( target, var) ;
108139 get_possible_image ( self , "IMAGE" , "IMAGE_TOOLCHAIN" , get_target, get_target)
109140 }
110141
111- fn dockerfile ( & self , target : & Target ) -> ( Option < String > , Option < String > ) {
142+ fn dockerfile ( & self , target : & Target ) -> ConfVal < String > {
112143 self . get_values_for ( "DOCKERFILE" , target, ToOwned :: to_owned)
113144 }
114145
115- fn dockerfile_context ( & self , target : & Target ) -> ( Option < String > , Option < String > ) {
146+ fn dockerfile_context ( & self , target : & Target ) -> ConfVal < String > {
116147 self . get_values_for ( "DOCKERFILE_CONTEXT" , target, ToOwned :: to_owned)
117148 }
118149
119- fn pre_build ( & self , target : & Target ) -> ( Option < PreBuild > , Option < PreBuild > ) {
150+ fn pre_build ( & self , target : & Target ) -> ConfVal < PreBuild > {
120151 self . get_values_for ( "PRE_BUILD" , target, |v| {
121152 let v: Vec < _ > = v. split ( '\n' ) . map ( String :: from) . collect ( ) ;
122153 if v. len ( ) == 1 {
@@ -134,11 +165,11 @@ impl Environment {
134165 self . get_target_var ( target, "RUNNER" )
135166 }
136167
137- fn passthrough ( & self , target : & Target ) -> ( Option < Vec < String > > , Option < Vec < String > > ) {
168+ fn passthrough ( & self , target : & Target ) -> ConfVal < Vec < String > > {
138169 self . get_values_for ( "ENV_PASSTHROUGH" , target, split_to_cloned_by_ws)
139170 }
140171
141- fn volumes ( & self , target : & Target ) -> ( Option < Vec < String > > , Option < Vec < String > > ) {
172+ fn volumes ( & self , target : & Target ) -> ConfVal < Vec < String > > {
142173 self . get_values_for ( "ENV_VOLUMES" , target, split_to_cloned_by_ws)
143174 }
144175
@@ -209,10 +240,6 @@ pub fn try_bool_from_envvar(envvar: &str) -> Option<bool> {
209240 }
210241}
211242
212- fn map_opt_tuple < T , U , F : Fn ( T ) -> U > ( t : ( Option < T > , Option < T > ) , f : F ) -> ( Option < U > , Option < U > ) {
213- ( t. 0 . map ( & f) , t. 1 . map ( & f) )
214- }
215-
216243#[ derive( Debug ) ]
217244pub struct Config {
218245 toml : Option < CrossToml > ,
@@ -250,26 +277,26 @@ impl Config {
250277 fn get_from_value_inner < T , U > (
251278 & self ,
252279 target : & Target ,
253- env : impl for < ' a > FnOnce ( & ' a Environment , & Target ) -> ( Option < T > , Option < T > ) ,
254- config : impl for < ' a > FnOnce ( & ' a CrossToml , & Target ) -> ( Option < Cow < ' a , U > > , Option < Cow < ' a , U > > ) ,
280+ env : impl for < ' a > FnOnce ( & ' a Environment , & Target ) -> ConfVal < T > ,
281+ config : impl for < ' a > FnOnce ( & ' a CrossToml , & Target ) -> ConfVal < Cow < ' a , U > > ,
255282 ) -> Option < T >
256283 where
257284 U : ToOwned < Owned = T > + ?Sized ,
258285 {
259- let ( env_build , env_target ) = env ( & self . env , target) ;
260- let ( toml_build , toml_target ) = self
286+ let env = env ( & self . env , target) ;
287+ let toml = self
261288 . toml
262289 . as_ref ( )
263290 . map ( |toml| config ( toml, target) )
264291 . unwrap_or_default ( ) ;
265292
266- match ( env_target , toml_target ) {
293+ match ( env . target , toml . target ) {
267294 ( Some ( value) , _) => return Some ( value) ,
268295 ( None , Some ( value) ) => return Some ( value. into_owned ( ) ) ,
269296 ( None , None ) => { }
270297 }
271298
272- match ( env_build , toml_build ) {
299+ match ( env . build , toml . build ) {
273300 ( Some ( value) , _) => return Some ( value) ,
274301 ( None , Some ( value) ) => return Some ( value. into_owned ( ) ) ,
275302 ( None , None ) => { }
@@ -281,19 +308,16 @@ impl Config {
281308 fn vec_from_config (
282309 & self ,
283310 target : & Target ,
284- env : impl for < ' a > FnOnce ( & ' a Environment , & Target ) -> ( Option < Vec < String > > , Option < Vec < String > > ) ,
285- config : impl for < ' a > FnOnce (
286- & ' a CrossToml ,
287- & Target ,
288- ) -> ( Option < & ' a [ String ] > , Option < & ' a [ String ] > ) ,
311+ env : impl for < ' a > FnOnce ( & ' a Environment , & Target ) -> ConfVal < Vec < String > > ,
312+ config : impl for < ' a > FnOnce ( & ' a CrossToml , & Target ) -> ConfVal < & ' a [ String ] > ,
289313 sum : bool ,
290314 ) -> Option < Vec < String > > {
291315 if sum {
292- let ( mut env_build , env_target ) = env ( & self . env , target) ;
293- if let ( Some ( b) , Some ( mut t) ) = ( & mut env_build , env_target ) {
294- b. append ( & mut t) ;
316+ let mut env = env ( & self . env , target) ;
317+ if let ( Some ( b) , Some ( t) ) = ( & mut env . build , & mut env . target ) {
318+ b. append ( t) ;
295319 }
296- self . sum_of_env_toml_values ( env_build , |t| config ( t, target) )
320+ self . sum_of_env_toml_values ( env . build , |t| config ( t, target) )
297321 } else {
298322 self . get_from_ref ( target, env, config)
299323 }
@@ -302,28 +326,28 @@ impl Config {
302326 fn get_from_ref < T , U > (
303327 & self ,
304328 target : & Target ,
305- env : impl for < ' a > FnOnce ( & ' a Environment , & Target ) -> ( Option < T > , Option < T > ) ,
306- config : impl for < ' a > FnOnce ( & ' a CrossToml , & Target ) -> ( Option < & ' a U > , Option < & ' a U > ) ,
329+ env : impl for < ' a > FnOnce ( & ' a Environment , & Target ) -> ConfVal < T > ,
330+ config : impl for < ' a > FnOnce ( & ' a CrossToml , & Target ) -> ConfVal < & ' a U > ,
307331 ) -> Option < T >
308332 where
309333 U : ToOwned < Owned = T > + ?Sized ,
310334 {
311335 self . get_from_value_inner ( target, env, |toml, target| {
312- map_opt_tuple ( config ( toml, target) , |v| Cow :: Borrowed ( v) )
336+ config ( toml, target) . map ( |v| Cow :: Borrowed ( v) )
313337 } )
314338 }
315339
316340 fn get_from_value < T > (
317341 & self ,
318342 target : & Target ,
319- env : impl FnOnce ( & Environment , & Target ) -> ( Option < T > , Option < T > ) ,
320- config : impl FnOnce ( & CrossToml , & Target ) -> ( Option < T > , Option < T > ) ,
343+ env : impl FnOnce ( & Environment , & Target ) -> ConfVal < T > ,
344+ config : impl FnOnce ( & CrossToml , & Target ) -> ConfVal < T > ,
321345 ) -> Option < T >
322346 where
323347 T : ToOwned < Owned = T > ,
324348 {
325349 self . get_from_value_inner :: < T , T > ( target, env, |toml, target| {
326- map_opt_tuple ( config ( toml, target) , |v| Cow :: Owned ( v) )
350+ config ( toml, target) . map ( |v| Cow :: Owned ( v) )
327351 } )
328352 }
329353
@@ -357,16 +381,16 @@ impl Config {
357381 let env = self . env . image ( target) ?;
358382 Ok ( self . get_from_ref (
359383 target,
360- |_, _| ( None , env) ,
361- |toml, target| ( None , toml. image ( target) ) ,
384+ |_, _| ConfVal :: new ( None , env) ,
385+ |toml, target| ConfVal :: new ( None , toml. image ( target) ) ,
362386 ) )
363387 }
364388
365389 pub fn runner ( & self , target : & Target ) -> Option < String > {
366390 self . get_from_ref (
367391 target,
368- |env, target| ( None , env. runner ( target) ) ,
369- |toml, target| ( None , toml. runner ( target) ) ,
392+ |env, target| ConfVal :: new ( None , env. runner ( target) ) ,
393+ |toml, target| ConfVal :: new ( None , toml. runner ( target) ) ,
370394 )
371395 }
372396
@@ -435,19 +459,19 @@ impl Config {
435459 fn sum_of_env_toml_values < ' a > (
436460 & ' a self ,
437461 env_values : Option < Vec < String > > ,
438- toml_getter : impl FnOnce ( & ' a CrossToml ) -> ( Option < & ' a [ String ] > , Option < & ' a [ String ] > ) ,
462+ toml_getter : impl FnOnce ( & ' a CrossToml ) -> ConfVal < & ' a [ String ] > ,
439463 ) -> Option < Vec < String > > {
440464 let mut defined = false ;
441465 let mut collect = vec ! [ ] ;
442466 if env_values. is_some ( ) {
443467 return env_values;
444- } else if let Some ( ( build , target ) ) = self . toml . as_ref ( ) . map ( toml_getter) {
445- if let Some ( build) = build {
468+ } else if let Some ( toml ) = self . toml . as_ref ( ) . map ( toml_getter) {
469+ if let Some ( build) = toml . build {
446470 collect. extend ( build. iter ( ) . cloned ( ) ) ;
447471 defined = true ;
448472 }
449473
450- if let Some ( target) = target {
474+ if let Some ( target) = toml . target {
451475 collect. extend ( target. iter ( ) . cloned ( ) ) ;
452476 defined = true ;
453477 }
@@ -564,7 +588,7 @@ mod tests {
564588
565589 let env = Environment :: new ( Some ( map) ) ;
566590
567- let ( build, target) = env. passthrough ( & target ( ) ) ;
591+ let ConfVal { build, target } = env. passthrough ( & target ( ) ) ;
568592 assert ! ( build. as_ref( ) . unwrap( ) . contains( & "TEST1" . to_owned( ) ) ) ;
569593 assert ! ( build. as_ref( ) . unwrap( ) . contains( & "TEST2" . to_owned( ) ) ) ;
570594 assert ! ( target. as_ref( ) . unwrap( ) . contains( & "PASS1" . to_owned( ) ) ) ;
0 commit comments