Skip to content

Commit 1826adb

Browse files
committed
Simplify config internals, remove duplicated code
1 parent e9f6003 commit 1826adb

File tree

1 file changed

+55
-85
lines changed

1 file changed

+55
-85
lines changed

src/config.rs

Lines changed: 55 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::docker::{ImagePlatform, PossibleImage};
44
use crate::shell::MessageInfo;
55
use crate::{CrossToml, Result, Target, TargetList};
66

7+
use std::borrow::Cow;
78
use std::collections::HashMap;
89
use std::env;
910
use std::str::FromStr;
@@ -33,9 +34,8 @@ impl Environment {
3334
target: &Target,
3435
convert: impl Fn(&str) -> T,
3536
) -> (Option<T>, Option<T>) {
36-
let target_values = self.get_target_var(target, var).map(|ref s| convert(s));
37-
3837
let build_values = self.get_build_var(var).map(|ref s| convert(s));
38+
let target_values = self.get_target_var(target, var).map(|ref s| convert(s));
3939

4040
(build_values, target_values)
4141
}
@@ -209,6 +209,10 @@ pub fn try_bool_from_envvar(envvar: &str) -> Option<bool> {
209209
}
210210
}
211211

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+
212216
#[derive(Debug)]
213217
pub struct Config {
214218
toml: Option<CrossToml>,
@@ -243,46 +247,52 @@ impl Config {
243247
Ok(())
244248
}
245249

246-
fn bool_from_config(
250+
fn get_from_value_inner<T, U>(
247251
&self,
248252
target: &Target,
249-
env: impl Fn(&Environment, &Target) -> (Option<bool>, Option<bool>),
250-
config: impl Fn(&CrossToml, &Target) -> (Option<bool>, Option<bool>),
251-
) -> Option<bool> {
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>>),
255+
) -> Option<T>
256+
where
257+
U: ToOwned<Owned = T> + ?Sized,
258+
{
252259
let (env_build, env_target) = env(&self.env, target);
253-
let (toml_build, toml_target) = if let Some(ref toml) = self.toml {
254-
config(toml, target)
255-
} else {
256-
(None, None)
257-
};
260+
let (toml_build, toml_target) = self
261+
.toml
262+
.as_ref()
263+
.map(|toml| config(toml, target))
264+
.unwrap_or_default();
258265

259266
match (env_target, toml_target) {
260267
(Some(value), _) => return Some(value),
261-
(None, Some(value)) => return Some(value),
268+
(None, Some(value)) => return Some(value.into_owned()),
262269
(None, None) => {}
263-
};
270+
}
264271

265272
match (env_build, toml_build) {
266273
(Some(value), _) => return Some(value),
267-
(None, Some(value)) => return Some(value),
274+
(None, Some(value)) => return Some(value.into_owned()),
268275
(None, None) => {}
269-
};
276+
}
270277

271278
None
272279
}
273280

274281
fn vec_from_config(
275282
&self,
276283
target: &Target,
277-
env: impl for<'a> Fn(&'a Environment, &Target) -> (Option<Vec<String>>, Option<Vec<String>>),
278-
config: impl for<'a> Fn(&'a CrossToml, &Target) -> (Option<&'a [String]>, Option<&'a [String]>),
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]>),
279289
sum: bool,
280290
) -> Option<Vec<String>> {
281291
if sum {
282292
let (mut env_build, env_target) = env(&self.env, target);
283-
env_build
284-
.as_mut()
285-
.map(|b| env_target.map(|mut t| b.append(&mut t)));
293+
if let (Some(b), Some(mut t)) = (&mut env_build, env_target) {
294+
b.append(&mut t);
295+
}
286296
self.sum_of_env_toml_values(env_build, |t| config(t, target))
287297
} else {
288298
self.get_from_ref(target, env, config)
@@ -292,64 +302,29 @@ impl Config {
292302
fn get_from_ref<T, U>(
293303
&self,
294304
target: &Target,
295-
env: impl for<'a> Fn(&'a Environment, &Target) -> (Option<T>, Option<T>),
296-
config: impl for<'a> Fn(&'a CrossToml, &Target) -> (Option<&'a U>, Option<&'a U>),
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>),
297307
) -> Option<T>
298308
where
299309
U: ToOwned<Owned = T> + ?Sized,
300310
{
301-
let (env_build, env_target) = env(&self.env, target);
302-
303-
if let Some(env_target) = env_target {
304-
return Some(env_target);
305-
}
306-
307-
let (build, target) = self
308-
.toml
309-
.as_ref()
310-
.map(|t| config(t, target))
311-
.unwrap_or_default();
312-
313-
// FIXME: let expression
314-
if target.is_none() && env_build.is_some() {
315-
return env_build;
316-
}
317-
318-
if target.is_none() {
319-
build.map(ToOwned::to_owned)
320-
} else {
321-
target.map(ToOwned::to_owned)
322-
}
311+
self.get_from_value_inner(target, env, |toml, target| {
312+
map_opt_tuple(config(toml, target), |v| Cow::Borrowed(v))
313+
})
323314
}
324315

