Commit ed1f5abe authored by Nick Mathewson's avatar Nick Mathewson 🦞
Browse files

Merge branch 'config-sub-list' into 'main'

Introduce macro for ThingListBuilder, and use for AuthorityListBuilder

See merge request !471
parents c529d6cd e81d2157
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -3342,6 +3342,7 @@ dependencies = [
 "serde",
 "serde",
 "shellexpand-fork",
 "shellexpand-fork",
 "thiserror",
 "thiserror",
 "tor-basic-utils",
 "tor-error",
 "tor-error",
 "tracing",
 "tracing",
 "tracing-test",
 "tracing-test",
+3 −6
Original line number Original line Diff line number Diff line
@@ -390,8 +390,7 @@ mod test {
        let auth = dir::Authority::builder()
        let auth = dir::Authority::builder()
            .name("Fred")
            .name("Fred")
            .v3ident([22; 20].into())
            .v3ident([22; 20].into())
            .build()
            .clone();
            .unwrap();
        let fallback = dir::FallbackDir::builder()
        let fallback = dir::FallbackDir::builder()
            .rsa_identity([23; 20].into())
            .rsa_identity([23; 20].into())
            .ed_identity([99; 32].into())
            .ed_identity([99; 32].into())
@@ -399,10 +398,8 @@ mod test {
            .clone();
            .clone();


        let mut bld = TorClientConfig::builder();
        let mut bld = TorClientConfig::builder();
        bld.tor_network()
        bld.tor_network().authorities().replace(vec![auth]);
            .authorities(vec![auth])
        bld.tor_network().fallback_caches().replace(vec![fallback]);
            .fallback_caches()
            .set(vec![fallback]);
        bld.storage()
        bld.storage()
            .cache_dir(CfgPath::new("/var/tmp/foo".to_owned()))
            .cache_dir(CfgPath::new("/var/tmp/foo".to_owned()))
            .state_dir(CfgPath::new("/var/tmp/bar".to_owned()));
            .state_dir(CfgPath::new("/var/tmp/bar".to_owned()));
+8 −6
Original line number Original line Diff line number Diff line
@@ -229,8 +229,7 @@ mod test {
        let auth = dir::Authority::builder()
        let auth = dir::Authority::builder()
            .name("Fred")
            .name("Fred")
            .v3ident([22; 20].into())
            .v3ident([22; 20].into())
            .build()
            .clone();
            .unwrap();
        let fallback = dir::FallbackDir::builder()
        let fallback = dir::FallbackDir::builder()
            .rsa_identity([23; 20].into())
            .rsa_identity([23; 20].into())
            .ed_identity([99; 32].into())
            .ed_identity([99; 32].into())
@@ -240,11 +239,11 @@ mod test {
        let mut bld = ArtiConfig::builder();
        let mut bld = ArtiConfig::builder();
        bld.proxy().socks_port(Some(9999));
        bld.proxy().socks_port(Some(9999));
        bld.logging().console("warn");
        bld.logging().console("warn");
        bld.tor().tor_network().authorities().replace(vec![auth]);
        bld.tor()
        bld.tor()
            .tor_network()
            .tor_network()
            .authorities(vec![auth])
            .fallback_caches()
            .fallback_caches()
            .set(vec![fallback]);
            .replace(vec![fallback]);
        bld.tor()
        bld.tor()
            .storage()
            .storage()
            .cache_dir(CfgPath::new("/var/tmp/foo".to_owned()))
            .cache_dir(CfgPath::new("/var/tmp/foo".to_owned()))
@@ -260,10 +259,13 @@ mod test {
            .path_rules()
            .path_rules()
            .ipv4_subnet_family_prefix(20)
            .ipv4_subnet_family_prefix(20)
            .ipv6_subnet_family_prefix(48);
            .ipv6_subnet_family_prefix(48);
        bld.tor().preemptive_circuits().disable_at_threshold(12);
        bld.tor()
            .preemptive_circuits()
            .initial_predicted_ports()
            .replace(vec![80, 443]);
        bld.tor()
        bld.tor()
            .preemptive_circuits()
            .preemptive_circuits()
            .disable_at_threshold(12)
            .initial_predicted_ports(vec![80, 443])
            .prediction_lifetime(Duration::from_secs(3600))
            .prediction_lifetime(Duration::from_secs(3600))
            .min_exit_circs_for_port(2);
            .min_exit_circs_for_port(2);
        bld.tor()
        bld.tor()
+8 −46
Original line number Original line Diff line number Diff line
@@ -5,7 +5,7 @@ use derive_builder::Builder;
use serde::Deserialize;
use serde::Deserialize;
use std::path::Path;
use std::path::Path;
use std::str::FromStr;
use std::str::FromStr;
use tor_config::{CfgPath, ConfigBuildError};
use tor_config::{define_list_config_builder, CfgPath, ConfigBuildError};
use tracing::Subscriber;
use tracing::Subscriber;
use tracing_appender::non_blocking::WorkerGuard;
use tracing_appender::non_blocking::WorkerGuard;
use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::layer::SubscriberExt;
@@ -65,53 +65,15 @@ impl LoggingConfig {
/// Local type alias, mostly helpful for derive_builder to DTRT
/// Local type alias, mostly helpful for derive_builder to DTRT
type LogfileListConfig = Vec<LogfileConfig>;
type LogfileListConfig = Vec<LogfileConfig>;


#[derive(Default, Clone, Deserialize)]
define_list_config_builder! {
#[serde(transparent)]
    /// List of logfiles to use, being built as part of the configuration.
/// List of logfiles to use, being built as part of the configuration
pub struct LogfileListConfigBuilder {
    /// The logfiles, as overridden
    files: Option<Vec<LogfileConfigBuilder>>,
}

impl LogfileListConfigBuilder {
    /// Add a file logger
    pub fn append(&mut self, file: LogfileConfigBuilder) -> &mut Self {
        self.files
            .get_or_insert_with(Self::default_files)
            .push(file);
        self
    }

    /// Set the list of file loggers to the supplied `files`
    pub fn set(&mut self, files: impl IntoIterator<Item = LogfileConfigBuilder>) -> &mut Self {
        self.files = Some(files.into_iter().collect());
        self
    }

    /// Default logfiles
    ///
    ///
    /// (Currently) there are no defauolt logfiles.
    /// The default is not to log to any files.
    pub(crate) fn default_files() -> Vec<LogfileConfigBuilder> {
    pub struct LogfileListConfigBuilder {
        vec![]
        files: [LogfileConfigBuilder],
    }

    /// Resolve `LoggingConfigBuilder.files` to a value for `LoggingConfig.files`
    pub(crate) fn build(&self) -> Result<Vec<LogfileConfig>, ConfigBuildError> {
        let default_buffer;
        let files = match &self.files {
            Some(files) => files,
            None => {
                default_buffer = Self::default_files();
                &default_buffer
            }
        };
        let files = files
            .iter()
            .map(|item| item.build())
            .collect::<Result<_, _>>()
            .map_err(|e| e.within("files"))?;
        Ok(files)
    }
    }
    built: LogfileListConfig = files;
    default = vec![];
}
}


/// Configuration information for an (optionally rotating) logfile.
/// Configuration information for an (optionally rotating) logfile.
+30 −0
Original line number Original line Diff line number Diff line
@@ -140,3 +140,33 @@ macro_rules! define_accessor_trait {
}
}


// ----------------------------------------------------------------------
// ----------------------------------------------------------------------

/// Helper for assisting with macro "argument" defaulting
///
/// ```ignore
/// macro_coalesce_args!{ [ something ]  ... }  // =>   something
/// macro_coalesce_args!{ [ ], [ other ] ... }  // =>   other
/// // etc.
/// ```
///
/// ### Usage note
///
/// It is generally possible to avoid use of `macro_coalesce_args`, at the cost of
/// providing many alternative matcher patterns.  Using `macro_coalesce_args` can make
/// it possible to provide a single pattern with the optional items in `$( )?`.
///
/// This is valuable because a single pattern with some optional items
/// makes much better documentation than several patterns which the reader must compare
/// by eye - and it also simplifies the implementation.
///
/// `macro_coalesce_args` takes each of its possible expansions in `[ ]` and returns
/// the first nonempty one.
#[macro_export]
macro_rules! macro_first_nonempty {
    { [ $($yes:tt)+ ] $($rhs:tt)* } => { $($yes)* };
    { [ ]$(,)? [ $($otherwise:tt)* ] $($rhs:tt)* } => {
        $crate::macro_first_nonempty!{ [ $($otherwise)* ] $($rhs)* }
    };
}

// ----------------------------------------------------------------------
Loading