107 lines
2.6 KiB
Rust
107 lines
2.6 KiB
Rust
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<String> = env::args().collect();
|
|
let program = args[0].clone();
|
|
|
|
let mut opts = Options::new();
|
|
|
|
opts.optopt("p", "spread", "Rainbow spread", "<f>");
|
|
opts.optopt("F", "freq", "Rainbow frequency", "<f>");
|
|
opts.optopt("S", "seed", "Rainbow seed, 0 = random", "<i>");
|
|
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)
|
|
}
|