fn merge_dotrc(
    partial_config: PartialConfig,
    dotrc_config: dotrc::Config,
) -> Result<Config, Error> {
    /// Merges an item from a `PartialConfig` and an item from a
    /// `dotrc::Config`, making sure to respect the hierarchy of selecting
    /// in the following order
    /// - CLI
    /// - dotrc
    /// - Default source
    fn merge_hierarchy<T>(partial: (T, PartialSource), dotrc: Option<T>) -> T {
        match (partial, dotrc) {
            ((x, PartialSource::Cli), _) => x,
            (_, Some(x)) => x,
            ((x, PartialSource::Default), None) => x,
        }
    }

    let dotfiles_path = AbsolutePath::from(merge_hierarchy(
        partial_config.dotfiles_path,
        dotrc_config.dotfiles_path.map(util::tilde_to_home),
    ));

    let excludes = {
        let mut excludes: Vec<AbsolutePath> =
            // Merge the excludes from partial_config (CLI + default) with the excludes from the dotrc
            util::append_vecs(
                partial_config.excludes,
                // We need to handle the possibility of the dotrc not specifying any excludes,
                // as well as converting from the raw `String` input to a `PathBuf`
                dotrc_config
                    .excludes
                    .unwrap_or_default()
                    .iter()
                    .map(PathBuf::from)
                    .collect(),
            )
            .into_iter()
            // Try to glob expand each exclude
            .map(|path| expand_glob(&path, &dotfiles_path))
            // If any glob expansion failed due to an I/O error, give up
            .collect::<Result<Vec<Vec<_>>, _>>()?
            // Then flatten the glob-expanded results
            .into_iter()
            .flatten()
            // Finally, make each exclude path absolute by prepending them with
            // the dotfiles path
            .map(|exclude| AbsolutePath::from(dotfiles_path.join(exclude)))
            .collect();

        // Finally, remove any duplicate entries due to files matching multiple globs
        let set: HashSet<_> = excludes.drain(..).collect();
        excludes.extend(set.into_iter());

        excludes
    };

    let tags = util::append_vecs(partial_config.tags, dotrc_config.tags.unwrap_or_default());

    let hostname = merge_hierarchy(partial_config.hostname, dotrc_config.hostname);

    let platform = match (partial_config.platform, dotrc_config.platform) {
        ((platform, PartialSource::Cli), _) => platform,
        (_, Some(platform)) => Platform::from_str(&platform)?,
        ((platform, PartialSource::Default), None) => platform,
    };

    let command = partial_config.command;

    Ok(Config {
        excludes,
        tags,
        dotfiles_path,
        hostname,
        platform,
        command,
    })
}
/// Merges a partial config (obtained from the CLI and default settings) with a
/// config obtained from reading the dotrc to create a complete configuration.
Merges a partial config (obtained from the CLI and default settings) with a
config obtained from reading the dotrc to create a complete configuration.
Merges a partial config ( obtained from the CLI and default settings ) with a config obtained from reading the dotrc to create a complete configuration .
fn merge_dotrc(
    partial_config: PartialConfig,
    dotrc_config: dotrc::Config,
) -> Result<Config, Error> {
    /// Merges an item from a `PartialConfig` and an item from a
    /// `dotrc::Config`, making sure to respect the hierarchy of selecting
    /// in the following order
    /// - CLI
    /// - dotrc
    /// - Default source
    fn merge_hierarchy<T>(partial: (T, PartialSource), dotrc: Option<T>) -> T {
        match (partial, dotrc) {
            ((x, PartialSource::Cli), _) => x,
            (_, Some(x)) => x,
            ((x, PartialSource::Default), None) => x,
        }
    }
    let dotfiles_path = AbsolutePath::from(merge_hierarchy(
        partial_config.dotfiles_path,
        dotrc_config.dotfiles_path.map(util::tilde_to_home),
    ));
    let excludes = {
        let mut excludes: Vec<AbsolutePath> =
            // Merge the excludes from partial_config (CLI + default) with the excludes from the dotrc
            util::append_vecs(
                partial_config.excludes,
                // We need to handle the possibility of the dotrc not specifying any excludes,
                // as well as converting from the raw `String` input to a `PathBuf`
                dotrc_config
                    .excludes
                    .unwrap_or_default()
                    .iter()
                    .map(PathBuf::from)
                    .collect(),
            )
            .into_iter()
            // Try to glob expand each exclude
            .map(|path| expand_glob(&path, &dotfiles_path))
            // If any glob expansion failed due to an I/O error, give up
            .collect::<Result<Vec<Vec<_>>, _>>()?
            // Then flatten the glob-expanded results
            .into_iter()
            .flatten()
            // Finally, make each exclude path absolute by prepending them with
            // the dotfiles path
            .map(|exclude| AbsolutePath::from(dotfiles_path.join(exclude)))
            .collect();
        // Finally, remove any duplicate entries due to files matching multiple globs
        let set: HashSet<_> = excludes.drain(..).collect();
        excludes.extend(set.into_iter());
        excludes
    };
    let tags = util::append_vecs(partial_config.tags, dotrc_config.tags.unwrap_or_default());
    let hostname = merge_hierarchy(partial_config.hostname, dotrc_config.hostname);
    let platform = match (partial_config.platform, dotrc_config.platform) {
        ((platform, PartialSource::Cli), _) => platform,
        (_, Some(platform)) => Platform::from_str(&platform)?,
        ((platform, PartialSource::Default), None) => platform,
    };
    let command = partial_config.command;
    Ok(Config {
        excludes,
        tags,
        dotfiles_path,
        hostname,
        platform,
        command,
    })
}
fn merge_dotrc ( partial_config : PartialConfig , dotrc_config : dotrc :: Config , ) -> Result < Config , Error > { /// Merges an item from a `PartialConfig` and an item from a /// `dotrc::Config`, making sure to respect the hierarchy of selecting /// in the following order /// - CLI /// - dotrc /// - Default source fn merge_hierarchy < T > ( partial : ( T , PartialSource ) , dotrc : Option < T > ) -> T { match ( partial , dotrc ) { ( ( x , PartialSource :: Cli ) , _ ) => x , ( _ , Some ( x ) ) => x , ( ( x , PartialSource :: Default ) , None ) => x , } } let dotfiles_path = AbsolutePath :: from ( merge_hierarchy ( partial_config . dotfiles_path , dotrc_config . dotfiles_path . map ( util :: tilde_to_home ) , ) ) ; let excludes = { let mut excludes : Vec < AbsolutePath > = // Merge the excludes from partial_config (CLI + default) with the excludes from the dotrc util :: append_vecs ( partial_config . excludes , // We need to handle the possibility of the dotrc not specifying any excludes, // as well as converting from the raw `String` input to a `PathBuf` dotrc_config . excludes . unwrap_or_default ( ) . iter ( ) . map ( PathBuf :: from ) . collect ( ) , ) . into_iter ( ) // Try to glob expand each exclude . map ( | path | expand_glob ( & path , & dotfiles_path ) ) // If any glob expansion failed due to an I/O error, give up . collect :: < Result < Vec < Vec < _ > > , _ > > ( ) ? // Then flatten the glob-expanded results . into_iter ( ) . flatten ( ) // Finally, make each exclude path absolute by prepending them with // the dotfiles path . map ( | exclude | AbsolutePath :: from ( dotfiles_path . join ( exclude ) ) ) . collect ( ) ; // Finally, remove any duplicate entries due to files matching multiple globs let set : HashSet < _ > = excludes . drain ( .. ) . collect ( ) ; excludes . extend ( set . into_iter ( ) ) ; excludes } ; let tags = util :: append_vecs ( partial_config . tags , dotrc_config . tags . unwrap_or_default ( ) ) ; let hostname = merge_hierarchy ( partial_config . hostname , dotrc_config . hostname ) ; let platform = match ( partial_config . platform , dotrc_config . platform ) { ( ( platform , PartialSource :: Cli ) , _ ) => platform , ( _ , Some ( platform ) ) => Platform :: from_str ( & platform ) ? , ( ( platform , PartialSource :: Default ) , None ) => platform , } ; let command = partial_config . command ; Ok ( Config { excludes , tags , dotfiles_path , hostname , platform , command , } ) }
Merges a partial config (obtained from the CLI and default settings) with a
config obtained from reading the dotrc to create a complete configuration.
Merges a partial config ( obtained from the CLI and default settings ) with a config obtained from reading the dotrc to create a complete configuration .
partial_config
PartialConfig
dotrc_config
dotrc::Config
partial_config
PartialConfig
dotrc_config
dotrc::Config