Skip to content

Commit 27555a8

Browse files
committed
rust: bear modes are represented in types
1 parent 1b15d5e commit 27555a8

File tree

1 file changed

+99
-88
lines changed

1 file changed

+99
-88
lines changed

rust/bear/src/bin/bear.rs

Lines changed: 99 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -43,27 +43,38 @@ fn main() -> anyhow::Result<ExitCode> {
4343

4444
/// Represent the application state.
4545
enum Application {
46-
/// The intercept mode we are only capturing the build commands.
47-
Intercept {
48-
input: args::BuildCommand,
49-
output: args::BuildEvents,
50-
config: config::Intercept,
51-
},
52-
/// The semantic mode we are deduct the semantic meaning of the
53-
/// executed commands from the build process.
54-
Semantic {
55-
event_source: EventFileReader,
56-
semantic_recognition: Recognition,
57-
semantic_transform: Transformation,
58-
output_writer: OutputWriter,
59-
},
60-
/// The all model is combining the intercept and semantic modes.
61-
All {
62-
input: args::BuildCommand,
63-
output: args::BuildSemantic,
64-
intercept_config: config::Intercept,
65-
output_config: config::Output,
66-
},
46+
Intercept(Intercept),
47+
Semantic(Semantic),
48+
All(All),
49+
}
50+
51+
/// The intercept mode we are only capturing the build commands.
52+
struct Intercept {
53+
input: args::BuildCommand,
54+
output: args::BuildEvents,
55+
config: config::Intercept,
56+
}
57+
58+
/// The semantic mode we are deduct the semantic meaning of the
59+
/// executed commands from the build process.
60+
struct Semantic {
61+
event_source: EventFileReader,
62+
semantic_recognition: Recognition,
63+
semantic_transform: Transformation,
64+
output_writer: OutputWriter,
65+
}
66+
67+
/// The all model is combining the intercept and semantic modes.
68+
struct All {
69+
input: args::BuildCommand,
70+
output: args::BuildSemantic,
71+
intercept_config: config::Intercept,
72+
output_config: config::Output,
73+
}
74+
75+
/// The mode trait is used to run the application in different modes.
76+
trait Mode {
77+
fn run(self) -> ExitCode;
6778
}
6879

6980
impl Application {
@@ -76,110 +87,110 @@ impl Application {
7687
match args.mode {
7788
args::Mode::Intercept { input, output } => {
7889
let intercept_config = config.intercept;
79-
let result = Application::Intercept {
90+
let mode = Intercept {
8091
input,
8192
output,
8293
config: intercept_config,
8394
};
84-
Ok(result)
95+
Ok(Application::Intercept(mode))
8596
}
8697
args::Mode::Semantic { input, output } => {
8798
let event_source = EventFileReader::try_from(input)?;
8899
let semantic_recognition = Recognition::try_from(&config)?;
89100
let semantic_transform = Transformation::from(&config.output);
90101
let output_writer = OutputWriter::configure(&output, &config.output)?;
91-
let result = Application::Semantic {
102+
let mode = Semantic {
92103
event_source,
93104
semantic_recognition,
94105
semantic_transform,
95106
output_writer,
96107
};
97-
Ok(result)
108+
Ok(Application::Semantic(mode))
98109
}
99110
args::Mode::All { input, output } => {
100111
let intercept_config = config.intercept;
101112
let output_config = config.output;
102-
let result = Application::All {
113+
let mode = All {
103114
input,
104115
output,
105116
intercept_config,
106117
output_config,
107118
};
108-
Ok(result)
119+
Ok(Application::All(mode))
109120
}
110121
}
111122
}
123+
}
112124

113-
/// Executes the configured application.
125+
impl Mode for Application {
114126
fn run(self) -> ExitCode {
115127
match self {
116-
Application::Intercept {
117-
input,
118-
output,
119-
config,
120-
} => {
121-
match &config {
122-
config::Intercept::Wrapper { .. } => {
123-
let service = InterceptService::new()
124-
.expect("Failed to create the intercept service");
125-
let environment = InterceptEnvironment::new(&config, service.address())
126-
.expect("Failed to create the intercept environment");
127-
128-
// start writer thread
129-
let writer_thread = thread::spawn(move || {
130-
let mut writer = std::fs::File::create(output.file_name)
131-
.expect("Failed to create the output file");
132-
for envelope in service.receiver().iter() {
133-
envelope
134-
.write_into(&mut writer)
135-
.expect("Failed to write the envelope");
136-
}
137-
});
138-
139-
let status = environment.execute_build_command(input);
140-
141-
writer_thread
142-
.join()
143-
.expect("Failed to join the writer thread");
144-
145-
status.unwrap_or(ExitCode::FAILURE)
146-
}
147-
config::Intercept::Preload { .. } => {
148-
todo!()
128+
Application::Intercept(intercept) => intercept.run(),
129+
Application::Semantic(semantic) => semantic.run(),
130+
Application::All(all) => all.run(),
131+
}
132+
}
133+
}
134+
135+
impl Mode for Intercept {
136+
fn run(self) -> ExitCode {
137+
match &self.config {
138+
config::Intercept::Wrapper { .. } => {
139+
let service = InterceptService::new()
140+
.expect("Failed to create the intercept service");
141+
let environment = InterceptEnvironment::new(&self.config, service.address())
142+
.expect("Failed to create the intercept environment");
143+
144+
// start writer thread
145+
let writer_thread = thread::spawn(move || {
146+
let mut writer = std::fs::File::create(self.output.file_name)
147+
.expect("Failed to create the output file");
148+
for envelope in service.receiver().iter() {
149+
envelope
150+
.write_into(&mut writer)
151+
.expect("Failed to write the envelope");
149152
}
150-
}
151-
}
152-
Application::Semantic {
153-
event_source,
154-
semantic_recognition,
155-
semantic_transform,
156-
output_writer,
157-
} => {
158-
// Set up the pipeline of compilation database entries.
159-
let entries = event_source
160-
.generate()
161-
.flat_map(|execution| semantic_recognition.apply(execution))
162-
.flat_map(|semantic| semantic_transform.apply(semantic));
163-
// Consume the entries and write them to the output file.
164-
// The exit code is based on the result of the output writer.
165-
match output_writer.run(entries) {
166-
Ok(_) => ExitCode::SUCCESS,
167-
Err(_) => ExitCode::FAILURE,
168-
}
153+
});
154+
155+
let status = environment.execute_build_command(self.input);
156+
157+
writer_thread
158+
.join()
159+
.expect("Failed to join the writer thread");
160+
161+
status.unwrap_or(ExitCode::FAILURE)
169162
}
170-
Application::All {
171-
input,
172-
output,
173-
intercept_config,
174-
output_config,
175-
} => {
176-
// TODO: Implement the all mode.
177-
ExitCode::FAILURE
163+
config::Intercept::Preload { .. } => {
164+
todo!()
178165
}
179166
}
180167
}
181168
}
182169

170+
impl Mode for Semantic {
171+
fn run(self) -> ExitCode {
172+
// Set up the pipeline of compilation database entries.
173+
let entries = self
174+
.event_source
175+
.generate()
176+
.flat_map(|execution| self.semantic_recognition.apply(execution))
177+
.flat_map(|semantic| self.semantic_transform.apply(semantic));
178+
// Consume the entries and write them to the output file.
179+
// The exit code is based on the result of the output writer.
180+
match self.output_writer.run(entries) {
181+
Ok(_) => ExitCode::SUCCESS,
182+
Err(_) => ExitCode::FAILURE,
183+
}
184+
}
185+
}
186+
187+
impl Mode for All {
188+
fn run(self) -> ExitCode {
189+
// TODO: Implement the all mode.
190+
ExitCode::FAILURE
191+
}
192+
}
193+
183194
struct InterceptService {
184195
collector: Arc<EventCollectorOnTcp>,
185196
receiver: Receiver<Envelope>,

0 commit comments

Comments
 (0)