You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: tasks_builder.rs
    path of file: ./repos/moon/nextgen/task-builder/src
    
    the code of the file until where you have to start completion: #![allow(dead_code)]

use crate::tasks_builder_error::TasksBuilderError;
use moon_common::{color, Id};
use moon_config::{
    is_glob_like, InheritedTasksConfig, InputPath, PlatformType, ProjectConfig,
    ProjectWorkspaceInheritedTasksConfig, TaskConfig, TaskDependency, TaskDependencyConfig,
    TaskMergeStrategy, TaskOptionsConfig, TaskOutputStyle, TaskType, ToolchainConfig,
};
use moon_platform_detector::detect_task_platform;
use moon_target::Target;
use moon_task::{parse_task_args, Task, TaskOptions};
use rustc_hash::{FxHashMap, FxHashSet};
use std::collections::BTreeMap;
use std::hash::Hash;
use std::path::Path;
use tracing::trace;

struct ConfigChain<'proj> {
    config: &'proj TaskConfig,
    inherited: bool,
}

fn extract_config<'builder, 'proj>(
    task_id: &'builder Id,
    local_tasks: &'builder FxHashMap<&'proj Id, &'proj TaskConfig>,
    global_tasks: &'builder FxHashMap<&'proj Id, &'proj TaskConfig>,
) -> miette::Result<Vec<ConfigChain<'proj>>> {
    let mut stack = vec![];

    let mut extract = |tasks: &'builder FxHashMap<&'proj Id, &'proj TaskConfig>,
                       inherited: bool|
     -> miette::Result<()> {
        if let Some(config) = tasks.get(task_id) {
            stack.push(ConfigChain { config, inherited });

            if let Some(extend_task_id) = &config.extends {
                let extended_stack = extract_config(extend_task_id, local_tasks, global_tasks)?;

                if extended_stack.is_empty() {
                    return Err(TasksBuilderError::UnknownExtendsSource {
                        source_id: task_id.to_owned(),
                        target_id: extend_task_id.to_owned(),
                    }
                    .into());
                } else {
                    stack.extend(extended_stack);
                }
            }
        }

        Ok(())
    };

    extract(local_tasks, false)?;
    extract(global_tasks, true)?;

    Ok(stack)
}

pub struct TasksBuilderContext<'proj> {
    pub toolchain_config: &'proj ToolchainConfig,
    pub workspace_root: &'proj Path,
}

pub struct TasksBuilder<'proj> {
    context: TasksBuilderContext<'proj>,

    project_id: &'proj str,
    project_env: FxHashMap<&'proj str, &'proj str>,
    project_platform: &'proj PlatformType,
    project_source: &'proj str,

    // Global settings for tasks to inherit
    implicit_deps: Vec<&'proj TaskDependency>,
    implicit_inputs: Vec<&'proj InputPath>,

    // Tasks to merge 
    
    fn build_task_options(&self, id: &Id, is_local: bool) -> miette::Result<TaskOptions> {
        let mut options = TaskOptions {
            cache: !is_local,
            interactive: false,
            output_style: is_local.then_some(TaskOutputStyle::Stream),
            persistent: is_local,
            run_in_ci: !is_local,
            ..TaskOptions::default()
        };

        let mut chain = vec![];

        if let Some(default_options) = self.global_task_options {
            chain.push(default_options);
        }

        chain.extend(
            self.get_config_inherit_chain(id)?
                .iter()
                .map(|link| &link.config.options)
                .collect::<Vec<_>>(),
        );

        for config in chain {
            if let Some(affected_files) = &config.affected_files {
                options.affected_files = Some(affected_files.to_owned());
            }

            if let Some(affected_pass_inputs) = &config.affected_pass_inputs {
                options.affected_pass_inputs = *affected_pass_inputs;
            }

            if let Some(allow_failure) = &config.allow_failure {
                options.allow_failure = *allow_failure;
            }

            if let Some(cache) = &config.cache {
                options.cache = *cache;
            }

            if let Some(env_file) = &config.env_file {
                options.env_files = env_file.to_input_paths();
            }

            if let Some(interactive) = &config.interactive {
                options.interactive = *interactive;
            }

            if let Some(merge_args) = &config.merge_args {
                options.merge_args = *merge_args;
            }

            if let Some(merge_deps) = &config.merge_deps {
                options.merge_deps = *merge_deps;
            }

            if let Some(merge_env) = &config.merge_env {
                options.merge_env = *merge_env;
            }

            if let Some(merge_inputs) = &config.merge_inputs {
                options.merge_inputs = *merge_inputs;
            }

            if let Some(merge_outputs) = &config.merge_outputs {
                options.merge_outputs = *merge_outputs;
            }

            if let Some(output_style) = &config.output_style {
                options.output_style = Some(*output_style);
            }

            if let Some(persistent) = &config.persistent {
                options.persistent = *persistent;
            }

            if let Some(retry_count) = &config.retry_count {
                options.retry_count = *retry_count;
            }

            if let Some(run_deps_in_parallel) = &config.run_deps_in_parallel {
                options.run_deps_in_parallel = *run_deps_in_parallel;
            }

            if let Some(run_in_ci) = &config.run_in_ci {
                options.run_in_ci = *run_in_ci;
            }

            if let Some(run_from_workspace_root) = &config.run_from_workspace_root {
                options.run_from_workspace_root = *run_from_workspace_root;
            }

            if let Some(shell) = &config.shell {
                options.shell = Some(*shell);
            }

            if let Some(unix_shell) = &config.unix_shell {
                options.unix_shell = Some(*unix_shell);
            }

            if let Some(windows_shell) = &config.windows_shell {
                options.windows_shell = Some(*windows_shell);
            }
        }

        if options.interactive {
            options.cache = false;
            options.output_style = Some(TaskOutputStyle::Stream);
            options.persistent = false;
            options.run_in_ci = false;
        }

        Ok(options)
    }