added simple tui interface
This commit is contained in:
parent
9f0f94a9f5
commit
e802e87c28
@ -7,7 +7,4 @@ edition = "2024"
|
||||
anyhow = "1.0.98"
|
||||
clap = { version = "4.5.39", features = ["derive"] }
|
||||
colored = "3.0.0"
|
||||
|
||||
[dev-dependencies]
|
||||
predicates = "3.1.3"
|
||||
assert_cmd = "2.0.17"
|
||||
cursive = "0.21.1"
|
||||
|
||||
@ -7,7 +7,7 @@ use anyhow::Error;
|
||||
use clap::Parser;
|
||||
use colored::Colorize;
|
||||
|
||||
use crate::img::{cat_picture, woof_err};
|
||||
use crate::img::{cat_picture, cat_picture_coloured, woof_err};
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
struct Options {
|
||||
@ -46,7 +46,7 @@ pub fn run_cli() -> Result<(), Error> {
|
||||
fn run_cli_with_args(mut options: Options) -> Result<(), Error> {
|
||||
let message = get_message(&mut options)?;
|
||||
// get picture before printing message - this way if theres an error it gets printed first
|
||||
let cat_picture = cat_picture(options.file, options.dead)?;
|
||||
let cat_picture = cat_picture_coloured(options.file, options.dead)?;
|
||||
woof_err(&message);
|
||||
println!("{}", format_msg(&message));
|
||||
println!("{}", cat_picture);
|
||||
@ -9,9 +9,13 @@ const DEFAULT_TEMPLATE: &str = r#" \
|
||||
( {eye} {eye} )
|
||||
=( I )="#;
|
||||
|
||||
fn get_eye(dead: bool) -> String {
|
||||
fn get_eye(dead: bool, colored: bool) -> String {
|
||||
let eye = if dead { "x" } else { "o" };
|
||||
format!("{}", eye.red().bold())
|
||||
if colored {
|
||||
format!("{}", eye.red().bold())
|
||||
} else {
|
||||
eye.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn woof_err(message: &str) {
|
||||
@ -31,7 +35,19 @@ fn get_template(file: Option<PathBuf>) -> Result<String, Error> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cat_picture(file: Option<PathBuf>, dead: bool) -> Result<String, Error> {
|
||||
pub fn cat_picture(file: Option<PathBuf>, dead: bool, colored: bool) -> Result<String, Error> {
|
||||
let template = get_template(file)?;
|
||||
Ok(template.replace("{eye}", &get_eye(dead)))
|
||||
Ok(template.replace("{eye}", &get_eye(dead, colored)))
|
||||
}
|
||||
|
||||
pub fn cat_picture_coloured(file: Option<PathBuf>, dead: bool) -> Result<String, Error> {
|
||||
cat_picture(file, dead, true)
|
||||
}
|
||||
|
||||
pub fn cat_picture_uncoloured(file: Option<PathBuf>, dead: bool) -> Result<String, Error> {
|
||||
cat_picture(file, dead, false)
|
||||
}
|
||||
|
||||
pub fn default_cat() -> String {
|
||||
cat_picture_uncoloured(None, false).expect("This shouldnt happen")
|
||||
}
|
||||
|
||||
@ -1,2 +1,3 @@
|
||||
pub mod cli;
|
||||
pub(crate) mod img;
|
||||
pub mod run;
|
||||
pub mod tui;
|
||||
|
||||
82
cat_cli/src/tui.rs
Normal file
82
cat_cli/src/tui.rs
Normal file
@ -0,0 +1,82 @@
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
use cursive::{
|
||||
Cursive, CursiveRunnable,
|
||||
event::Key,
|
||||
view::Nameable,
|
||||
views::{Checkbox, Dialog, EditView, ListView},
|
||||
};
|
||||
|
||||
use crate::img::cat_picture_uncoloured;
|
||||
|
||||
#[derive(Default)]
|
||||
struct GlobalView(CursiveRunnable);
|
||||
|
||||
unsafe impl Send for GlobalView {}
|
||||
|
||||
impl GlobalView {
|
||||
fn add_quit_callback(&mut self) {
|
||||
self.0.add_global_callback(Key::Esc, |k| k.quit());
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for GlobalView {
|
||||
type Target = CursiveRunnable;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for GlobalView {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
struct Options<'a> {
|
||||
message: &'a str,
|
||||
dead: bool,
|
||||
}
|
||||
|
||||
fn cat_output_dialog(msg: &str, dead: bool) -> Dialog {
|
||||
let cat = cat_picture_uncoloured(None, dead).unwrap();
|
||||
Dialog::text(format!("{}\n{}", msg, cat))
|
||||
.title("The cat says")
|
||||
.button("Ok", |s| s.quit())
|
||||
}
|
||||
|
||||
fn cat_input_form() -> Dialog {
|
||||
Dialog::new()
|
||||
.title("Fill cat form")
|
||||
.content(
|
||||
ListView::new()
|
||||
.child("Say?:", EditView::new().with_name("message"))
|
||||
.child("dead?:", Checkbox::new().with_name("dead")),
|
||||
)
|
||||
.button("Ok", |s| {
|
||||
let message = s
|
||||
.call_on_name("message", |t: &mut EditView| t.get_content())
|
||||
.unwrap();
|
||||
let is_dead = s
|
||||
.call_on_name("dead", |t: &mut Checkbox| t.is_checked())
|
||||
.unwrap();
|
||||
let options = Options {
|
||||
message: &message.clone(),
|
||||
dead: is_dead,
|
||||
};
|
||||
print_cat(s, &options);
|
||||
})
|
||||
}
|
||||
|
||||
fn print_cat(view: &mut Cursive, options: &Options<'_>) {
|
||||
view.pop_layer();
|
||||
view.add_layer(cat_output_dialog(options.message, options.dead));
|
||||
}
|
||||
|
||||
pub fn run_tui() {
|
||||
let mut siv = GlobalView::default();
|
||||
siv.add_quit_callback();
|
||||
siv.add_layer(cat_input_form());
|
||||
siv.run();
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user