use serde::{Deserialize, Serialize}; use crate::marble_engine::{ grid::{Grid, ResizeDeltas}, pos::Pos, tile::Tile, }; #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct Comment { text: String, pos: Pos, } #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(from = "CompatBoard")] pub struct Board { pub grid: Grid, pub comments: Vec, } #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] enum CompatBoard { V1(String), V2 { grid: Grid, comments: Vec }, } impl From for Board { fn from(value: CompatBoard) -> Self { match value { CompatBoard::V1(string) => Self { grid: Grid::parse(&string), comments: Vec::new(), }, CompatBoard::V2 { grid, comments } => Self { grid, comments }, } } } impl Default for Board { fn default() -> Self { Self { grid: Grid::new_single(Tile::BLANK), comments: Vec::new(), } } } impl Board { pub fn new(grid: Grid) -> Self { Self { grid, comments: Vec::new(), } } pub fn single_tile(tile: Tile) -> Self { Self { grid: Grid::new_single(tile), comments: Vec::new(), } } pub fn get_rect(&self, pos: Pos, width: usize, height: usize) -> Self { // TODO filter for comments in the area let comments = self.comments.clone(); Self { grid: self.grid.get_rect(pos, width, height), comments, } } pub fn paste_board(&mut self, pos: Pos, board: &Board) { // TODO remove overlapping comments self.grid.paste_grid(pos, &board.grid); self.comments.extend_from_slice(&board.comments); } pub fn grow(&mut self, deltas: &ResizeDeltas) { self.grid.grow(deltas); // TODO adjust comments } pub fn shrink(&mut self, deltas: &ResizeDeltas) { self.grid.shrink(deltas); // TODO adjust comments } pub fn from_user_str(source: &str) -> Self { serde_json::from_str(source).unwrap_or_else(|_| Self { grid: Grid::parse(source), comments: Vec::new(), }) } pub fn width(&self) -> usize { self.grid.width() } pub fn height(&self) -> usize { self.grid.height() } }