beamtrace/
lib.rs

1pub mod geometry;
2
3use std::path::Path;
4use std::error::Error;
5use std::fs::File;
6use std::io::{Read,Write,BufWriter,BufReader};
7use serde::{Serialize,Deserialize};
8
9pub use crate::geometry::{point,rectangle,Point,Rectangle};
10
11pub type Color = u16;
12
13#[derive(Debug,Clone,Serialize,Deserialize)]
14pub enum Command {
15    Points{ color:Color,points:Vec<Point> },
16    Lines{ color:Color,lines:Vec<Vec<Point>> }
17}
18
19#[derive(Debug,Clone,Serialize,Deserialize)]
20pub struct Plot {
21    pub commands:Vec<Command>
22}
23
24#[derive(Debug,Clone,Serialize,Deserialize)]
25pub struct Page {
26    pub plots:Vec<Plot>
27}
28
29#[derive(Debug,Clone,Serialize,Deserialize)]
30pub struct Book {
31    pub pages:Vec<Page>
32}
33
34impl Command {
35    pub fn line(color:Color,p1:Point,p2:Point)->Command {
36	Self::Lines{ color,lines:vec![vec![p1,p2]] }
37    }
38
39    pub fn rectangle(color:Color,Rectangle{ a:p0,b:p1 }:Rectangle)->Command {
40	Self::Lines{ color, lines:vec![vec![p0,p0.with_x(p1),p1,p1.with_x(p0),p0]] }
41    }
42}
43
44impl Page {
45    pub fn new()->Self {
46	Self{ plots:Vec::new() }
47    }
48
49    pub fn len(&self)->usize {
50	self.plots.len()
51    }
52
53    pub fn is_empty(&self)->bool {
54	self.plots.is_empty()
55    }
56
57    pub fn plot(&mut self,pl:Plot) {
58	self.plots.push(pl);
59    }
60
61    pub fn get_plot(&self,k:isize)->Option<&Plot> {
62	let m = self.len();
63	if m == 0 {
64	    None
65	} else {
66	    let i = k.rem_euclid(m as isize) as usize;
67	    Some(&self.plots[i])
68	}
69    }
70}
71
72impl Default for Page {
73    fn default()->Self {
74	Self::new()
75    }
76}
77
78impl Plot {
79    pub fn new()->Self {
80	Self{ commands:Vec::new() }
81    }
82
83    pub fn point(&mut self,color:Color,p:Point) {
84	self.command(Command::Points{ color,points:vec![p] });
85    }
86
87    pub fn line(&mut self,color:Color,p1:Point,p2:Point) {
88	self.command(Command::Lines{ color,lines:vec![vec![p1,p2]] });
89    }
90
91    pub fn lines(&mut self,color:Color,lines:Vec<Vec<Point>>) {
92	self.command(Command::Lines{ color,lines });
93    }
94
95    pub fn rectangle(&mut self,color:Color,Rectangle{ a:p0,b:p1 }:Rectangle) {
96	self.lines(color,vec![vec![p0,p0.with_x(p1),p1,p1.with_x(p0),p0]]);
97    }
98
99    pub fn command(&mut self,cmd:Command) {
100	self.commands.push(cmd);
101    }
102
103    pub fn bounding(&self)->Rectangle {
104	let mut r = Rectangle::empty();
105	for cmd in self.commands.iter() {
106	    match cmd {
107		Command::Points{ points, .. } => {
108		    for &p in points.iter() {
109			r.add_point(p);
110		    }
111		},
112		Command::Lines{ lines, .. } => {
113		    for line in lines.iter() {
114			for &p in line.iter() {
115			    r.add_point(p);
116			}
117		    }
118		}
119	    }
120	}
121	r
122    }
123}
124
125impl Default for Plot {
126    fn default()->Self {
127	Self::new()
128    }
129}
130
131impl Book {
132    pub fn new()->Self {
133	Self{ pages:Vec::new() }
134    }
135
136    pub fn write<W:Write>(&self,w:&mut W)->Result<(),Box<dyn Error>> {
137	self.serialize(&mut rmp_serde::Serializer::new(w))?;
138	Ok(())
139    }
140
141    pub fn read<R:Read>(r:&mut R)->Result<Self,Box<dyn Error>> {
142	let this : Self = rmp_serde::decode::from_read(r)?;
143	Ok(this)
144    }
145
146    pub fn save_to_file<P:AsRef<Path>>(&self,path:P)->Result<(),Box<dyn Error>> {
147	let fd = File::create(path)?;
148	let mut buf = BufWriter::new(fd);
149	self.write(&mut buf)
150    }
151
152    pub fn load_from_file<P:AsRef<Path>>(path:P)->Result<Self,Box<dyn Error>> {
153	let fd = File::open(path)?;
154	let mut buf = BufReader::new(fd);
155	Self::read(&mut buf)
156    }
157
158    pub fn get_page(&self,k:isize)->Option<&Page> {
159	let m = self.pages.len();
160	if m == 0 {
161	    None
162	} else {
163	    let i = k.rem_euclid(m as isize) as usize;
164	    Some(&self.pages[i])
165	}
166    }
167
168    pub fn page(&mut self,page:Page) {
169	self.pages.push(page);
170    }
171}
172
173impl Default for Book {
174    fn default()->Self {
175	Self::new()
176    }
177}