1use crate::prelude::*;
2use crate::scene::*;
3use std::fmt;
4use std::fs::File;
5use std::io::{Read, Write};
6use std::rc::Rc;
7
8pub struct Logger {
9 pub frame: Frame,
10 pub bg: ColorItem,
11 pub objects: Vec<Rc<dyn Contains>>,
12}
13
14impl fmt::Display for Frame {
15 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
16 write!(f, "{} {} {} {} #", self.x, self.y, self.w, self.h)
17 }
18}
19
20impl fmt::Display for ColorItem {
21 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
22 write!(f, "{} {} {} ", self.shade.0, self.shade.1, self.shade.2)?;
23 write!(f, "{} {} {} ", self.theme.0, self.theme.1, self.theme.2)?;
24 write!(f, "{} ", self.salt)?;
25 write!(f, "{} {} #", self.deviation, self.distance)
26 }
27}
28
29impl fmt::Display for SaltItem {
30 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
31 write!(f, "{} {} {} ", self.color.0, self.color.1, self.color.2)?;
32 write!(f, "{} {} ", self.likeliness, self.variability)
33 }
34}
35
36impl fmt::Display for Salt {
37 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
38 for item in self.0.iter() {
39 write!(f, "{} ", item)?;
40 }
41 write!(f, "#")
42 }
43}
44
45impl fmt::Display for Disc {
46 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
47 write!(
48 f,
49 "Disc {} {} {} ",
50 self.center.0, self.center.1, self.radius
51 )?;
52 write!(f, "{} #", self.color)
53 }
54}
55
56impl fmt::Display for HalfPlane {
57 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
58 write!(
59 f,
60 "HalfPlane {} {} {} {} ",
61 self.limit.0, self.limit.1, self.reference.0, self.reference.1
62 )?;
63 write!(f, "{} #", self.color)
64 }
65}
66
67impl fmt::Display for Triangle {
68 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
69 write!(f, "Triangle {} {} ", self.a.0, self.a.1)?;
70 write!(f, "{} {} ", self.b.0, self.b.1)?;
71 write!(f, "{} {} ", self.c.0, self.c.1)?;
72 write!(f, "{} #", self.color)
73 }
74}
75
76impl fmt::Display for Spiral {
77 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
78 write!(
79 f,
80 "Spiral {} {} {} {} ",
81 self.center.0, self.center.1, self.width, self.tightness
82 )?;
83 write!(f, "{} #", self.color)
84 }
85}
86
87impl fmt::Display for Stripe {
88 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
89 write!(
90 f,
91 "Stripe {} {} {} {} ",
92 self.limit.0, self.limit.1, self.reference.0, self.reference.1
93 )?;
94 write!(f, "{} #", self.color)
95 }
96}
97
98impl fmt::Display for Wave {
99 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
100 write!(
101 f,
102 "Wave {} {} {} {} ",
103 self.limit.0, self.limit.1, self.reference.0, self.reference.1
104 )?;
105 write!(f, "{} {} ", self.amplitude, self.frequency)?;
106 write!(f, "{} #", self.color)
107 }
108}
109
110impl fmt::Display for Sawtooth {
111 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
112 write!(
113 f,
114 "Sawtooth {} {} {} {} ",
115 self.limit.0, self.limit.1, self.reference.0, self.reference.1
116 )?;
117 write!(f, "{} {} ", self.amplitude, self.frequency)?;
118 write!(f, "{} #", self.color)
119 }
120}
121
122impl fmt::Display for Logger {
123 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
124 write!(f, "{} ", self.frame)?;
125 write!(f, "{} ", self.bg)?;
126 write!(f, "{} ", self.objects.len())?;
127 for o in &self.objects {
128 write!(f, "{} ", o)?;
129 }
130 Ok(())
131 }
132}
133
134impl Logger {
135 pub fn save(&self, dest: &str) -> std::io::Result<()> {
136 let mut buffer = File::create(dest)?;
137 buffer.write_all(&format!("{}", &self).into_bytes())
138 }
139
140 pub fn load(src: &str) -> Self {
141 let mut s = String::new();
142 let mut file = File::open(src).unwrap();
143 file.read_to_string(&mut s).unwrap();
144 let mut items = s.split(' ');
145 Logger::restore(&mut items)
146 }
147}
148
149trait Restore {
150 fn restore<'a>(items: &mut impl Iterator<Item = &'a str>) -> Self;
151}
152
153impl Restore for usize {
154 fn restore<'a>(items: &mut impl Iterator<Item = &'a str>) -> Self {
155 items.next().unwrap().parse::<Self>().unwrap()
156 }
157}
158
159impl Restore for f64 {
160 fn restore<'a>(items: &mut impl Iterator<Item = &'a str>) -> Self {
161 items.next().unwrap().parse::<Self>().unwrap()
162 }
163}
164
165impl Restore for Pos {
166 fn restore<'a>(items: &mut impl Iterator<Item = &'a str>) -> Self {
167 Self(f64::restore(items), f64::restore(items))
168 }
169}
170
171impl Restore for Color {
172 fn restore<'a>(items: &mut impl Iterator<Item = &'a str>) -> Self {
173 Self(
174 usize::restore(items),
175 usize::restore(items),
176 usize::restore(items),
177 )
178 }
179}
180
181impl Restore for Logger {
182 fn restore<'a>(items: &mut impl Iterator<Item = &'a str>) -> Self {
183 let frame = Frame::restore(items);
184 let bg = ColorItem::restore(items);
185 let len = items.next().unwrap().parse::<usize>().unwrap();
186 let mut objects = Vec::new();
187 for _ in 0..len {
188 objects.push(match items.next().unwrap() {
189 "Disc" => Rc::new(Disc::restore(items)) as Rc<dyn Contains>,
190 "HalfPlane" => Rc::new(HalfPlane::restore(items)) as Rc<dyn Contains>,
191 "Stripe" => Rc::new(Stripe::restore(items)) as Rc<dyn Contains>,
192 "Triangle" => Rc::new(Triangle::restore(items)) as Rc<dyn Contains>,
193 "Spiral" => Rc::new(Spiral::restore(items)) as Rc<dyn Contains>,
194 "Wave" => Rc::new(Wave::restore(items)) as Rc<dyn Contains>,
195 "Sawtooth" => Rc::new(Sawtooth::restore(items)) as Rc<dyn Contains>,
196 _ => panic!("Unknown item"),
197 });
198 }
199 Self { frame, bg, objects }
200 }
201}
202
203impl Restore for Frame {
204 fn restore<'a>(items: &mut impl Iterator<Item = &'a str>) -> Self {
205 let x = usize::restore(items);
206 let y = usize::restore(items);
207 let w = usize::restore(items);
208 let h = usize::restore(items);
209 assert_eq!(items.next().unwrap(), "#");
210 Self { x, y, w, h }
211 }
212}
213
214impl Restore for Salt {
215 fn restore<'a>(items: &mut impl Iterator<Item = &'a str>) -> Self {
216 let nb = usize::restore(items);
217 let mut salt = Salt::default();
218 for _ in 0..nb {
219 salt.0.push(SaltItem::restore(items));
220 }
221 assert_eq!(items.next().unwrap(), "#");
222 salt
223 }
224}
225
226impl Restore for SaltItem {
227 fn restore<'a>(items: &mut impl Iterator<Item = &'a str>) -> Self {
228 let color = Color::restore(items);
229 let likeliness = f64::restore(items);
230 let variability = usize::restore(items);
231 Self {
232 color,
233 likeliness,
234 variability,
235 }
236 }
237}
238
239impl Restore for ColorItem {
240 fn restore<'a>(items: &mut impl Iterator<Item = &'a str>) -> Self {
241 let shade = Color::restore(items);
242 let theme = Color::restore(items);
243 let salt = Salt::restore(items);
244 let deviation = usize::restore(items);
245 let distance = usize::restore(items);
246 assert_eq!(items.next().unwrap(), "#");
247 Self {
248 shade,
249 theme,
250 deviation,
251 distance,
252 salt,
253 }
254 }
255}
256
257impl Restore for Disc {
258 fn restore<'a>(items: &mut impl Iterator<Item = &'a str>) -> Self {
259 let center = Pos::restore(items);
260 let radius = f64::restore(items);
261 let color = ColorItem::restore(items);
262 assert_eq!(items.next().unwrap(), "#");
263 Self {
264 center,
265 radius,
266 color,
267 }
268 }
269}
270
271impl Restore for HalfPlane {
272 fn restore<'a>(items: &mut impl Iterator<Item = &'a str>) -> Self {
273 let limit = Pos::restore(items);
274 let reference = Pos::restore(items);
275 let color = ColorItem::restore(items);
276 assert_eq!(items.next().unwrap(), "#");
277 Self {
278 limit,
279 reference,
280 color,
281 }
282 }
283}
284
285impl Restore for Stripe {
286 fn restore<'a>(items: &mut impl Iterator<Item = &'a str>) -> Self {
287 let limit = Pos::restore(items);
288 let reference = Pos::restore(items);
289 let color = ColorItem::restore(items);
290 assert_eq!(items.next().unwrap(), "#");
291 Self {
292 limit,
293 reference,
294 color,
295 }
296 }
297}
298
299impl Restore for Triangle {
300 fn restore<'a>(items: &mut impl Iterator<Item = &'a str>) -> Self {
301 let a = Pos::restore(items);
302 let b = Pos::restore(items);
303 let c = Pos::restore(items);
304 let color = ColorItem::restore(items);
305 assert_eq!(items.next().unwrap(), "#");
306 Self { a, b, c, color }
307 }
308}
309
310impl Restore for Spiral {
311 fn restore<'a>(items: &mut impl Iterator<Item = &'a str>) -> Self {
312 let center = Pos::restore(items);
313 let width = f64::restore(items);
314 let tightness = f64::restore(items);
315 let color = ColorItem::restore(items);
316 assert_eq!(items.next().unwrap(), "#");
317 Self {
318 center,
319 width,
320 color,
321 tightness,
322 }
323 }
324}
325
326impl Restore for Wave {
327 fn restore<'a>(items: &mut impl Iterator<Item = &'a str>) -> Self {
328 let limit = Pos::restore(items);
329 let reference = Pos::restore(items);
330 let amplitude = f64::restore(items);
331 let frequency = f64::restore(items);
332 let color = ColorItem::restore(items);
333 assert_eq!(items.next().unwrap(), "#");
334 Self {
335 limit,
336 reference,
337 amplitude,
338 frequency,
339 color,
340 }
341 }
342}
343
344impl Restore for Sawtooth {
345 fn restore<'a>(items: &mut impl Iterator<Item = &'a str>) -> Self {
346 let limit = Pos::restore(items);
347 let reference = Pos::restore(items);
348 let amplitude = f64::restore(items);
349 let frequency = f64::restore(items);
350 let color = ColorItem::restore(items);
351 assert_eq!(items.next().unwrap(), "#");
352 Self {
353 limit,
354 reference,
355 amplitude,
356 frequency,
357 color,
358 }
359 }
360}