Function tor_config::resolve_alternative_specs
source · pub fn resolve_alternative_specs<V, K>(
specified: impl IntoIterator<Item = (K, Option<V>)>,
default: impl FnOnce() -> V
) -> Result<V, ConfigBuildError>where
K: Into<String>,
V: Eq,
Expand description
Helper for resolving a config item which can be specified in multiple ways
Usable when a single configuration item can be specified via multiple (alternative) input fields; Each input field which is actually present should be converted to the common output type, and then passed to this function, which will handle consistency checks and defaulting.
A common use case is deprecated field name/types.
In that case, the deprecated field names should be added to the appropriate
load::TopLevel::DEPRECATED_KEYS
.
specified
should be an array (or other iterator) of (key, Option<value>)
where key
is the field name and
value
is that field from the builder,
converted to the common output type V
.
Example
use derive_builder::Builder;
use serde::{Deserialize, Serialize};
use tor_config::{impl_standard_builder, ConfigBuildError, Listen, resolve_alternative_specs};
#[derive(Debug, Clone, Builder, Eq, PartialEq)]
#[builder(build_fn(error = "ConfigBuildError"))]
#[builder(derive(Debug, Serialize, Deserialize))]
#[allow(clippy::option_option)]
pub struct ProxyConfig {
/// Addresses to listen on for incoming SOCKS connections.
#[builder(field(build = r#"self.resolve_socks_port()?"#))]
pub(crate) socks_listen: Listen,
/// Port to listen on (at localhost) for incoming SOCKS
/// connections.
#[builder(setter(strip_option), field(type = "Option<Option<u16>>", build = "()"))]
pub(crate) socks_port: (),
}
impl_standard_builder! { ProxyConfig }
impl ProxyConfigBuilder {
fn resolve_socks_port(&self) -> Result<Listen, ConfigBuildError> {
resolve_alternative_specs(
[
("socks_listen", self.socks_listen.clone()),
("socks_port", self.socks_port.map(Listen::new_localhost_optional)),
],
|| Listen::new_localhost(9150),
)
}
}