Skip to main content

wallrnd/
log.rs

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}