new stuff

This commit is contained in:
2026-02-27 21:44:13 +01:00
parent 6e33b9b51e
commit 444d376e42
12 changed files with 428 additions and 46 deletions

1
pandasay/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
target

1199
pandasay/Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

11
pandasay/Cargo.toml Normal file
View File

@@ -0,0 +1,11 @@
[package]
name = "pandasay"
version = "0.1.0"
edition = "2024"
[dependencies]
image = "0.25.9"
showie = "2.0.1"
clap = { version = "4.5.60", features = ["derive"] }
textwrap = "0.16.2"
unicode-width = "0.2.2"

47
pandasay/src/main.rs Normal file
View File

@@ -0,0 +1,47 @@
use clap::Parser;
use image::load_from_memory;
use std::io::{self, Read};
mod speech;
#[derive(Parser)]
struct Args {
#[arg(short, long, default_value_t = 32)]
res: u8,
}
const BYTES_32: &[u8] = include_bytes!(
"/home/jan/pl/nextcloud/Pandaloop/Intern/logos/pl_logo_r1/logo_pixel_art_32.png"
);
const BYTES_64: &[u8] = include_bytes!(
"/home/jan/pl/nextcloud/Pandaloop/Intern/logos/pl_logo_r1/logo_pixel_art_64.png"
);
fn main() {
let args = Args::parse();
let mut input_buffer = String::new();
let _ = io::stdin().read_to_string(&mut input_buffer);
let bytes = match args.res {
32 => BYTES_32,
64 => BYTES_64,
_ => panic!("Res should be 32 or 64"),
};
let img = load_from_memory(bytes).expect("Failed to decode embedded image");
let s = showie::render(&img);
println!(
"{}\n{}",
speech::print(
&input_buffer.trim(),
&speech::FormatOptions {
think: false,
width: 300,
},
),
s
);
}

110
pandasay/src/speech.rs Normal file
View File

@@ -0,0 +1,110 @@
use textwrap::wrap;
use unicode_width::UnicodeWidthStr;
pub struct FormatOptions {
pub think: bool,
pub width: u16,
}
struct Chars {
arrow: &'static str,
top: &'static str,
bottom: &'static str,
left: &'static str,
right: &'static str,
single_left: &'static str,
single_right: &'static str,
angled_up_right: &'static str,
angled_up_left: &'static str,
angled_down_right: &'static str,
angled_down_left: &'static str,
}
static SAY_CHARS: Chars = Chars {
arrow: "\\",
top: "-",
bottom: "-",
left: "|",
right: "|",
single_left: "<",
single_right: ">",
angled_up_right: "/",
angled_up_left: "\\",
angled_down_right: "\\",
angled_down_left: "/",
};
static THINK_CHARS: Chars = Chars {
arrow: "",
top: "",
bottom: "",
left: "(",
right: ")",
single_left: "(",
single_right: ")",
angled_up_right: "",
angled_up_left: "",
angled_down_right: "",
angled_down_left: "",
};
#[must_use]
pub fn generate(message: &str, format_opts: &FormatOptions) -> String {
let think = format_opts.think;
let width = format_opts.width;
let chars = if think { &THINK_CHARS } else { &SAY_CHARS };
let mut lines = wrap(message, width as usize);
let longest = lines.iter().map(|line| line.width()).max().unwrap();
format!(
"
{}
{}
{}
{}
{}",
chars.top.repeat(longest),
if lines.len() == 1 {
format!("{} {} {}", chars.single_left, lines[0], chars.single_right)
} else {
let mut result = format!(
"{} {}{}{}",
chars.angled_up_right,
lines[0],
" ".repeat(longest - lines[0].width() + 1),
chars.angled_up_left
);
lines.remove(0);
let last = lines.pop().unwrap();
for line in lines {
result = format!(
"{}\n{} {}{}{}",
result,
chars.left,
line,
" ".repeat(longest - line.width() + 1),
chars.right,
);
}
format!(
"{}\n{} {}{}{}",
result,
chars.angled_down_right,
last,
" ".repeat(longest - last.width() + 1),
chars.angled_down_left,
)
},
chars.bottom.repeat(longest),
chars.arrow,
chars.arrow,
)
}
pub fn print(message: &str, format_opts: &FormatOptions) -> String {
format!("{}", generate(message, &format_opts))
}