This repository was archived by the owner on Jul 21, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 30
Expand file tree
/
Copy pathapplication.rs
More file actions
112 lines (95 loc) · 3.17 KB
/
application.rs
File metadata and controls
112 lines (95 loc) · 3.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use chrono_tz::Tz;
use clap::ValueEnum;
use clio::Input;
use strum_macros::Display;
use crate::output::{OldCsvOutput, RecordOutput};
use super::bodyfile::{BodyfileDecoder, BodyfileReader, BodyfileSorter};
use super::cli::Cli;
use super::error::MactimeError;
use super::filter::{Consumer, Joinable, Provider, RunOptions, Sorter};
use super::output::{CsvOutput, TxtOutput};
use super::stream::StreamReader;
#[derive(ValueEnum, Clone, Display)]
enum InputFormat {
#[strum(serialize = "bodyfile")]
Bodyfile,
}
#[derive(ValueEnum, Clone, Display)]
pub(crate) enum OutputFormat {
/// Comma-Separated Values compliant to RFC 4180
#[strum(serialize = "csv")]
Csv,
/// legacy text format, inherited from the old mactime
#[strum(serialize = "txt")]
Txt,
/// flow.record format used by `dissect` and `rdump`
#[strum(serialize = "record")]
Record,
/// Use the old (non RFC compliant) CSV format that was used by legacy mactime.
#[strum(serialize = "old-csv")]
OldCsv,
}
pub struct Mactime2Application {
format: OutputFormat,
bodyfile: Input,
dst_zone: Tz,
show_headers: bool,
strict_mode: bool,
}
impl Mactime2Application {
fn create_sorter(
&self,
decoder: &mut BodyfileDecoder,
) -> Box<dyn Sorter<Result<(), MactimeError>>> {
let options = RunOptions {
strict_mode: self.strict_mode,
};
let mut sorter = BodyfileSorter::default().with_receiver(decoder.get_receiver(), options);
sorter = sorter.with_output(match self.format {
OutputFormat::OldCsv => Box::new(OldCsvOutput::new(std::io::stdout(), self.dst_zone)),
OutputFormat::Csv => Box::new(CsvOutput::new(
std::io::stdout(),
self.dst_zone,
self.show_headers,
)),
OutputFormat::Txt => Box::new(TxtOutput::new(std::io::stdout(), self.dst_zone)),
OutputFormat::Record => Box::new(RecordOutput::new(std::io::stdout(), self.dst_zone)),
_ => panic!("invalid execution path"),
});
Box::new(sorter)
}
pub fn run(&self) -> anyhow::Result<()> {
let options = RunOptions {
strict_mode: self.strict_mode,
};
let mut reader = <BodyfileReader as StreamReader<String, ()>>::from(self.bodyfile.clone())?;
let mut decoder = BodyfileDecoder::with_receiver(reader.get_receiver(), options);
let mut sorter = self.create_sorter(&mut decoder);
sorter.run();
let _ = reader.join();
let _ = decoder.join();
sorter.join().unwrap()?;
Ok(())
}
}
impl From<Cli> for Mactime2Application {
fn from(cli: Cli) -> Self {
let format = match cli.output_format {
Some(f) => f,
None => {
if cli.csv_format {
OutputFormat::Csv
} else {
OutputFormat::Txt
}
}
};
Self {
format,
bodyfile: cli.input_file,
dst_zone: cli.dst_zone.into_tz().unwrap(),
show_headers: cli.show_headers,
strict_mode: cli.strict_mode,
}
}
}