Refactor visualize.
This commit is contained in:
		
							parent
							
								
									5a6be3194e
								
							
						
					
					
						commit
						0c1345053b
					
				
					 3 changed files with 189 additions and 181 deletions
				
			
		|  | @ -1,181 +0,0 @@ | |||
| use std::collections::HashMap; | ||||
| 
 | ||||
| use std::io::Write; | ||||
| use termcolor::{ColorSpec, StandardStream, WriteColor}; | ||||
| 
 | ||||
| use crate::prelude::*; | ||||
| 
 | ||||
| pub trait Visualize { | ||||
|     fn visualize(&self) -> Visualization; | ||||
| 
 | ||||
|     fn print_visualization(&self) { | ||||
|         let v = self.visualize(); | ||||
| 
 | ||||
|         let stdout = &mut StandardStream::stdout(termcolor::ColorChoice::Always); | ||||
| 
 | ||||
|         let width_digits = (v.size.x - 1).ilog10() + 1; | ||||
|         let height_digits = (v.size.y - 1).ilog10() + 1; | ||||
| 
 | ||||
|         // print header
 | ||||
|         for i in 0..width_digits { | ||||
|             let d = width_digits - i - 1; | ||||
| 
 | ||||
|             //padding
 | ||||
|             for _ in 0..height_digits { | ||||
|                 write!(stdout, " ").unwrap(); | ||||
|             } | ||||
| 
 | ||||
|             for x in 0..v.size.x { | ||||
|                 let digits = x / (i32::pow(10, d)); | ||||
|                 if digits == 0 && d > 0 { | ||||
|                     write!(stdout, " ").unwrap(); | ||||
|                 } else { | ||||
|                     write!( | ||||
|                         stdout, | ||||
|                         "{}", | ||||
|                         char::from_u32((digits % 10) as u32 + 48).unwrap() | ||||
|                     ) | ||||
|                     .unwrap(); | ||||
|                 } | ||||
|             } | ||||
|             writeln!(stdout).unwrap(); | ||||
|         } | ||||
| 
 | ||||
|         for y in 0..v.size.y { | ||||
|             write!(stdout, "{:1$}", y, height_digits as usize).unwrap(); | ||||
| 
 | ||||
|             for x in 0..v.size.x { | ||||
|                 if let Some((s, fg, bg)) = v.symbols.get(&Position::new(x, y)) { | ||||
|                     let mut c = ColorSpec::new(); | ||||
|                     c.set_fg(fg.as_ref().map(|c| termcolor::Color::Rgb(c.r, c.g, c.b))); | ||||
|                     c.set_bg(bg.as_ref().map(|c| termcolor::Color::Rgb(c.r, c.g, c.b))); | ||||
|                     stdout.set_color(&c).unwrap(); | ||||
|                     write!(stdout, "{:1}", s.get_str()).unwrap(); | ||||
|                     stdout.reset().unwrap(); | ||||
|                 } else { | ||||
|                     write!(stdout, " ").unwrap(); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             writeln!(stdout, "{:1$}", y, height_digits as usize).unwrap(); | ||||
|         } | ||||
| 
 | ||||
|         for i in 0..width_digits { | ||||
|             let d = width_digits - i - 1; | ||||
| 
 | ||||
|             //padding
 | ||||
|             for _ in 0..height_digits { | ||||
|                 write!(stdout, " ").unwrap(); | ||||
|             } | ||||
| 
 | ||||
|             for x in 0..v.size.x { | ||||
|                 let digits = x / (i32::pow(10, d)); | ||||
|                 if digits == 0 && d > 0 { | ||||
|                     write!(stdout, " ").unwrap(); | ||||
|                 } else { | ||||
|                     write!( | ||||
|                         stdout, | ||||
|                         "{}", | ||||
|                         char::from_u32((digits % 10) as u32 + 48).unwrap() | ||||
|                     ) | ||||
|                     .unwrap(); | ||||
|                 } | ||||
|             } | ||||
|             writeln!(stdout).unwrap(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub enum Symbol { | ||||
|     Arrow(Direction), | ||||
|     ArrowEnter(Direction), | ||||
|     ArrowExit(Direction), | ||||
|     Char(&'static str), | ||||
|     Block, | ||||
|     Space, | ||||
| } | ||||
| 
 | ||||
| impl Symbol { | ||||
|     fn get_str(&self) -> &'static str { | ||||
|         match self { | ||||
|             Symbol::Arrow(dir) => match dir { | ||||
|                 Direction::Up => "↑", | ||||
|                 Direction::Right => "→", | ||||
|                 Direction::Down => "↓", | ||||
|                 Direction::Left => "←", | ||||
|             }, | ||||
|             Symbol::ArrowEnter(dir) => match dir { | ||||
|                 Direction::Up => "↟", | ||||
|                 Direction::Right => "↠", | ||||
|                 Direction::Down => "↡", | ||||
|                 Direction::Left => "↞", | ||||
|             }, | ||||
|             Symbol::ArrowExit(dir) => match dir { | ||||
|                 Direction::Up => "↥", | ||||
|                 Direction::Right => "↦", | ||||
|                 Direction::Down => "↧", | ||||
|                 Direction::Left => "↤", | ||||
|             }, | ||||
|             Symbol::Char(c) => c.split_at(1).0, | ||||
|             Symbol::Block => "#", | ||||
|             Symbol::Space => " ", | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn get_char(&self) -> char { | ||||
|         self.get_str().chars().next().unwrap() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct Visualization { | ||||
|     size: Position, | ||||
|     symbols: HashMap<Position, (Symbol, Option<Color>, Option<Color>)>, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone, Copy)] | ||||
| pub struct Color { | ||||
|     r: u8, | ||||
|     g: u8, | ||||
|     b: u8, | ||||
| } | ||||
| 
 | ||||
| impl Color { | ||||
|     pub fn new(r: u8, g: u8, b: u8) -> Self { | ||||
|         Self { r, g, b } | ||||
|     } | ||||
| 
 | ||||
|     pub fn index(i: usize) -> Self { | ||||
|         let c = [ | ||||
|             Color::new(0xe6, 0x00, 0x49), | ||||
|             Color::new(0x0b, 0xb4, 0xff), | ||||
|             Color::new(0x50, 0xe9, 0x91), | ||||
|             Color::new(0xe6, 0xd8, 0x00), | ||||
|             Color::new(0x9b, 0x19, 0xf5), | ||||
|             Color::new(0xff, 0xa3, 0x00), | ||||
|             Color::new(0xdc, 0x0a, 0xb4), | ||||
|             Color::new(0xb3, 0xd4, 0xff), | ||||
|             Color::new(0x00, 0xbf, 0xa0), | ||||
|         ]; | ||||
| 
 | ||||
|         c[i % c.len()] | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Visualization { | ||||
|     pub fn new(size: Position) -> Self { | ||||
|         Self { | ||||
|             size, | ||||
|             symbols: HashMap::new(), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn add_symbol( | ||||
|         &mut self, | ||||
|         pos: Position, | ||||
|         symbol: Symbol, | ||||
|         fg: Option<Color>, | ||||
|         bg: Option<Color>, | ||||
|     ) { | ||||
|         self.symbols.insert(pos, (symbol, fg, bg)); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										108
									
								
								src/common/visualize/mod.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								src/common/visualize/mod.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,108 @@ | |||
| mod print; | ||||
| 
 | ||||
| use std::collections::HashMap; | ||||
| 
 | ||||
| use crate::prelude::*; | ||||
| 
 | ||||
| pub trait Visualize { | ||||
|     fn visualize(&self) -> Visualization; | ||||
| 
 | ||||
|     fn print_visualization(&self) { | ||||
|         let v = self.visualize(); | ||||
|         print::print(v); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub enum Symbol { | ||||
|     Arrow(Direction), | ||||
|     ArrowEnter(Direction), | ||||
|     ArrowExit(Direction), | ||||
|     Char(&'static str), | ||||
|     Block, | ||||
|     Space, | ||||
| } | ||||
| 
 | ||||
| impl Symbol { | ||||
|     fn get_str(&self) -> &'static str { | ||||
|         match self { | ||||
|             Symbol::Arrow(dir) => match dir { | ||||
|                 Direction::Up => "↑", | ||||
|                 Direction::Right => "→", | ||||
|                 Direction::Down => "↓", | ||||
|                 Direction::Left => "←", | ||||
|             }, | ||||
|             Symbol::ArrowEnter(dir) => match dir { | ||||
|                 Direction::Up => "↟", | ||||
|                 Direction::Right => "↠", | ||||
|                 Direction::Down => "↡", | ||||
|                 Direction::Left => "↞", | ||||
|             }, | ||||
|             Symbol::ArrowExit(dir) => match dir { | ||||
|                 Direction::Up => "↥", | ||||
|                 Direction::Right => "↦", | ||||
|                 Direction::Down => "↧", | ||||
|                 Direction::Left => "↤", | ||||
|             }, | ||||
|             Symbol::Char(c) => c.split_at(1).0, | ||||
|             Symbol::Block => "#", | ||||
|             Symbol::Space => " ", | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // fn get_char(&self) -> char {
 | ||||
|     //     self.get_str().chars().next().unwrap()
 | ||||
|     // }
 | ||||
| } | ||||
| 
 | ||||
| pub struct Visualization { | ||||
|     size: Position, | ||||
|     symbols: HashMap<Position, (Symbol, Option<Color>, Option<Color>)>, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone, Copy)] | ||||
| pub struct Color { | ||||
|     r: u8, | ||||
|     g: u8, | ||||
|     b: u8, | ||||
| } | ||||
| 
 | ||||
| impl Color { | ||||
|     pub fn new(r: u8, g: u8, b: u8) -> Self { | ||||
|         Self { r, g, b } | ||||
|     } | ||||
| 
 | ||||
|     pub fn index(i: usize) -> Self { | ||||
|         let c = [ | ||||
|             Color::new(0xe6, 0x00, 0x49), | ||||
|             Color::new(0x0b, 0xb4, 0xff), | ||||
|             Color::new(0x50, 0xe9, 0x91), | ||||
|             Color::new(0xe6, 0xd8, 0x00), | ||||
|             Color::new(0x9b, 0x19, 0xf5), | ||||
|             Color::new(0xff, 0xa3, 0x00), | ||||
|             Color::new(0xdc, 0x0a, 0xb4), | ||||
|             Color::new(0xb3, 0xd4, 0xff), | ||||
|             Color::new(0x00, 0xbf, 0xa0), | ||||
|         ]; | ||||
| 
 | ||||
|         c[i % c.len()] | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Visualization { | ||||
|     pub fn new(size: Position) -> Self { | ||||
|         Self { | ||||
|             size, | ||||
|             symbols: HashMap::new(), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn add_symbol( | ||||
|         &mut self, | ||||
|         pos: Position, | ||||
|         symbol: Symbol, | ||||
|         fg: Option<Color>, | ||||
|         bg: Option<Color>, | ||||
|     ) { | ||||
|         self.symbols.insert(pos, (symbol, fg, bg)); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										81
									
								
								src/common/visualize/print.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								src/common/visualize/print.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,81 @@ | |||
| use super::Visualization; | ||||
| 
 | ||||
| use std::io::Write; | ||||
| use termcolor::{ColorSpec, StandardStream, WriteColor}; | ||||
| 
 | ||||
| use crate::prelude::*; | ||||
| 
 | ||||
| pub(super) fn print(v: Visualization) { | ||||
|     let stdout = &mut StandardStream::stdout(termcolor::ColorChoice::Always); | ||||
| 
 | ||||
|     let width_digits = (v.size.x - 1).ilog10() + 1; | ||||
|     let height_digits = (v.size.y - 1).ilog10() + 1; | ||||
| 
 | ||||
|     // print header
 | ||||
|     for i in 0..width_digits { | ||||
|         let d = width_digits - i - 1; | ||||
| 
 | ||||
|         //padding
 | ||||
|         for _ in 0..height_digits { | ||||
|             write!(stdout, " ").unwrap(); | ||||
|         } | ||||
| 
 | ||||
|         for x in 0..v.size.x { | ||||
|             let digits = x / (i32::pow(10, d)); | ||||
|             if digits == 0 && d > 0 { | ||||
|                 write!(stdout, " ").unwrap(); | ||||
|             } else { | ||||
|                 write!( | ||||
|                     stdout, | ||||
|                     "{}", | ||||
|                     char::from_u32((digits % 10) as u32 + 48).unwrap() | ||||
|                 ) | ||||
|                 .unwrap(); | ||||
|             } | ||||
|         } | ||||
|         writeln!(stdout).unwrap(); | ||||
|     } | ||||
| 
 | ||||
|     for y in 0..v.size.y { | ||||
|         write!(stdout, "{:1$}", y, height_digits as usize).unwrap(); | ||||
| 
 | ||||
|         for x in 0..v.size.x { | ||||
|             if let Some((s, fg, bg)) = v.symbols.get(&Position::new(x, y)) { | ||||
|                 let mut c = ColorSpec::new(); | ||||
|                 c.set_fg(fg.as_ref().map(|c| termcolor::Color::Rgb(c.r, c.g, c.b))); | ||||
|                 c.set_bg(bg.as_ref().map(|c| termcolor::Color::Rgb(c.r, c.g, c.b))); | ||||
|                 stdout.set_color(&c).unwrap(); | ||||
|                 write!(stdout, "{:1}", s.get_str()).unwrap(); | ||||
|                 stdout.reset().unwrap(); | ||||
|             } else { | ||||
|                 write!(stdout, " ").unwrap(); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         writeln!(stdout, "{:1$}", y, height_digits as usize).unwrap(); | ||||
|     } | ||||
| 
 | ||||
|     for i in 0..width_digits { | ||||
|         let d = width_digits - i - 1; | ||||
| 
 | ||||
|         //padding
 | ||||
|         for _ in 0..height_digits { | ||||
|             write!(stdout, " ").unwrap(); | ||||
|         } | ||||
| 
 | ||||
|         for x in 0..v.size.x { | ||||
|             let digits = x / (i32::pow(10, d)); | ||||
|             if digits == 0 && d > 0 { | ||||
|                 write!(stdout, " ").unwrap(); | ||||
|             } else { | ||||
|                 write!( | ||||
|                     stdout, | ||||
|                     "{}", | ||||
|                     char::from_u32((digits % 10) as u32 + 48).unwrap() | ||||
|                 ) | ||||
|                 .unwrap(); | ||||
|             } | ||||
|         } | ||||
|         writeln!(stdout).unwrap(); | ||||
|     } | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue