discord-kurante/src/commands/cube.rs

74 lines
2.6 KiB
Rust

/// This was directly ported from the Java version. I make no quality assurances.
use serenity::framework::standard::{macros::command, Args, CommandResult};
use serenity::model::channel::Message;
use serenity::prelude::Context;
use unicode_segmentation::UnicodeSegmentation;
#[command]
pub(crate) async fn cube(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult {
let resp = match args
.iter()
.map(|e: Result<String, _>| e.unwrap())
.collect::<Vec<_>>()
.as_slice()
{
[] => "What do you wanna cube?".to_string(),
args => {
let to_cube: &str = &args.join(" ");
let to_cube = UnicodeSegmentation::graphemes(to_cube, true).collect::<Vec<_>>();
let cube_len = to_cube.len();
let should_reverse = to_cube.last() != to_cube.first();
let offset = cube_len / 2;
let mut field =
vec![vec![" ".to_string(); (cube_len + offset) * 2 - 1]; cube_len + offset];
draw_diagonal(&mut field, cube_len, offset);
draw_box(&mut field, &to_cube, should_reverse, offset * 2, 0);
draw_box(&mut field, &to_cube, should_reverse, 0, offset);
let text = field
.iter()
.map(|r| r.join("").trim_end().to_string())
.collect::<Vec<_>>()
.join("\n");
["```\n".to_string(), text, "```".to_string()].concat()
}
};
msg.channel_id.say(ctx, resp).await?;
Ok(())
}
fn draw_diagonal(field: &mut Vec<Vec<String>>, cube_len: usize, offset: usize) {
let diag_char = "/".to_string();
for x in 0..offset {
field[offset - x][x * 2] = diag_char.clone();
field[cube_len - x + offset - 1][x * 2] = diag_char.clone();
field[offset - x][(x + cube_len - 1) * 2] = diag_char.clone();
field[cube_len - x + offset - 1][(x + cube_len - 1) * 2] = diag_char.clone();
}
}
fn draw_box(field: &mut Vec<Vec<String>>, chars: &[&str], should_rev: bool, x: usize, y: usize) {
let word_len = chars.len();
// Magic numbers are good as long as they're 1 or 2 right?
for i in 0..word_len {
field[y + i][x] = chars[i].to_string();
field[y][x + i * 2] = chars[i].to_string();
field[y + (word_len - 1)][x + (word_len - 1 - i) * 2] = if should_rev {
chars[i].to_string()
} else {
chars[word_len - i - 1].to_string()
};
field[y + (word_len - 1) - i][x + (word_len - 1) * 2] = if should_rev {
chars[i].to_string()
} else {
chars[word_len - i - 1].to_string()
};
}
}