extern crate getopts; extern crate rand; extern crate ansi_term; use std::io; use std::io::prelude::*; use std::f32::consts::PI; use std::env; use getopts::Options; use rand::{thread_rng, Rng}; use ansi_term::Colour::RGB; fn print_usage(program: &str, opts: Options) { let brief = format!("Usage: {} [OPTION]... [FILE]...", program); print!("{}", opts.usage(&brief)); } fn main() { let args: Vec = env::args().collect(); let program = args[0].clone(); let mut opts = Options::new(); opts.optopt("p", "spread", "Rainbow spread", ""); opts.optopt("F", "freq", "Rainbow frequency", ""); opts.optopt("S", "seed", "Rainbow seed, 0 = random", ""); opts.optflag("h", "help", "Show this message"); let matches = match opts.parse(&args[1..]) { Ok(m) => { m } Err(f) => { panic!(f.to_string()) } }; if matches.opt_present("h") { print_usage(&program, opts); return; } // @todo this is nasty... fix this. let spread : f32 = match matches.opt_default("spread", "3.0") { Some(s) => { match s.parse() { Ok(0.0) => 3.0, Ok(n) => n, _ => 3.0 } }, None => 3.0 }; // @todo this is nasty... fix this. let freq : f32 = match matches.opt_default("freq", "0.1") { Some(s) => { match s.parse() { Ok(0.0) => 0.1, Ok(n) => n, _ => 0.1 } }, None => 0.1 }; // @todo this is nasty... fix this. let mut seed : i32 = match matches.opt_default("seed", "0") { Some(s) => { match s.parse() { Ok(0) => thread_rng().gen_range(0, 256), Ok(n) => n, _ => thread_rng().gen_range(0, 256) } }, None => thread_rng().gen_range(0, 256) }; let stdin = io::stdin(); for line in stdin.lock().lines() { seed += 1; let mut delta = 0; for c in line.unwrap().chars() { delta += match c { '\t' => 8, _ => 1 }; let (red, green, blue) = rainbow(freq, (seed + delta) as f32 / spread); print!("{}", RGB(red, green, blue).paint(c.to_string())); } print!("\n"); } } fn rainbow(frec: f32, i: f32) -> (u8, u8, u8) { let red = (f32::sin(frec * i) * 127.0 + 128.0) as u8; let green = (f32::sin(frec * i + 2.0 * PI / 3.0) * 127.0 + 128.0) as u8; let blue = (f32::sin(frec * i + 4.0 * PI / 3.0) * 127.0 + 128.0) as u8; (red, green, blue) }