pub mod geometry;
use std::path::Path;
use std::error::Error;
use std::fs::File;
use std::io::{Read,Write,BufWriter,BufReader};
use serde::{Serialize,Deserialize};
pub use crate::geometry::{point,rectangle,Point,Rectangle};
pub type Color = u16;
#[derive(Debug,Clone,Serialize,Deserialize)]
pub enum Command {
Points{ color:Color,points:Vec<Point> },
Lines{ color:Color,lines:Vec<Vec<Point>> }
}
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct Plot {
pub commands:Vec<Command>
}
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct Page {
pub plots:Vec<Plot>
}
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct Book {
pub pages:Vec<Page>
}
impl Command {
pub fn line(color:Color,p1:Point,p2:Point)->Command {
Self::Lines{ color,lines:vec![vec![p1,p2]] }
}
pub fn rectangle(color:Color,Rectangle{ a:p0,b:p1 }:Rectangle)->Command {
Self::Lines{ color, lines:vec![vec![p0,p0.with_x(p1),p1,p1.with_x(p0),p0]] }
}
}
impl Page {
pub fn new()->Self {
Self{ plots:Vec::new() }
}
pub fn len(&self)->usize {
self.plots.len()
}
pub fn is_empty(&self)->bool {
self.plots.is_empty()
}
pub fn plot(&mut self,pl:Plot) {
self.plots.push(pl);
}
pub fn get_plot(&self,k:isize)->Option<&Plot> {
let m = self.len();
if m == 0 {
None
} else {
let i = k.rem_euclid(m as isize) as usize;
Some(&self.plots[i])
}
}
}
impl Default for Page {
fn default()->Self {
Self::new()
}
}
impl Plot {
pub fn new()->Self {
Self{ commands:Vec::new() }
}
pub fn point(&mut self,color:Color,p:Point) {
self.command(Command::Points{ color,points:vec![p] });
}
pub fn line(&mut self,color:Color,p1:Point,p2:Point) {
self.command(Command::Lines{ color,lines:vec![vec![p1,p2]] });
}
pub fn lines(&mut self,color:Color,lines:Vec<Vec<Point>>) {
self.command(Command::Lines{ color,lines });
}
pub fn rectangle(&mut self,color:Color,Rectangle{ a:p0,b:p1 }:Rectangle) {
self.lines(color,vec![vec![p0,p0.with_x(p1),p1,p1.with_x(p0),p0]]);
}
pub fn command(&mut self,cmd:Command) {
self.commands.push(cmd);
}
pub fn bounding(&self)->Rectangle {
let mut r = Rectangle::empty();
for cmd in self.commands.iter() {
match cmd {
Command::Points{ points, .. } => {
for &p in points.iter() {
r.add_point(p);
}
},
Command::Lines{ lines, .. } => {
for line in lines.iter() {
for &p in line.iter() {
r.add_point(p);
}
}
}
}
}
r
}
}
impl Default for Plot {
fn default()->Self {
Self::new()
}
}
impl Book {
pub fn new()->Self {
Self{ pages:Vec::new() }
}
pub fn write<W:Write>(&self,w:&mut W)->Result<(),Box<dyn Error>> {
self.serialize(&mut rmp_serde::Serializer::new(w))?;
Ok(())
}
pub fn read<R:Read>(r:&mut R)->Result<Self,Box<dyn Error>> {
let this : Self = rmp_serde::decode::from_read(r)?;
Ok(this)
}
pub fn save_to_file<P:AsRef<Path>>(&self,path:P)->Result<(),Box<dyn Error>> {
let fd = File::create(path)?;
let mut buf = BufWriter::new(fd);
self.write(&mut buf)
}
pub fn load_from_file<P:AsRef<Path>>(path:P)->Result<Self,Box<dyn Error>> {
let fd = File::open(path)?;
let mut buf = BufReader::new(fd);
Self::read(&mut buf)
}
pub fn get_page(&self,k:isize)->Option<&Page> {
let m = self.pages.len();
if m == 0 {
None
} else {
let i = k.rem_euclid(m as isize) as usize;
Some(&self.pages[i])
}
}
pub fn page(&mut self,page:Page) {
self.pages.push(page);
}
}
impl Default for Book {
fn default()->Self {
Self::new()
}
}