walletconnect 0.0.1

WalletConnect client implementation in Rust.
Documentation
use crate::qr::image::{Dot, Grid};
use atty::Stream;
use std::io::{Result as IoResult, Write};
use termcolor::Color;
use termcolor::{ColorChoice, ColorSpec, StandardStream, WriteColor};
use terminfo::capability::MaxColors;
use terminfo::Database;

#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum Output {
    Stdout,
    Stderr,
}

impl Output {
    pub fn stream(self) -> StandardStream {
        match self {
            Output::Stdout => StandardStream::stdout(default_color_choice(Stream::Stdout)),
            Output::Stderr => StandardStream::stderr(default_color_choice(Stream::Stderr)),
        }
    }
}

fn default_color_choice(stream: Stream) -> ColorChoice {
    if atty::is(stream) {
        ColorChoice::Auto
    } else {
        ColorChoice::Never
    }
}

impl Default for Output {
    fn default() -> Self {
        Output::Stdout
    }
}

#[derive(Clone, Debug)]
pub struct Colors {
    pub black: Option<Color>,
    pub white: Option<Color>,
}

impl Colors {
    pub fn none() -> Self {
        Colors {
            black: None,
            white: None,
        }
    }

    #[cfg(unix)]
    pub fn from_env() -> Self {
        if let Ok(db) = Database::from_env() {
            match db.get::<MaxColors>() {
                Some(MaxColors(8)) => Colors::standard(),
                Some(MaxColors(256)) => Colors::ansi256(),
                _ => Colors::none(),
            }
        } else {
            Colors::none()
        }
    }

    #[cfg(windows)]
    pub fn from_env() -> Self {
        Colors::standard()
    }

    fn standard() -> Self {
        Colors {
            black: Some(Color::Black),
            white: Some(Color::White),
        }
    }

    #[cfg(unix)]
    fn ansi256() -> Self {
        Colors {
            black: Some(Color::Ansi256(16)),
            white: Some(Color::Ansi256(231)),
        }
    }
}

pub trait Print {
    fn print(&self, output: Output, colors: Colors) -> IoResult<()>;
}

impl Print for Grid {
    fn print(&self, output: Output, colors: Colors) -> IoResult<()> {
        let stream = output.stream();
        let mut w = stream.lock();
        let Colors { black, white } = colors;

        let (lines, last_row) = self.lines();

        w.reset()?;
        for line in lines {
            w.set_color(
                ColorSpec::new()
                    .set_reset(false)
                    .set_fg(white)
                    .set_bg(black),
            )?;
            for point in line {
                write!(
                    w,
                    "{}",
                    match point {
                        (Dot::Black, Dot::Black) => ' ',
                        (Dot::Black, Dot::White) => '',
                        (Dot::White, Dot::Black) => '',
                        (Dot::White, Dot::White) => '',
                    }
                )?;
            }
            w.reset()?;
            writeln!(w)?;
        }

        if let Some(row) = last_row {
            w.set_color(ColorSpec::new().set_reset(false).set_fg(white))?;
            let mut current_fg = white;

            for dot in row {
                if black.is_some() && w.supports_color() {
                    let fg = match dot {
                        Dot::Black => black,
                        Dot::White => white,
                    };
                    if fg != current_fg {
                        w.set_color(ColorSpec::new().set_reset(false).set_fg(fg))?;
                        current_fg = fg;
                    }
                    write!(w, "")?;
                } else {
                    write!(
                        w,
                        "{}",
                        match dot {
                            Dot::White => '',
                            Dot::Black => ' ',
                        }
                    )?;
                }
            }
            writeln!(w)?;
        }

        Ok(())
    }
}