use serde_json;
use termcolor;
use self::termcolor::{BufferedStandardStream, ColorChoice, ColorSpec, WriteColor};
use crate::board::Board;
use crate::error::Result;
use std::collections::HashMap;
use std::io::Write;
pub fn draw_term(board: &Board<'_>, show_altitude: bool) -> Result<()> {
let stdout = &mut BufferedStandardStream::stdout(ColorChoice::Always);
let mut prev = ColorSpec::default();
let mut legends = HashMap::new();
for row in board.rows() {
for cell in row.iter() {
if prev != cell.color {
stdout.set_color(&cell.color)?;
prev = cell.color.clone();
}
if show_altitude {
write!(stdout, "{:02}", cell.altitude)?;
} else {
write!(stdout, "{}", cell.char)?;
}
legends.entry(cell.kind.legend()).or_insert(cell);
}
writeln!(stdout)?;
}
let term_width = board.width() * 2; let mut width = usize::max_value();
for (legend, cell) in legends.iter() {
let legend_len = cell.char.chars().count() + 3 + legend.len();
if width.saturating_add(legend_len) > term_width {
write!(stdout, "\n ")?;
width = 2 + legend_len;
} else {
write!(stdout, ", ")?;
width += 2 + legend_len;
}
stdout.set_color(&cell.color)?;
write!(stdout, "{}", cell.char)?;
stdout.reset()?;
write!(stdout, " : {}", legend)?;
}
writeln!(stdout)?;
Ok(())
}
pub fn draw_json<W: Write>(writer: &mut W, board: &Board<'_>) -> Result<()> {
serde_json::to_writer(writer, &board)?;
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use crate::board::Board;
use crate::land::LandKind;
#[test]
fn draw_1x1_board_as_json() {
let b = Board::build(1, 1, |_, _| LandKind::Forest.preset(50));
let mut buf = Vec::<u8>::new();
draw_json(&mut buf, &b).unwrap();
let expect: serde_json::Value = serde_json::from_str(
r##"{
"width": 1,
"height": 1,
"cells": [
[
{
"kind": "Forest",
"char": "██",
"color": {
"fg": "#005f00",
"bg": null,
"bold": false,
"underline": false,
"intense": false
},
"altitude": 50
}
]
],
"legends": {
"Forest": "Forest"
}
}"##,
)
.unwrap();
let actual: serde_json::Value =
serde_json::from_str(std::str::from_utf8(&buf).unwrap()).unwrap();
assert_eq!(expect, actual);
}
}