Files
loldog/src/main.rs
2016-09-02 12:54:20 +02:00

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)
}