1use std::fs::File;
2use std::hash::{Hash, Hasher};
3use std::io::{self, Read, Write};
4use crate::buffer::{Buffer, BufferError};
6
7trait Serialisable<T> {
8 fn serialise(&self) -> Result<Buffer, BufferError>;
10 fn deserialise(data: &mut Buffer) -> Result<T, BufferError>;
12}
13
14#[derive(Debug, PartialEq)]
15pub struct Session {
16 pub date: String,
17 pub location: String,
18 pub rounds: Vec<Round>,
21}
22
23#[derive(Debug)]
24pub enum FileError {
25 BufferError(BufferError),
26 IOError(io::Error),
27}
28
29impl From<BufferError> for FileError {
30 fn from(err: BufferError) -> Self {
31 Self::BufferError(err)
32 }
33}
34
35impl From<io::Error> for FileError {
36 fn from(err: io::Error) -> Self {
37 Self::IOError(err)
38 }
39}
40
41impl Session {
42 pub fn encode(&self, filename: String) -> Result<(), FileError> {
43 let mut res = Buffer::new();
44
45 res.append_u8(0x4f); res.append_u8(0x41); res.append_u8(0x46); res.append_u8(0x46); res.append_u8(0); res.append_u8(1); res.append_u8(0); let mut data = self.serialise()?;
57
58 res.append_u64(data.length() as u64);
59 res.append(&mut data);
60
61 let mut f = File::create(filename)?;
62 Ok(f.write_all(res.take_underlying_buffer().as_slice())?)
63 }
64
65 pub fn decode(filename: String) -> Result<Self, FileError> {
66 let mut f = File::open(filename)?;
67
68 let mut data = vec![];
69
70 f.read_to_end(&mut data)?;
71
72 let mut buf = Buffer::from(data);
73 buf.pop_n_bytes(4)?;
74
75 let v1 = buf.pop_u8()?;
76 let v2 = buf.pop_u8()?;
77 let v3 = buf.pop_u8()?;
78
79 println!("Encoded with v{v1}.{v2}.{v3}");
80
81 println!("Session has length {:?}", buf.pop_u64()?);
82
83 Ok(Session::deserialise(&mut buf)?)
84 }
85}
86
87impl Serialisable<Session> for Session {
88 fn serialise(&self) -> Result<Buffer, BufferError> {
89 let mut res = Buffer::new();
90
91 res.append_string(&self.date)?;
92
93 res.append_string(&self.location)?;
94
95 res.append_usize(self.rounds.len())?;
96 for round in &self.rounds {
97 res.append(&mut round.serialise()?);
98 }
99
100 Ok(res)
101 }
102
103 fn deserialise(data: &mut Buffer) -> Result<Self, BufferError> {
104 let date = data.pop_string()?;
105 let location = data.pop_string()?;
106
107 let mut rounds = vec![];
108 let read = data.pop_usize()?;
109
110 for _ in 0..read {
111 rounds.push(Round::deserialise(data)?);
112 }
113
114 Ok(Session {
115 date,
116 location,
117 rounds,
118 })
119 }
120}
121
122#[derive(Debug, PartialEq)]
123pub struct Round {
124 pub name: String,
125 pub targets: Vec<Target>,
126}
127
128impl Serialisable<Round> for Round {
129 fn serialise(&self) -> Result<Buffer, BufferError> {
130 let mut res = Buffer::new();
131
132 res.append_string(&self.name)?;
133
134 res.append_usize(self.targets.len())?;
135 for target in &self.targets {
136 res.append(&mut target.serialise()?);
137 }
138
139 Ok(res)
140 }
141
142 fn deserialise(data: &mut Buffer) -> Result<Self, BufferError> {
143 let name = data.pop_string()?;
144
145 let mut targets = vec![];
146 let read = data.pop_usize()?;
147
148 for _ in 0..read {
149 targets.push(Target::deserialise(data)?);
150 }
151
152 Ok(Round {
153 name,
154 targets,
155 })
156 }
157}
158
159#[derive(Debug, PartialEq)]
160pub struct Target {
161 pub name: String,
162 pub distance: u32,
163 pub distance_unit: String,
164 pub face_size: u32,
165 pub face_size_unit: String,
166 pub inclination: u32,
167 pub ends: Vec<End>,
168}
169
170impl Serialisable<Target> for Target {
171 fn serialise(&self) -> Result<Buffer, BufferError> {
172 let mut res = Buffer::new();
173
174 res.append_string(&self.name)?;
175
176 res.append_u32(self.distance);
177 res.append_string(&self.distance_unit)?;
178
179 res.append_u32(self.face_size);
180 res.append_string(&self.face_size_unit)?;
181
182 res.append_u32(self.inclination);
183
184 res.append_usize(self.ends.len())?;
185 for end in &self.ends {
186 res.append(&mut end.serialise()?);
187 }
188
189 Ok(res)
190 }
191
192 fn deserialise(data: &mut Buffer) -> Result<Self, BufferError> {
193 let name = data.pop_string()?;
194
195 let dist = data.pop_u32()?;
196 let dist_unit = data.pop_string()?;
197
198 let face = data.pop_u32()?;
199 let face_unit = data.pop_string()?;
200
201 let inclination = data.pop_u32()?;
202
203 let mut ends = vec![];
204 let read = data.pop_usize()?;
205
206 for _ in 0..read {
207 ends.push(End::deserialise(data)?);
208 }
209
210 Ok(Target {
211 name,
212 distance: dist,
213 distance_unit: dist_unit,
214 face_size: face,
215 face_size_unit: face_unit,
216 inclination,
217 ends,
218 })
219 }
220}
221
222#[derive(Debug, PartialEq)]
223pub enum End {
224 Scored(Vec<ValueScore>),
225 Measured(Vec<MeasuredScore>),
226 Blank(u32),
227 ShotTrainer(u32),
228 BareShaft(Vec<BareShaft>),
229 BowDraws(u32),
230}
231
232impl Serialisable<End> for End {
233 fn serialise(&self) -> Result<Buffer, BufferError> {
234 Ok(match self {
235 End::Scored(scores) => {
236 let mut res = Buffer::from(vec![0]);
237
238 res.append_usize(scores.len())?;
239 for score in scores {
240 res.append(&mut score.serialise()?);
241 }
242
243 res
244 },
245 End::Measured(scores) => {
246 let mut res = Buffer::from(vec![1]);
247
248 res.append_usize(scores.len())?;
249 for score in scores {
250 res.append(&mut score.serialise()?);
251 }
252
253 res
254 },
255 End::Blank(count) => {
256 let mut res = Buffer::from(vec![2]);
257
258 res.append_u32(*count);
259
260 res
261 },
262 End::ShotTrainer(count) => {
263 let mut res = Buffer::from(vec![3]);
264
265 res.append_u32(*count);
266
267 res
268 },
269 End::BareShaft(scores) => {
270 let mut res = Buffer::from(vec![4]);
271
272 res.append_usize(scores.len())?;
273 for score in scores {
274 res.append(&mut score.serialise()?);
275 }
276
277 res
278 },
279 End::BowDraws(count) => {
280 let mut res = Buffer::from(vec![5]);
281
282 res.append_u32(*count);
283
284 res
285 },
286 })
287 }
288
289 fn deserialise(data: &mut Buffer) -> Result<Self, BufferError> {
290 let t = data.pop_u8()?;
291 Ok(match t {
292 0 => {
293 let mut scores = vec![];
294 let read = data.pop_usize()?;
295
296 for _ in 0..read {
297 let s = ValueScore::deserialise(data)?;
298 scores.push(s);
299 }
300
301 End::Scored(scores)
302 },
303 1 => {
304 let mut scores = vec![];
305 let read = data.pop_usize()?;
306
307 for _ in 0..read {
308 let s = MeasuredScore::deserialise(data)?;
309 scores.push(s);
310 }
311
312 End::Measured(scores)
313 },
314 2 => {
315 End::Blank(data.pop_u32()?)
316 },
317 3 => {
318 End::ShotTrainer(data.pop_u32()?)
319 },
320 4 => {
321 let mut scores = vec![];
322 let read = data.pop_usize()?;
323
324 for _ in 0..read {
325 let s = BareShaft::deserialise(data)?;
326 scores.push(s);
327 }
328
329 End::BareShaft(scores)
330 },
331 5 => {
332 End::BowDraws(data.pop_u32()?)
333 },
334 other => {
335 panic!("unknown end type: {}", other)
336 }
337 })
338 }
339}
340
341#[derive(Debug, PartialEq)]
342pub struct ValueScore {
343 pub value: u8,
344 pub value_name: String,
345}
346
347#[derive(Debug, PartialEq)]
348pub struct MeasuredScore {
349 pub value: u8,
350 pub value_name: String,
351 pub r: u32,
352 pub theta: u32,
353}
354
355#[derive(Debug, PartialEq)]
356pub struct BareShaft {
357 pub r: u32,
358 pub theta: u32,
359}
360
361impl Serialisable<ValueScore> for ValueScore {
362 fn serialise(&self) -> Result<Buffer, BufferError> {
363 let mut res = Buffer::from(vec![self.value]);
364
365 res.append_string(&self.value_name)?;
366
367 Ok(res)
368 }
369
370 fn deserialise(data: &mut Buffer) -> Result<Self, BufferError> {
371 Ok(Self {
372 value: data.pop_u8()?,
373 value_name: data.pop_string()?,
374 })
375 }
376}
377
378impl Serialisable<MeasuredScore> for MeasuredScore {
379 fn serialise(&self) -> Result<Buffer, BufferError> {
380 let mut res = Buffer::from(vec![self.value]);
381
382 res.append_string(&self.value_name)?;
383
384 res.append_u32(self.r);
385 res.append_u32(self.theta);
386
387 Ok(res)
388 }
389
390 fn deserialise(data: &mut Buffer) -> Result<Self, BufferError> {
391 Ok(Self {
392 value: data.pop_u8()?,
393 value_name: data.pop_string()?,
394 r: data.pop_u32()?,
395 theta: data.pop_u32()?,
396 })
397 }
398}
399
400impl Serialisable<BareShaft> for BareShaft {
401 fn serialise(&self) -> Result<Buffer, BufferError> {
402 let mut res = Buffer::from(vec![]);
403
404 res.append_u32(self.r);
405 res.append_u32(self.theta);
406
407 Ok(res)
408 }
409
410 fn deserialise(data: &mut Buffer) -> Result<Self, BufferError> {
411 Ok(Self {
412 r: data.pop_u32()?,
413 theta: data.pop_u32()?,
414 })
415 }
416}
417
418
419#[cfg(test)]
420mod tests {
421 use super::*;
422
423 #[test]
424 fn test_files() {
425 let s = Session {
426 date: "2024-01-02".to_string(),
427 location: "Home".to_string(),
428 rounds: vec![
429 Round {
430 name: "Portsmouth".to_string(),
431 targets: vec![
432 Target {
433 name: "WA 60cm Indoor".to_string(),
434 distance: 18,
435 distance_unit: "m".to_string(),
436 face_size: 60,
437 face_size_unit: "cm".to_string(),
438 inclination: 0,
439 ends: vec![
440 End::Scored(vec![
441 ValueScore {
442 value: 10,
443 value_name: "ten".to_string(),
444 },
445 ValueScore {
446 value: 10,
447 value_name: "ten".to_string(),
448 },
449 ValueScore {
450 value: 10,
451 value_name: "ten".to_string(),
452 },
453 ])
454 ],
455 }
456 ],
457 }
458 ],
459 };
460
461 s.encode("tmp.oaf".to_string()).unwrap();
462
463 let decoded_s = Session::decode("tmp.oaf".to_string()).unwrap();
464
465 assert_eq!(s, decoded_s)
466 }
467
468 #[test]
469 fn test_full() {
470 let s = Session {
471 date: "4/12/2023".to_string(),
472 location: "St Andrews".to_string(),
473 rounds: vec![
474 Round {
475 name: "Portsmouth".to_string(),
476 targets: vec![
477 Target {
478 name: "WA 60cm Indoor".to_string(),
479 distance: 18,
480 distance_unit: "m".to_string(),
481 face_size: 60,
482 face_size_unit: "cm".to_string(),
483 inclination: 0,
484 ends: vec![
485 End::Scored(vec![
486 ValueScore {
487 value: 10,
488 value_name: "10".to_string(),
489 },
490 ValueScore {
491 value: 10,
492 value_name: "10".to_string(),
493 },
494 ValueScore {
495 value: 9,
496 value_name: "9".to_string(),
497 }
498 ]),
499 End::Scored(vec![
500 ValueScore {
501 value: 10,
502 value_name: "10".to_string(),
503 },
504 ValueScore {
505 value: 9,
506 value_name: "9".to_string(),
507 },
508 ValueScore {
509 value: 9,
510 value_name: "9".to_string(),
511 }
512 ])
513 ],
514 }
515 ],
516 }
517 ],
518 };
519
520 assert_eq!(s, Session::deserialise(&mut s.serialise().unwrap()).unwrap())
521 }
522
523 #[test]
524 fn test_measured_score_serialise() {
525 let data = MeasuredScore {
526 value: 7,
527 value_name: "seven".to_string(),
528 r: 255,
529 theta: 6000,
530 }.serialise().unwrap();
531 assert_eq!(
532 data,
533 vec![7, 5, 0, 115, 101, 118, 101, 110, 255, 0, 0, 0, 112, 23, 0, 0]
534 )
535 }
536
537 #[test]
538 fn test_measured_score_deserialise() {
539 let data = MeasuredScore::deserialise(&mut Buffer::from(vec![7, 5, 0, 115, 101, 118, 101, 110, 255, 0, 0, 0, 112, 23, 0, 0])).unwrap();
540 let s = MeasuredScore {
541 value: 7,
542 value_name: "seven".to_string(),
543 r: 255,
544 theta: 6000,
545 };
546 assert_eq!(
547 data,
548 s,
549 )
550 }
551
552 #[test]
553 fn test_value_score_serialise() {
554 let data = ValueScore {
555 value: 7,
556 value_name: "seven".to_string(),
557 }.serialise().unwrap();
558 assert_eq!(
559 data,
560 vec![7, 5, 0, 115, 101, 118, 101, 110]
561 )
562 }
563
564 #[test]
565 fn test_value_score_deserialise() {
566 let data = ValueScore::deserialise(&mut Buffer::from(vec![7, 5, 0, 115, 101, 118, 101, 110])).unwrap();
567 let s = ValueScore {
568 value: 7,
569 value_name: "seven".to_string(),
570 };
571 assert_eq!(
572 data,
573 s,
574 )
575 }
576
577 #[test]
578 fn test_measured_end_serialise() {
579 let data = End::Measured( vec![
580 MeasuredScore {
581 value: 7,
582 value_name: "seven".to_string(),
583 r: 255,
584 theta: 6000,
585 },
586 MeasuredScore {
587 value: 6,
588 value_name: "six".to_string(),
589 r: 1000,
590 theta: 3000,
591 },
592 MeasuredScore {
593 value: 5,
594 value_name: "five".to_string(),
595 r: 1500,
596 theta: 50,
597 }
598 ] ).serialise().unwrap();
599 assert_eq!(
600 data,
601 vec![1, 3, 0,
602 7, 5, 0, 115, 101, 118, 101, 110, 255, 0, 0, 0, 112, 23, 0, 0,
603 6, 3, 0, 115, 105, 120, 232, 3, 0, 0, 184, 11, 0, 0,
604 5, 4, 0, 102, 105, 118, 101, 220, 5, 0, 0, 50, 0, 0, 0,
605 ]
606 )
607 }
608
609 #[test]
610 fn test_measured_end_deserialise() {
611 let data = End::deserialise(
612 &mut Buffer::from(
613 vec![1, 3, 0,
614 7, 5, 0, 115, 101, 118, 101, 110, 255, 0, 0, 0, 112, 23, 0, 0,
615 6, 3, 0, 115, 105, 120, 232, 3, 0, 0, 184, 11, 0, 0,
616 5, 4, 0, 102, 105, 118, 101, 220, 5, 0, 0, 50, 0, 0, 0,
617 ]
618 )).unwrap();
619 let s = End::Measured( vec![
620 MeasuredScore {
621 value: 7,
622 value_name: "seven".to_string(),
623 r: 255,
624 theta: 6000,
625 },
626 MeasuredScore {
627 value: 6,
628 value_name: "six".to_string(),
629 r: 1000,
630 theta: 3000,
631 },
632 MeasuredScore {
633 value: 5,
634 value_name: "five".to_string(),
635 r: 1500,
636 theta: 50,
637 }
638 ] );
639 assert_eq!(
640 data,
641 s,
642 )
643 }
644 #[test]
645 fn test_value_end_serialise() {
646 let data = End::Scored( vec![
647 ValueScore {
648 value: 7,
649 value_name: "seven".to_string(),
650 },
651 ValueScore {
652 value: 6,
653 value_name: "six".to_string(),
654 },
655 ValueScore {
656 value: 5,
657 value_name: "five".to_string(),
658 }
659 ] ).serialise().unwrap();
660 assert_eq!(
661 data,
662 vec![0, 3, 0,
663 7, 5, 0, 115, 101, 118, 101, 110,
664 6, 3, 0, 115, 105, 120,
665 5, 4, 0, 102, 105, 118, 101,
666 ]
667 )
668 }
669
670 #[test]
671 fn test_value_end_deserialise() {
672 let data = End::deserialise(
673 &mut Buffer::from(
674 vec![0, 3, 0,
675 7, 5, 0, 115, 101, 118, 101, 110,
676 6, 3, 0, 115, 105, 120,
677 5, 4, 0, 102, 105, 118, 101,
678 ]
679 )).unwrap();
680 let s = End::Scored( vec![
681 ValueScore {
682 value: 7,
683 value_name: "seven".to_string(),
684 },
685 ValueScore {
686 value: 6,
687 value_name: "six".to_string(),
688 },
689 ValueScore {
690 value: 5,
691 value_name: "five".to_string(),
692 }
693 ] );
694 assert_eq!(
695 data,
696 s,
697 )
698 }
699}