use std::io::stdout; use std::time::Duration; use anyhow::Error; use clap::Parser; use clap::ArgEnum; use crossterm::style::Color::*; use crate::animation::Animation; use crate::animation::circle::CircleAnimation; use crate::char::SimpleCharSampler; use crate::color::{ColorSampler, SimpleColorSampler}; use crate::fill::circle::CircleFillMode; use crate::fill::FillMode; use crate::fill::level::LevelFillMode; use crate::render::{Renderer, SamplerRenderer}; use crate::runner::Runner; use crate::sampler::ComposedSampler; use crate::surface::WriteSurface; use crate::timer::SimpleTimer; use crate::vec::Vector; mod color; mod char; mod fill; mod vec; mod array; mod surface; mod animation; mod sampler; mod render; mod timer; mod runner; #[derive(Copy, Clone, ArgEnum)] enum AnimationType { Circle } #[derive(Copy, Clone, ArgEnum)] enum ColorType { Red, Green, Blue, LightRed, LightGreen, LightBlue, Grey, Rainbow, } #[derive(Copy, Clone, ArgEnum)] enum FillModeType { Circle, Level } #[derive(Parser)] #[clap(author = "Rico Riedel", version = "0.1.0", about = "Wipe your terminal with a random animation.")] struct Args { #[clap(short, long, help = "Add animation", arg_enum)] animation: Vec, #[clap(short, long, help = "Add fill mode", arg_enum)] fill: Vec, #[clap(short, long, help = "Add color pallet", arg_enum)] color: Vec, #[clap(long, default_value = ".-+%#", help = "Set chars")] chars: String, #[clap(long, help = "Set width [default: terminal width]")] width: Option, #[clap(long, help = "Set height [default: terminal height]")] height: Option, } fn main() -> Result<(), Error> { let args = Args::parse(); let terminal = crossterm::terminal::size()?; let width = args.width.unwrap_or(terminal.0 as usize); let height = args.width.unwrap_or(terminal.1 as usize); let size = Vector::from_terminal(width, height); let animation = create_animation(args.animation[0], size); let fill = create_fill(args.fill[0], size); let color = create_color(args.color[0]); let char = Box::new(SimpleCharSampler::new(args.chars)); let sampler = Box::new(ComposedSampler::new(animation, fill, color, char)); let surface = Box::new(WriteSurface::new(stdout(), width, height)); let renderer = Box::new(SamplerRenderer::new(surface, sampler)); let timer = Box::new(SimpleTimer::new(Duration::from_millis(1000 / 60))); let runner = Runner::new(Duration::from_secs(2), timer, renderer); runner.run() } fn create_animation(animation: AnimationType, size: Vector) -> Box { match animation { AnimationType::Circle => Box::new(CircleAnimation::new(size)) } } fn create_fill(fill: FillModeType, size: Vector) -> Box { match fill { FillModeType::Circle => Box::new(CircleFillMode::new(size)), FillModeType::Level => Box::new(LevelFillMode::new()), } } fn create_color(color: ColorType) -> Box { match color { ColorType::Red => Box::new(SimpleColorSampler::new(vec![Yellow, DarkYellow, Red])), ColorType::Green => Box::new(SimpleColorSampler::new(vec![Cyan, DarkGreen, Green])), ColorType::Blue => Box::new(SimpleColorSampler::new(vec![Magenta, DarkBlue, Blue])), ColorType::LightRed => Box::new(SimpleColorSampler::new(vec![White, Yellow, Red])), ColorType::LightGreen => Box::new(SimpleColorSampler::new(vec![White, Cyan, Green])), ColorType::LightBlue => Box::new(SimpleColorSampler::new(vec![White, Blue, Magenta])), ColorType::Grey => Box::new(SimpleColorSampler::new(vec![Black, Grey, White])), ColorType::Rainbow => Box::new(SimpleColorSampler::new(vec![Magenta, Blue, Green, Yellow, Red])) } }