introduced Flag enum to unify main control flow; no more exits in complex renderers

This commit is contained in:
Valerie Wolfe 2023-07-07 12:36:31 -04:00
parent 2802f6dd42
commit b0678542ef
5 changed files with 136 additions and 61 deletions

View file

@ -1,4 +1,4 @@
use std::process::exit; //! flags that require more complex rendering than just scaling colored stripes
use termion::{ use termion::{
terminal_size, terminal_size,
@ -7,7 +7,7 @@ use termion::{
}; };
use crate::color::*; use crate::color::*;
use crate::draw; use crate::draw::{ self, Flag };
use crate::flag; use crate::flag;
/// vertically stacking eighths /// vertically stacking eighths
@ -24,7 +24,7 @@ pub static TRIANGLE_21: [char; 3] = ['', '🭬', ''];
/// 2/3 slope slant /// 2/3 slope slant
pub static SLANT_23: [char; 2] = ['🭒', '🭏']; pub static SLANT_23: [char; 2] = ['🭒', '🭏'];
pub fn progress(small: bool) -> Colors { pub fn progress(small: bool) -> Flag {
let red = bg(0xE50000); let red = bg(0xE50000);
let orange = bg(0xFF8D00); let orange = bg(0xFF8D00);
let yellow = bg(0xFFEE00); let yellow = bg(0xFFEE00);
@ -41,23 +41,68 @@ pub fn progress(small: bool) -> Colors {
let (height, width) = if small { (6, 18) } else { terminal_size().unwrap() }; let (height, width) = if small { (6, 18) } else { terminal_size().unwrap() };
// create color slices and line buffer
let stripes = [red, orange, yellow, green, blue, purple]; let stripes = [red, orange, yellow, green, blue, purple];
let chevrons = [white, pink, ltblue, brown, black]; let chevrons = [white, pink, ltblue, brown, black];
let mut lines: Vec<String> = Vec::new(); let mut lines: Vec<String> = Vec::new();
//let mut lines = draw::bg_stripes(stripes, width, height);
/* i think i'm stuck having to write stripes here too. it'll // set up stripe index
* be easier to just generate the stripes on alongside the let mut stripe_index = 0;
* chevrons than to figure out where to move the ansi bg code
/* ok, coming up with procedure:
* - can't rely on bg_stripes; line count, threshold, etc., will need to happen here
* - line count will always be the largest multiple of 6 smaller than height; c = h - (h % 6)
* - chevrons may have larger widths: TODO calc
* - depth will be funky; line depth will need to use "full" depth; (Df - Dl) / Wc = Ic (TODO verify?)
* - switch stripe index on *absolute* line number rather than n
* - chevron building will be BLOCK.repeat(width) + TRIANGLE_21[0] (fg Ic, bg Ic + 1)
* - chevrons[len - 1] will need unique handling to draw stripes
*/ */
let stripe_index = 0; // set up constraints
let chevron_index = 5; // chevrons are funky :) let linecount = height - (height % 6); // largest multiple of 6 smaller than height
let full_depth = linecount / 2;
let corner = linecount % 2 == 1;
let chevron_width = 0; // chevron width (TODO)
let thresh = height / linecount; // stripe threshold; no bg_stripes call!
let mut line_no = 0; // absolute line number; n is relative
// piecewise functions: ascent -> peak -> descent
for n in 0..full_depth {
// advance stripe color at stripe threshold by line number
if line_no != 0 && line_no % thresh == 0 { stripe_index += 1; }
// init current line
let line = String::new();
draw::lines(lines, !small); // get this line's depth?
exit(0); // get chevron start: (full_depth - line_depth) / chevron_width = chevron_start
// for chevron_index in chevron_start..5
// if chevron_index = 4, draw stripe after (stripe width = width - line_depth - 1)
// else, draw <fg:chevron_index,bg:chevron_index+1>BLOCK.repeat(chevron_width) + TRIANGLE_21[0]
lines.push(line);
line_no += 1;
}
if corner {
if line_no % thresh == 0 { stripe_index += 1; }
let line = String::new();
lines.push(line);
line_no += 1;
}
for n in 0..full_depth {
if line_no % thresh == 0 { stripe_index += 1; }
let line = String::new();
lines.push(line);
line_no += 1;
}
Flag::Lines(lines)
} }
// everything below this point is in alphabetical order // everything below this point is in alphabetical order
@ -80,6 +125,7 @@ fn demi_orientation_render(middle: Bg<Rgb>, bottom: Bg<Rgb>, width: u16, height:
let linecount = lines.len(); let linecount = lines.len();
let depth = linecount / 2; let depth = linecount / 2;
let corner = linecount % 2 == 1; let corner = linecount % 2 == 1;
// piecewise functions: ascending -> peak -> descending
for n in 0..depth { for n in 0..depth {
let line = lines[n].clone(); let line = lines[n].clone();
@ -104,26 +150,24 @@ fn demi_orientation_render(middle: Bg<Rgb>, bottom: Bg<Rgb>, width: u16, height:
lines lines
} }
pub fn demiromantic(small: bool) -> Colors { pub fn demiromantic(small: bool) -> Flag {
let green = bg(0x3DA542); let green = bg(0x3DA542);
let gray = bg(0xD2D2D2); let gray = bg(0xD2D2D2);
let (width, height) = if small { (15, 5) } else { terminal_size().unwrap() }; let (width, height) = if small { (15, 5) } else { terminal_size().unwrap() };
let lines = demi_orientation_render(green, gray, width, height); let lines = demi_orientation_render(green, gray, width, height);
draw::lines(lines, !small); Flag::Lines(lines)
exit(0);
} }
pub fn demisexual(small: bool) -> Colors { pub fn demisexual(small: bool) -> Flag {
let purple = bg(0x832FA8); let purple = bg(0x832FA8);
let grey = bg(0x7B868C); let grey = bg(0x7B868C);
let (width, height) = if small { (15, 5) } else { terminal_size().unwrap() }; let (width, height) = if small { (15, 5) } else { terminal_size().unwrap() };
let lines = demi_orientation_render(purple, grey, width, height); let lines = demi_orientation_render(purple, grey, width, height);
draw::lines(lines, !small); Flag::Lines(lines)
exit(0);
} }
pub fn disability() { pub fn disability() {
@ -138,9 +182,10 @@ pub fn disability() {
let stripes = [red, yellow, white, blue, green]; let stripes = [red, yellow, white, blue, green];
// 2/3 slant stripes with gray background // 2/3 slant stripes with gray background
} }
pub fn intersex() -> Colors { pub fn intersex() -> Flag {
let yellow = bg(0xFFDA00); let yellow = bg(0xFFDA00);
let purple = rgb(0x7A00AC); let purple = rgb(0x7A00AC);
@ -154,8 +199,7 @@ pub fn intersex() -> Colors {
format!("{stripe}") format!("{stripe}")
]; ];
draw::lines(lines, false); Flag::Lines(lines)
exit(0);
} }
pub fn polyamorous() { pub fn polyamorous() {

View file

@ -62,7 +62,7 @@ pub fn small(colors: Colors) {
stdout.flush().ok(); stdout.flush().ok();
} }
pub fn lines(lines: Vec<String>, hold: bool) { pub fn draw_lines(lines: Vec<String>, hold: bool) {
let mut stdout = io::stdout().into_raw_mode().unwrap(); let mut stdout = io::stdout().into_raw_mode().unwrap();
let count = lines.len() as u16; let count = lines.len() as u16;
@ -133,3 +133,27 @@ pub fn bg_stripes(colors: Vec<Bg<Rgb>>, width: u16, height: u16) -> Vec<String>
output output
} }
pub enum Flag {
Stripes(Colors),
Lines(Vec<String>)
}
impl Flag {
pub fn draw(self, hold: bool) {
let lines = match self {
Flag::Stripes(colors)
=> {
let (width, height);
if hold { (width, height) = terminal_size().unwrap(); }
else {
height = colors.len() as u16;
width = height * 3;
}
fg_stripes(colors, width, height)
},
Flag::Lines(lines)
=> lines
};
draw_lines(lines, hold);
}
}

View file

@ -1,7 +1,8 @@
use crate::color::*; use crate::color::*;
use crate::draw::Flag;
pub fn pride() -> Colors { pub fn pride() -> Flag {
let red = rgb(0xE50000); let red = rgb(0xE50000);
let orange = rgb(0xFF8D00); let orange = rgb(0xFF8D00);
let yellow = rgb(0xFFEE00); let yellow = rgb(0xFFEE00);
@ -9,108 +10,108 @@ pub fn pride() -> Colors {
let blue = rgb(0x004CFF); let blue = rgb(0x004CFF);
let purple = rgb(0x770088); let purple = rgb(0x770088);
vec![red, orange, yellow, green, blue, purple] Flag::Stripes(vec![red, orange, yellow, green, blue, purple])
} }
pub fn transgender() -> Colors { pub fn transgender() -> Flag {
let pink = rgb(0x7ACBF5); let pink = rgb(0x7ACBF5);
let blue = rgb(0xEAACB8); let blue = rgb(0xEAACB8);
vec![pink, blue, WHITE, blue, pink] Flag::Stripes(vec![pink, blue, WHITE, blue, pink])
} }
// everything below here is alphabetical // everything below here is alphabetical
pub fn agender() -> Colors { pub fn agender() -> Flag {
let gray = rgb(0xB9B9B9); let gray = rgb(0xB9B9B9);
let green = rgb(0xB8F483); let green = rgb(0xB8F483);
vec![BLACK, gray, WHITE, green, WHITE, gray, BLACK] Flag::Stripes(vec![BLACK, gray, WHITE, green, WHITE, gray, BLACK])
} }
pub fn aromantic() -> Colors { pub fn aromantic() -> Flag {
let green = rgb(0x3BA740); let green = rgb(0x3BA740);
let lime = rgb(0xA8D47A); let lime = rgb(0xA8D47A);
let grey = rgb(0xABABAB); let grey = rgb(0xABABAB);
vec![green, lime, WHITE, grey, BLACK] Flag::Stripes(vec![green, lime, WHITE, grey, BLACK])
} }
pub fn asexual() -> Colors { pub fn asexual() -> Flag {
let grey = rgb(0xA4A4A4); let grey = rgb(0xA4A4A4);
let purple = rgb(0x810081); let purple = rgb(0x810081);
vec![BLACK, grey, WHITE, purple] Flag::Stripes(vec![BLACK, grey, WHITE, purple])
} }
pub fn bigender() -> Colors { pub fn bigender() -> Flag {
let pink = rgb(0xE676A6); let pink = rgb(0xE676A6);
let yellow = rgb(0xF9F04C); let yellow = rgb(0xF9F04C);
let purple = rgb(0xAB6BBB); let purple = rgb(0xAB6BBB);
let blue = rgb(0x6D96DC); let blue = rgb(0x6D96DC);
vec![pink, yellow, WHITE, purple, blue] Flag::Stripes(vec![pink, yellow, WHITE, purple, blue])
} }
pub fn bisexual() -> Colors { pub fn bisexual() -> Flag {
let magenta = rgb(0xC42A6F); let magenta = rgb(0xC42A6F);
let purple = rgb(0x915392); let purple = rgb(0x915392);
let blue = rgb(0x1437A2); let blue = rgb(0x1437A2);
vec![magenta, magenta, purple, blue, blue] Flag::Stripes(vec![magenta, magenta, purple, blue, blue])
} }
pub fn genderfluid() -> Colors { pub fn genderfluid() -> Flag {
let pink = rgb(0xFF75A2); let pink = rgb(0xFF75A2);
let violet = rgb(0xBE18D6); let violet = rgb(0xBE18D6);
let blue = rgb(0x333EBD); let blue = rgb(0x333EBD);
vec![pink, WHITE, violet, BLACK, blue] Flag::Stripes(vec![pink, WHITE, violet, BLACK, blue])
} }
pub fn genderqueer() -> Colors { pub fn genderqueer() -> Flag {
let purple = rgb(0xB899DF); let purple = rgb(0xB899DF);
let green = rgb(0x6B8E3B); let green = rgb(0x6B8E3B);
vec![purple, WHITE, green] Flag::Stripes(vec![purple, WHITE, green])
} }
pub fn gendervoid() -> Colors { pub fn gendervoid() -> Flag {
let navy = rgb(0x08114A); let navy = rgb(0x08114A);
let gray = rgb(0x4A484B); let gray = rgb(0x4A484B);
vec![navy, gray, BLACK, gray, navy] Flag::Stripes(vec![navy, gray, BLACK, gray, navy])
} }
pub fn lesbian() -> Colors { pub fn lesbian() -> Flag {
let red = rgb(0xD62800); let red = rgb(0xD62800);
let orange = rgb(0xFF9B56); let orange = rgb(0xFF9B56);
let pink = rgb(0xD462A6); let pink = rgb(0xD462A6);
let magenta = rgb(0xA40062); let magenta = rgb(0xA40062);
vec![red, orange, WHITE, pink, magenta] Flag::Stripes(vec![red, orange, WHITE, pink, magenta])
} }
pub fn multigender() -> Colors { pub fn multigender() -> Flag {
let blue = rgb(0x3F47CC); let blue = rgb(0x3F47CC);
let ltblue = rgb(0x01A4E9); let ltblue = rgb(0x01A4E9);
let orange = rgb(0xFB7F27); let orange = rgb(0xFB7F27);
vec![blue, ltblue, orange, ltblue, blue] Flag::Stripes(vec![blue, ltblue, orange, ltblue, blue])
} }
pub fn nonbinary() -> Colors { pub fn nonbinary() -> Flag {
let yellow = rgb(0xFFF433); let yellow = rgb(0xFFF433);
let purple = rgb(0x9B59D0); let purple = rgb(0x9B59D0);
vec![yellow, WHITE, purple, BLACK] Flag::Stripes(vec![yellow, WHITE, purple, BLACK])
} }
pub fn pansexual() -> Colors { pub fn pansexual() -> Flag {
let magenta = rgb(0xFF1B8D); let magenta = rgb(0xFF1B8D);
let yellow = rgb(0xFFDA00); let yellow = rgb(0xFFDA00);
let cyan = rgb(0x1BB3FF); let cyan = rgb(0x1BB3FF);
vec![magenta, yellow, cyan] Flag::Stripes(vec![magenta, yellow, cyan])
} }

View file

@ -8,7 +8,7 @@ mod draw;
mod flag; mod flag;
mod variant; mod variant;
use crate::color::Colors; use crate::draw::Flag;
static VERSION: &str = env!("CARGO_PKG_VERSION"); static VERSION: &str = env!("CARGO_PKG_VERSION");
@ -38,7 +38,7 @@ fn main() {
let subcommand = args.subcommand().unwrap(); let subcommand = args.subcommand().unwrap();
let colors: Colors = match subcommand.as_deref() { let flag: Flag = match subcommand.as_deref() {
Some("pride" | "gay") Some("pride" | "gay")
=> { => {
let variant = args.subcommand().unwrap_or(None); let variant = args.subcommand().unwrap_or(None);
@ -115,8 +115,7 @@ fn main() {
_ => { help_text(); exit(1) } _ => { help_text(); exit(1) }
}; };
if small { draw::small(colors); } flag.draw(!small);
else { draw::full(colors); }
} }

View file

@ -1,10 +1,11 @@
use crate::{ use crate::{
color::*, color::*,
draw::Flag,
flag flag
}; };
pub fn gilbert_baker() -> Colors { pub fn gilbert_baker() -> Flag {
let pink = rgb(0xFF69B4); // sex let pink = rgb(0xFF69B4); // sex
let red = rgb(0xFF0000); // life let red = rgb(0xFF0000); // life
let orange = rgb(0xFF8F00); // healing let orange = rgb(0xFF8F00); // healing
@ -14,16 +15,22 @@ pub fn gilbert_baker() -> Colors {
let indigo = rgb(0x3E0099); // serenity let indigo = rgb(0x3E0099); // serenity
let purple = rgb(0x8F008F); // spirit let purple = rgb(0x8F008F); // spirit
vec![pink, red, orange, yellow, green, cyan, indigo, purple] Flag::Stripes(vec![pink, red, orange, yellow, green, cyan, indigo, purple])
} }
pub fn philadelphia() -> Colors { pub fn philadelphia() -> Flag {
let brown = rgb(0x784F17); let brown = rgb(0x784F17);
let mut output = flag::pride(); let base = flag::pride();
output.insert(0, BLACK); let mut colors = match base {
output.insert(1, brown); Flag::Stripes(inner)
=> inner,
_
=> { panic!("impossible enum variant"); }
};
colors.insert(0, BLACK);
colors.insert(1, brown);
output Flag::Stripes(colors)
} }