<commit_before>//! This provides wrappers around the `StdoutTerminal` and `StderrTerminal` types
//! that does not fail if `StdoutTerminal` etc can't be constructed, which happens
//! if TERM isn't defined.

use lazy_static::lazy_static;
use rustup::utils::tty;
use std::io;
use std::sync::Mutex;

pub use term::color;
pub use term::Attr;
pub use term::Terminal;

mod termhack {
    // Things we should submit to term as improvements: here temporarily.
    use std::collections::HashMap;
    use std::io;
    use term::terminfo::TermInfo;
    use term::{StderrTerminal, StdoutTerminal, Terminal, TerminfoTerminal};

    // Works around stdio instances being unclonable.
    pub trait Instantiable {
        fn instance() -> Self;
    }

    impl Instantiable for io::Stdout {
        fn instance() -> Self {
            io::stdout()
        }
    }

    impl Instantiable for io::Stderr {
        fn instance() -> Self {
            io::stderr()
        }
    }

    /// Return a Terminal object for T on this platform.
    /// If there is no terminfo and the platform requires terminfo, then None is returned.
    fn make_terminal<T>(terminfo: Option<TermInfo>) -> Option<Box<Terminal<Output = T> + Send>>
    where
        T: 'static + io::Write + Send + Instantiable,
    {
        let result = terminfo
            .map(move |ti| TerminfoTerminal::new_with_terminfo(T::instance(), ti.clone()))
            .map(|t| Box::new(t) as Box<Terminal<Output = T> + Send>);
        #[cfg(windows)]
        {
            result.or_else(|| {
                term::WinConsole::new(T::instance())
                    .ok()
                    .map(|t| Box::new(t) as Box<Terminal<Output = T> + Send>)
            })
        }
        #[cfg(not(windows))]
        {
            result
        }
    }

    fn make_terminal_with_fallback<T>(
        terminfo: Option<TermInfo>,
    ) -> Box<Terminal<Output = T> + Send>
    where
        T: 'static + io::Write + Send + Instantiable,
    {
        make_terminal(terminfo)
            .or_else(|| {
                let ti = TermInfo {
                    names: vec![],
                    bools: HashMap::new(),
                    numbers: HashMap::new(),
                    strings: HashMap::new(),
                };
                let t = TerminfoTerminal::new_with_terminfo(T::instance(), ti);
                Some(Box::new(t) as Box<Terminal<Output = T> + Send>)
            })
            .unwrap()
    }
    /// Return a Terminal wrapping stdout, or None if a terminal couldn't be
    /// opened.
    #[allow(unused)]
    pub fn stdout(terminfo: Option<TermInfo>) -> Option<Box<StdoutTerminal>> {
        make_terminal(terminfo)
    }

    /// Return a Terminal wrapping stderr, or None if a terminal couldn't be
    /// opened.
    #[allow(unused)]
    pub fn stderr(terminfo: Option<TermInfo>) -> Option<Box<StderrTerminal>> {
        make_terminal(terminfo)
    }

    /// Return a Terminal wrapping stdout.
    pub fn stdout_with_fallback(terminfo: Option<TermInfo>) -> Box<StdoutTerminal> {<commit_msg>term2.rs: Add `dyn` to various Box<> types<commit_after>//! This provides wrappers around the `StdoutTerminal` and `StderrTerminal` types
//! that does not fail if `StdoutTerminal` etc can't be constructed, which happens
//! if TERM isn't defined.

use lazy_static::lazy_static;
use rustup::utils::tty;
use std::io;
use std::sync::Mutex;

pub use term::color;
pub use term::Attr;
pub use term::Terminal;

mod termhack {
    // Things we should submit to term as improvements: here temporarily.
    use std::collections::HashMap;
    use std::io;
    use term::terminfo::TermInfo;
    use term::{StderrTerminal, StdoutTerminal, Terminal, TerminfoTerminal};

    // Works around stdio instances being unclonable.
    pub trait Instantiable {
        fn instance() -> Self;
    }

    impl Instantiable for io::Stdout {
        fn instance() -> Self {
            io::stdout()
        }
    }

    impl Instantiable for io::Stderr {
        fn instance() -> Self {
            io::stderr()
        }
    }

    /// Return a Terminal object for T on this platform.
    /// If there is no terminfo and the platform requires terminfo, then None is returned.
    fn make_terminal<T>(terminfo: Option<TermInfo>) -> Option<Box<dyn Terminal<Output = T> + Send>>
    where
        T: 'static + io::Write + Send + Instantiable,
    {
        let result = terminfo
            .map(move |ti| TerminfoTerminal::new_with_terminfo(T::instance(), ti.clone()))
            .map(|t| Box::new(t) as Box<dyn Terminal<Output = T> + Send>);
        #[cfg(windows)]
        {
            result.or_else(|| {
                term::WinConsole::new(T::instance())
                    .ok()
                    .map(|t| Box::new(t) as Box<dyn Terminal<Output = T> + Send>)
            })
        }
        #[cfg(not(windows))]
        {
            result
        }
    }

    fn make_terminal_with_fallback<T>(
        terminfo: Option<TermInfo>,
    ) -> Box<dyn Terminal<Output = T> + Send>
    where
        T: 'static + io::Write + Send + Instantiable,
    {
        make_terminal(terminfo)
            .or_else(|| {
                let ti = TermInfo {
                    names: vec![],
                    bools: HashMap::new(),
                    numbers: HashMap::new(),
                    strings: HashMap::new(),
                };
                let t = TerminfoTerminal::new_with_terminfo(T::instance(), ti);
                Some(Box::new(t) as Box<dyn Terminal<Output = T> + Send>)
            })
            .unwrap()
    }
    /// Return a Terminal wrapping stdout, or None if a terminal couldn't be
    /// opened.
    #[allow(unused)]
    pub fn stdout(terminfo: Option<TermInfo>) -> Option<Box<StdoutTerminal>> {
        make_terminal(terminfo)
    }

    /// Return a Terminal wrapping stderr, or None if a terminal couldn't be
    /// opened.
    #[allow(unused)]
    pub fn stderr(terminfo: Option<TermInfo>) -> Option<Box<StderrTerminal>> {
        make_terminal(terminfo)
    }

    /// Return a Terminal wrapping stdout.
    pub fn stdout_with_fallback(terminfo: Option<TermInfo>) -> Box<StdoutTerminal> {
{'fraction_non_alphanumeric': 0.12822593734783314, 'fraction_numerical': 0.00016231131309852296, 'mean_word_length': 2.1326893746822573, 'pattern_counts': {'":': 0, '<': 50, '<?xml version=': 0, '>': 66, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7082964', 'n_tokens_mistral': 1871, 'n_tokens_neox': 1797, 'n_words': 491}