From 6af1485a9053e9522c4430fb52497c92a75bcb78 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Mon, 7 Aug 2023 17:41:51 +0100 Subject: [PATCH] tor-config: Add ConfigurationSources::try_from_cmdline We'll use this in crates/arti in a moment. --- Cargo.lock | 1 + crates/tor-config/Cargo.toml | 1 + crates/tor-config/semver.md | 1 + crates/tor-config/src/sources.rs | 59 +++++++++++++++++++++++--------- 4 files changed, 46 insertions(+), 16 deletions(-) create mode 100644 crates/tor-config/semver.md diff --git a/Cargo.lock b/Cargo.lock index a628010d4..3fd5ac300 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4405,6 +4405,7 @@ dependencies = [ "tor-error", "tracing", "tracing-test", + "void", ] [[package]] diff --git a/crates/tor-config/Cargo.toml b/crates/tor-config/Cargo.toml index f66302dea..becd40e01 100644 --- a/crates/tor-config/Cargo.toml +++ b/crates/tor-config/Cargo.toml @@ -46,6 +46,7 @@ toml = "0.7.2" tor-basic-utils = { path = "../tor-basic-utils", version = "0.7.3" } tor-error = { path = "../tor-error", version = "0.5.3" } tracing = "0.1.36" +void = "1" [dev-dependencies] config = { version = "0.13", default-features = false, features = ["toml"] } diff --git a/crates/tor-config/semver.md b/crates/tor-config/semver.md new file mode 100644 index 000000000..e728df671 --- /dev/null +++ b/crates/tor-config/semver.md @@ -0,0 +1 @@ +ADDED: ConfigurationSources::try_from_cmdline() diff --git a/crates/tor-config/src/sources.rs b/crates/tor-config/src/sources.rs index e2326679f..e3ef2a549 100644 --- a/crates/tor-config/src/sources.rs +++ b/crates/tor-config/src/sources.rs @@ -25,6 +25,8 @@ use std::ffi::OsString; use std::{fs, io}; +use void::ResultVoidExt as _; + use crate::err::ConfigError; use crate::CmdLine; @@ -146,21 +148,9 @@ impl ConfigurationSources { Self::default() } - /// Establish a [`ConfigurationSources`] the usual way from a command line and defaults + /// Establish a [`ConfigurationSources`] the from an infallible command line and defaults /// - /// The caller should have parsed the program's command line, and extracted (inter alia) - /// - /// * `config_files_options`: Paths of config file(s) (or directories of `.toml` files) - /// * `cmdline_toml_override_options`: Overrides ("key=value") - /// - /// The caller should also provide `default_config_files`, the default locations of the - /// configuration files. This is used if no file(s) are specified on the command line. - /// - /// `mistrust` is used to check whether the configuration files have appropriate permissions. - /// - /// `ConfigurationSource::Dir`s - /// will be scanned for files whose name ends in `.toml`. - /// All those files (if any) will be read (in lexical order by filename). + /// Convenience method for if the default config file location(s) can be infallibly computed. pub fn from_cmdline( default_config_files: impl IntoIterator, config_files_options: impl IntoIterator, @@ -169,6 +159,43 @@ impl ConfigurationSources { where F: Into, O: Into, + { + ConfigurationSources::try_from_cmdline( + || Ok(default_config_files), + config_files_options, + cmdline_toml_override_options, + ) + .void_unwrap() + } + + /// Establish a [`ConfigurationSources`] the usual way from a command line and defaults + /// + /// The caller should have parsed the program's command line, and extracted (inter alia) + /// + /// * `config_files_options`: Paths of config file(s) (or directories of `.toml` files) + /// * `cmdline_toml_override_options`: Overrides ("key=value") + /// + /// The caller should also provide `default_config_files`, + /// which returns the default locations of the configuration files. + /// This used if no file(s) are specified on the command line. + // + // The other inputs are always used and therefore + // don't need to be lifted into FnOnce() -> Result. + /// + /// `mistrust` is used to check whether the configuration files have appropriate permissions. + /// + /// `ConfigurationSource::Dir`s + /// will be scanned for files whose name ends in `.toml`. + /// All those files (if any) will be read (in lexical order by filename). + pub fn try_from_cmdline( + default_config_files: impl FnOnce() -> Result, + config_files_options: impl IntoIterator, + cmdline_toml_override_options: impl IntoIterator, + ) -> Result + where + F: Into, + O: Into, + DEF: IntoIterator, { let mut cfg_sources = ConfigurationSources::new_empty(); @@ -179,7 +206,7 @@ impl ConfigurationSources { any_files = true; } if !any_files { - for default in default_config_files { + for default in default_config_files()? { cfg_sources.push_source(default, MustRead::TolerateAbsence); } } @@ -188,7 +215,7 @@ impl ConfigurationSources { cfg_sources.push_option(s); } - cfg_sources + Ok(cfg_sources) } /// Add `src` to the list of files or directories that we want to read configuration from.