@@ -43,27 +43,38 @@ fn main() -> anyhow::Result<ExitCode> {
4343
4444/// Represent the application state.
4545enum 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
6980impl 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+
183194struct InterceptService {
184195 collector : Arc < EventCollectorOnTcp > ,
185196 receiver : Receiver < Envelope > ,
0 commit comments