libmactime2/bodyfile/
bodyfile_decoder.rs1use crate::{Filter, Joinable, RunOptions, Provider, Consumer};
2use std::sync::mpsc::{self, Sender, Receiver};
3use std::thread::{JoinHandle};
4use bodyfile::Bodyfile3Line;
5use std::convert::TryFrom;
6
7pub struct BodyfileDecoder {
8 worker: Option<JoinHandle<()>>,
9 rx: Option<Receiver<Bodyfile3Line>>,
10}
11
12impl Filter<String, Bodyfile3Line, ()> for BodyfileDecoder {
13 fn worker(reader: Receiver<String>, tx: Sender<Bodyfile3Line>, options: RunOptions) {
14 loop {
15 let mut line = match reader.recv() {
16 Err(_) => {break;}
17 Ok(l) => l
18 };
19
20 if line.starts_with('#') { continue; }
21 Self::trim_newline(&mut line);
22
23 let bf_line = match Bodyfile3Line::try_from(line.as_ref()) {
24 Err(e) => {
25 if options.strict_mode {
26 log::warn!("bodyfile parser error: {}", e);
27 panic!("failed while parsing: {:?}", line);
28 } else {
29 log::warn!("bodyfile parser error: {}", e);
30 #[cfg(debug_assertions)]
31 log::warn!("failed line was: {:?}", line);
32 }
33 continue;
34 }
35 Ok(l) => l
36 };
37
38 if tx.send(bf_line).is_err() {
39 break;
40 }
41 }
42 }
43}
44
45impl Provider<Bodyfile3Line, ()> for BodyfileDecoder {
46 fn get_receiver(&mut self) -> Receiver<Bodyfile3Line> {
47 self.rx.take().unwrap()
48 }
49
50}
51
52impl Consumer<String> for BodyfileDecoder {
53 fn with_receiver(reader: Receiver<String>, options: RunOptions) -> Self {
54 let (tx, rx): (Sender<Bodyfile3Line>, Receiver<Bodyfile3Line>) = mpsc::channel();
55 Self {
56 worker: Some(std::thread::spawn(move || {
57 Self::worker(reader, tx, options)
58 })),
59 rx: Some(rx),
60 }
61 }
62}
63
64impl BodyfileDecoder {
65 fn trim_newline(s: &mut String) {
66 if s.ends_with('\n') {
67 s.pop();
68 if s.ends_with('\r') {
69 s.pop();
70 }
71 }
72 }
73}
74
75impl Joinable<()> for BodyfileDecoder {
76 fn join(&mut self) -> std::thread::Result<()> {
77 self.worker.take().unwrap().join()
78 }
79}