1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
extern crate syntect;
extern crate reqwest;

use std::io::Read;
use syntect::easy::HighlightLines;
use syntect::util::as_24_bit_terminal_escaped;
use syntect::parsing::SyntaxSet;
use syntect::highlighting::{ThemeSet, Style, Theme};
use std::io::Cursor;
use reqwest::header::HeadersItems;
use reqwest::header::HeaderView;

pub struct Html {
    raw_string: String
}

impl Html {
    pub fn parse<R: Read>(input: &mut R) -> Option<Html> {
        let mut s = String::new();
        match input.read_to_string(&mut s) {
            Ok(_) => {
                Some(Html {
                    raw_string: s
                })
            }
            Err(_) => {
                None
            }
        }
    }

    pub fn ansi_colorized(&self) -> String {
        let ps = SyntaxSet::load_defaults_nonewlines();
        let mut theme_str = Cursor::new(include_str!("base16-tomorrow-night.tmTheme"));
        let theme = ThemeSet::load_from_reader(&mut theme_str).unwrap();
        let syntax = ps.find_syntax_by_extension("html").unwrap();
        let mut h = HighlightLines::new(syntax, &theme);
        let mut output = String::new();

        for line in self.raw_string.lines() {
            let ranges: Vec<(Style, &str)> = h.highlight(line);
            let escaped = as_24_bit_terminal_escaped(&ranges[..], false);
            output += escaped.as_str();
            output += "\n";
        }

        output
    }
}


/// Colorize a given iterator of headers
/// Currently this function will collect the colorized headers into a vector of strings
pub fn colorized_headers(headers: HeadersItems) -> ColorizedHeaders {
    let mut theme_str = Cursor::new(include_str!("base16-tomorrow-night.tmTheme"));
    let theme = ThemeSet::load_from_reader(&mut theme_str).unwrap();
    let ps = SyntaxSet::load_defaults_nonewlines();
    let syntax = ps.find_syntax_by_extension("yaml").unwrap();
    let mut highlighter = HighlightLines::new(syntax, &theme);
    let mut output = Vec::new();

    for header in headers {
        let header_repr = header.to_string();
        let ranges: Vec<(Style, &str)> = highlighter.highlight(&header_repr);
        let escaped = as_24_bit_terminal_escaped(&ranges[..], false);
        output.push(escaped);
    }

    output
}

pub type ColorizedHeaders = Vec<String>;


#[cfg(test)]
mod tests {
    use Html;
    use std::io::Cursor;
    use reqwest::header::{Headers, ContentType};
    use colorized_headers;

    #[test]
    fn colorize_div() {
        let mut div_str = Cursor::new("<div>foo</div>".to_string());
        let html = Html::parse(&mut div_str).unwrap();

        let pretty = html.ansi_colorized();
        assert_eq!(&pretty, "\u{1b}[38;2;197;200;198m<\u{1b}[38;2;204;102;102mdiv\u{1b}[38;2;197;200;198m>\u{1b}[38;2;197;200;198mfoo\u{1b}[38;2;197;200;198m</\u{1b}[38;2;204;102;102mdiv\u{1b}[38;2;197;200;198m>\n");
    }

    #[test]
    fn colorize_headers() {
        let mut headers = Headers::new();
        headers.set(ContentType::html());

        let pretty = colorized_headers(headers.iter());

        assert_eq!(pretty[0], "\u{1b}[38;2;204;102;102mContent-Type\u{1b}[38;2;197;200;198m:\u{1b}[38;2;197;200;198m \u{1b}[38;2;181;189;104mtext/html\u{1b}[38;2;197;200;198m\r\n");
    }
}