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),
        )
    }
}