#![forbid(unsafe_code)]
#![warn(warnings)]
#![warn(clippy::all, clippy::pedantic)]
#![allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)]
use std::{fs::File, io::Write, path::Path, thread::sleep, time::Duration};
use clap::Parser;
use terminal_size::{terminal_size, Height, Width};
mod cli;
use cli::Args;
fn render_to_stdout(fin: &Path, width: i32, height: i32) -> asciiframe::Result<()> {
asciiframe::render(fin, width, height, |frame| {
println!("{esc}c", esc = 27 as char);
println!("{}", frame.data);
let time_d = 1.0 / f32::from(frame.fps);
if frame.elapsed < time_d {
sleep(Duration::from_millis(
((time_d - frame.elapsed) * 1000.0) as u64,
));
}
Ok(())
})
}
fn render_to_file(fin: &Path, width: i32, height: i32, fout: &Path) -> asciiframe::Result<()> {
let mut fout = File::create(fout)?;
fout.write_all(
"#!/bin/bash\n# This file was auto-generated by asciiframe\necho -en '\x1b[2J' \n"
.as_bytes(),
)?;
asciiframe::render(fin, width, height, |frame| {
fout.write_all(
format!(
"echo '{}'\nsleep {}\necho '\u{001b}[0;0H' \n",
frame.data,
1.0 / f32::from(frame.fps),
)
.as_bytes(),
)?;
Ok(())
})
}
pub fn main() {
let args = Args::parse();
let (Width(w), Height(h)) = terminal_size().unwrap_or((Width(256), Height(256)));
let width = i32::from(w);
let height = i32::from(h);
let result = if let Some(path) = args.output {
render_to_file(&args.file, width, height, &path)
} else {
render_to_stdout(&args.file, width, height)
};
match result {
Err(error) => {
println!("{error}");
std::process::exit(1);
}
Ok(()) => {
std::process::exit(0);
}
}
}