325316
fn get_from_value<T>(
326317
&self,
327318
target: &Target,
328-
env: impl Fn(&Environment, &Target) -> (Option<T>, Option<T>),
329-
config: impl Fn(&CrossToml, &Target) -> (Option<T>, Option<T>),
330-
) -> Option<T> {
331-
let (env_build, env_target) = env(&self.env, target);
332-
333-
if let Some(env_target) = env_target {
334-
return Some(env_target);
335-
}
336-
337-
let (build, target) = self
338-
.toml
339-
.as_ref()
340-
.map(|t| config(t, target))
341-
.unwrap_or_default();
342-
343-
// FIXME: let expression
344-
if target.is_none() && env_build.is_some() {
345-
return env_build;
346-
}
347-
348-
if target.is_none() {
349-
build
350-
} else {
351-
target
352-
}
319+
env: impl FnOnce(&Environment, &Target) -> (Option<T>, Option<T>),
320+
config: impl FnOnce(&CrossToml, &Target) -> (Option<T>, Option<T>),
321+
) -> Option<T>
322+
where
323+
T: ToOwned<Owned = T>,
324+
{
325+
self.get_from_value_inner::<T, T>(target, env, |toml, target| {
326+
map_opt_tuple(config(toml, target), |v| Cow::Owned(v))
327+
})
353328
}
354329

355330
#[cfg(test)]
@@ -358,31 +333,31 @@ impl Config {
358333
}
359334

360335
pub fn xargo(&self, target: &Target) -> Option<bool> {
361-
self.bool_from_config(target, Environment::xargo, CrossToml::xargo)
336+
self.get_from_value(target, Environment::xargo, CrossToml::xargo)
362337
}
363338

364339
pub fn build_std(&self, target: &Target) -> Option<BuildStd> {
365340
self.get_from_ref(target, Environment::build_std, CrossToml::build_std)
366341
}
367342

368343
pub fn zig(&self, target: &Target) -> Option<bool> {
369-
self.bool_from_config(target, Environment::zig, CrossToml::zig)
344+
self.get_from_value(target, Environment::zig, CrossToml::zig)
370345
}
371346

372347
pub fn zig_version(&self, target: &Target) -> Option<String> {
373348
self.get_from_value(target, Environment::zig_version, CrossToml::zig_version)
374349
}
375350

376351
pub fn zig_image(&self, target: &Target) -> Result<Option<PossibleImage>> {
377-
let (b, t) = self.env.zig_image(target)?;
378-
Ok(self.get_from_value(target, |_, _| (b.clone(), t.clone()), CrossToml::zig_image))
352+
let env = self.env.zig_image(target)?;
353+
Ok(self.get_from_value(target, |_, _| env, CrossToml::zig_image))
379354
}
380355

381356
pub fn image(&self, target: &Target) -> Result<Option<PossibleImage>> {
382357
let env = self.env.image(target)?;
383358
Ok(self.get_from_ref(
384359
target,
385-
move |_, _| (None, env.clone()),
360+
|_, _| (None, env),
386361
|toml, target| (None, toml.image(target)),
387362
))
388363
}
@@ -459,29 +434,26 @@ impl Config {
459434
// FIXME: remove when we disable sums in 0.3.0.
460435
fn sum_of_env_toml_values<'a>(
461436
&'a self,
462-
env_values: Option<impl AsRef<[String]>>,
437+
env_values: Option<Vec<String>>,
463438
toml_getter: impl FnOnce(&'a CrossToml) -> (Option<&'a [String]>, Option<&'a [String]>),
464439
) -> Option<Vec<String>> {
465440
let mut defined = false;
466441
let mut collect = vec![];
467-
if let Some(vars) = env_values {
468-
collect.extend(vars.as_ref().iter().cloned());
469-
defined = true;
442+
if env_values.is_some() {
443+
return env_values;
470444
} else if let Some((build, target)) = self.toml.as_ref().map(toml_getter) {
471445
if let Some(build) = build {
472446
collect.extend(build.iter().cloned());
473447
defined = true;
474448
}
449+
475450
if let Some(target) = target {
476451
collect.extend(target.iter().cloned());
477452
defined = true;
478453
}
479454
}
480-
if !defined {
481-
None
482-
} else {
483-
Some(collect)
484-
}
455+
456+
defined.then_some(collect)
485457
}
486458
}
487459

@@ -527,7 +499,6 @@ mod tests {
527499
}
528500

529501
mod test_environment {
530-
531502
use super::*;
532503

533504
#[test]
@@ -603,7 +574,6 @@ mod tests {
603574

604575
#[cfg(test)]
605576
mod test_config {
606-
607577
use super::*;
608578

609579
macro_rules! s {

0 commit comments

Comments
 (0)