use std::convert::{From, Into, TryFrom}; #[derive(Debug)] pub struct Pixmap { pub width: u32, pub height: u32, pub data: Vec, } #[derive(Copy, Clone, Debug)] pub struct MapPoint { pub x: u32, pub y: u32, } impl From<(u32, u32)> for MapPoint { fn from((x, y): (u32, u32)) -> MapPoint { MapPoint { x, y } } } impl TryFrom<(i32, i32)> for MapPoint { type Error = (); fn try_from((x, y): (i32, i32)) -> Result { if x < 0 || y < 0 { return Err(()); } else { Ok(MapPoint { x: x as u32, y: y as u32, }) } } } impl TryFrom<(i64, i64)> for MapPoint { type Error = (); fn try_from((x, y): (i64, i64)) -> Result { if x < 0 || y < 0 { return Err(()); } else { Ok(MapPoint { x: x as u32, y: y as u32, }) } } } impl Pixmap where T: Copy + Clone + Default, { pub fn new(width: u32, height: u32) -> Self { let data = vec![Default::default(); (width * height) as usize]; Pixmap { width, height, data, } } pub fn new_with(width: u32, height: u32, start: T) -> Self { let data = vec![start; (width * height) as usize]; Pixmap { width, height, data, } } pub fn is_inside>(&self, pt: P) -> bool { let MapPoint { x, y } = pt.into(); x < self.width && y < self.height } pub fn idx>(&self, pt: P) -> usize { let MapPoint { x, y } = pt.into(); (y * self.width + x) as usize } pub fn get>(&self, pt: P) -> T { let idx = self.idx(pt); self.data[idx] } pub fn set>(&mut self, pt: P, new_val: T) -> T { let pt = pt.into(); let old_val = self.get(pt); let idx = self.idx(pt); self.data[idx] = new_val; old_val } }