1use std::io::{Read, Write};
15
16use serde::{Deserialize, Serialize};
17
18use crate::{
19 context::{BuildEventContext, read_build_event_context, write_build_event_context},
20 error::MuninError,
21 fields::{BuildEventArgsFields, read_build_event_args_fields, write_build_event_args_fields},
22 nvl_table::NameValueListTable,
23 primitives::{read_7bit_count, read_7bit_int, read_bool},
24 readers::{read_dedup_string, read_optional_string, read_string_dictionary},
25 string_table::StringTable,
26 writers::{
27 WriteContext, write_7bit_int, write_bool, write_dedup_string, write_dotnet_string,
28 write_guid, write_i64_le, write_optional_string, write_string_dictionary,
29 },
30};
31
32fn read_diagnostic_fields(
39 reader: &mut impl Read,
40 strings: &StringTable,
41 file_format_version: i32,
42) -> Result<DiagnosticLocation, MuninError> {
43 let subcategory = read_optional_string(reader, strings, file_format_version)?;
44 let code = read_optional_string(reader, strings, file_format_version)?;
45 let file = read_optional_string(reader, strings, file_format_version)?;
46 let project_file = read_optional_string(reader, strings, file_format_version)?;
47 let line_number = read_7bit_int(reader)?;
48 let column_number = read_7bit_int(reader)?;
49 let end_line_number = read_7bit_int(reader)?;
50 let end_column_number = read_7bit_int(reader)?;
51 Ok(DiagnosticLocation {
52 subcategory,
53 code,
54 file,
55 project_file,
56 line_number,
57 column_number,
58 end_line_number,
59 end_column_number,
60 })
61}
62
63#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
65pub struct DiagnosticLocation {
66 pub subcategory: Option<String>,
67 pub code: Option<String>,
68 pub file: Option<String>,
69 pub project_file: Option<String>,
70 pub line_number: i32,
71 pub column_number: i32,
72 pub end_line_number: i32,
73 pub end_column_number: i32,
74}
75
76#[derive(Debug, Clone, Default, Serialize, Deserialize)]
82pub struct BuildStartedEvent {
83 pub fields: BuildEventArgsFields,
84 pub environment: Option<Vec<(String, String)>>,
86}
87
88pub fn read_build_started(
90 reader: &mut impl Read,
91 strings: &StringTable,
92 nvl_table: &NameValueListTable,
93 file_format_version: i32,
94) -> Result<BuildStartedEvent, MuninError> {
95 let fields = read_build_event_args_fields(reader, strings, file_format_version, false)?;
96 let environment = read_string_dictionary(reader, strings, nvl_table, file_format_version)?;
97 Ok(BuildStartedEvent {
98 fields,
99 environment,
100 })
101}
102
103#[derive(Debug, Clone, Default, Serialize, Deserialize)]
105pub struct BuildFinishedEvent {
106 pub fields: BuildEventArgsFields,
107 pub succeeded: bool,
108}
109
110pub fn read_build_finished(
112 reader: &mut impl Read,
113 strings: &StringTable,
114 file_format_version: i32,
115) -> Result<BuildFinishedEvent, MuninError> {
116 let fields = read_build_event_args_fields(reader, strings, file_format_version, false)?;
117 let succeeded = read_bool(reader)?;
118 Ok(BuildFinishedEvent { fields, succeeded })
119}
120
121#[derive(Debug, Clone, Default, Serialize, Deserialize)]
123pub struct ProjectStartedEvent {
124 pub fields: BuildEventArgsFields,
125 pub parent_context: Option<BuildEventContext>,
126 pub project_file: Option<String>,
127 pub project_id: i32,
128 pub target_names: Option<String>,
129 pub tools_version: Option<String>,
130 pub global_properties: Option<Vec<(String, String)>>,
131 pub property_list: Option<Vec<(String, String)>>,
132 pub item_list: Option<Vec<ItemGroup>>,
133}
134
135pub fn read_project_started(
137 reader: &mut impl Read,
138 strings: &StringTable,
139 nvl_table: &NameValueListTable,
140 file_format_version: i32,
141) -> Result<ProjectStartedEvent, MuninError> {
142 let fields = read_build_event_args_fields(reader, strings, file_format_version, false)?;
143
144 let parent_context = if read_bool(reader)? {
145 Some(read_build_event_context(reader, file_format_version)?)
146 } else {
147 None
148 };
149
150 let project_file = read_optional_string(reader, strings, file_format_version)?;
151 let project_id = read_7bit_int(reader)?;
152 let target_names = read_dedup_string(reader, strings)?;
153 let tools_version = read_optional_string(reader, strings, file_format_version)?;
154
155 let global_properties = if file_format_version > 6 {
156 if file_format_version >= 18 || read_bool(reader)? {
159 read_string_dictionary(reader, strings, nvl_table, file_format_version)?
160 } else {
161 None
162 }
163 } else {
164 None
165 };
166
167 let property_list = read_property_list(reader, strings, nvl_table, file_format_version)?;
168 let item_list = read_project_items(reader, strings, nvl_table, file_format_version)?;
169
170 Ok(ProjectStartedEvent {
171 fields,
172 parent_context,
173 project_file,
174 project_id,
175 target_names,
176 tools_version,
177 global_properties,
178 property_list,
179 item_list,
180 })
181}
182
183#[derive(Debug, Clone, Default, Serialize, Deserialize)]
185pub struct ProjectFinishedEvent {
186 pub fields: BuildEventArgsFields,
187 pub project_file: Option<String>,
188 pub succeeded: bool,
189}
190
191pub fn read_project_finished(
193 reader: &mut impl Read,
194 strings: &StringTable,
195 file_format_version: i32,
196) -> Result<ProjectFinishedEvent, MuninError> {
197 let fields = read_build_event_args_fields(reader, strings, file_format_version, false)?;
198 let project_file = read_optional_string(reader, strings, file_format_version)?;
199 let succeeded = read_bool(reader)?;
200 Ok(ProjectFinishedEvent {
201 fields,
202 project_file,
203 succeeded,
204 })
205}
206
207#[derive(Debug, Clone, Default, Serialize, Deserialize)]
213pub struct TargetStartedEvent {
214 pub fields: BuildEventArgsFields,
215 pub target_name: Option<String>,
216 pub project_file: Option<String>,
217 pub target_file: Option<String>,
218 pub parent_target: Option<String>,
219 pub build_reason: i32,
221}
222
223pub fn read_target_started(
225 reader: &mut impl Read,
226 strings: &StringTable,
227 file_format_version: i32,
228) -> Result<TargetStartedEvent, MuninError> {
229 let fields = read_build_event_args_fields(reader, strings, file_format_version, false)?;
230 let target_name = read_optional_string(reader, strings, file_format_version)?;
231 let project_file = read_optional_string(reader, strings, file_format_version)?;
232 let target_file = read_optional_string(reader, strings, file_format_version)?;
233 let parent_target = read_optional_string(reader, strings, file_format_version)?;
234 let build_reason = if file_format_version > 3 {
235 read_7bit_int(reader)?
236 } else {
237 0 };
239 Ok(TargetStartedEvent {
240 fields,
241 target_name,
242 project_file,
243 target_file,
244 parent_target,
245 build_reason,
246 })
247}
248
249#[derive(Debug, Clone, Default, Serialize, Deserialize)]
251pub struct TargetFinishedEvent {
252 pub fields: BuildEventArgsFields,
253 pub succeeded: bool,
254 pub project_file: Option<String>,
255 pub target_file: Option<String>,
256 pub target_name: Option<String>,
257 pub target_outputs: Option<Vec<TaskItem>>,
258}
259
260pub fn read_target_finished(
262 reader: &mut impl Read,
263 strings: &StringTable,
264 nvl_table: &NameValueListTable,
265 file_format_version: i32,
266) -> Result<TargetFinishedEvent, MuninError> {
267 let fields = read_build_event_args_fields(reader, strings, file_format_version, false)?;
268 let succeeded = read_bool(reader)?;
269 let project_file = read_optional_string(reader, strings, file_format_version)?;
270 let target_file = read_optional_string(reader, strings, file_format_version)?;
271 let target_name = read_optional_string(reader, strings, file_format_version)?;
272 let target_outputs = read_task_item_list(reader, strings, nvl_table, file_format_version)?;
273 Ok(TargetFinishedEvent {
274 fields,
275 succeeded,
276 project_file,
277 target_file,
278 target_name,
279 target_outputs,
280 })
281}
282
283#[derive(Debug, Clone, Default, Serialize, Deserialize)]
285pub struct TargetSkippedEvent {
286 pub fields: BuildEventArgsFields,
287 pub target_file: Option<String>,
288 pub target_name: Option<String>,
289 pub parent_target: Option<String>,
290 pub condition: Option<String>,
291 pub evaluated_condition: Option<String>,
292 pub originally_succeeded: bool,
293 pub skip_reason: i32,
295 pub build_reason: i32,
296 pub original_build_event_context: Option<BuildEventContext>,
297}
298
299pub fn read_target_skipped(
301 reader: &mut impl Read,
302 strings: &StringTable,
303 file_format_version: i32,
304) -> Result<TargetSkippedEvent, MuninError> {
305 let fields = read_build_event_args_fields(reader, strings, file_format_version, true)?;
306 let target_file = read_optional_string(reader, strings, file_format_version)?;
307 let target_name = read_optional_string(reader, strings, file_format_version)?;
308 let parent_target = read_optional_string(reader, strings, file_format_version)?;
309
310 let mut condition = None;
311 let mut evaluated_condition = None;
312 let mut originally_succeeded = false;
313 let mut skip_reason = 0; if file_format_version >= 13 {
316 condition = read_optional_string(reader, strings, file_format_version)?;
317 evaluated_condition = read_optional_string(reader, strings, file_format_version)?;
318 originally_succeeded = read_bool(reader)?;
319
320 skip_reason = if condition.is_some() {
322 1 } else if originally_succeeded {
324 2 } else {
326 3 };
328 }
329
330 let build_reason = read_7bit_int(reader)?;
331
332 let mut original_build_event_context = None;
333 if file_format_version >= 14 {
334 skip_reason = read_7bit_int(reader)?;
335 if read_bool(reader)? {
337 original_build_event_context =
338 Some(read_build_event_context(reader, file_format_version)?);
339 }
340 }
341
342 Ok(TargetSkippedEvent {
343 fields,
344 target_file,
345 target_name,
346 parent_target,
347 condition,
348 evaluated_condition,
349 originally_succeeded,
350 skip_reason,
351 build_reason,
352 original_build_event_context,
353 })
354}
355
356#[derive(Debug, Clone, Default, Serialize, Deserialize)]
362pub struct TaskStartedEvent {
363 pub fields: BuildEventArgsFields,
364 pub task_name: Option<String>,
365 pub project_file: Option<String>,
366 pub task_file: Option<String>,
367 pub task_assembly_location: Option<String>,
368}
369
370pub fn read_task_started(
372 reader: &mut impl Read,
373 strings: &StringTable,
374 file_format_version: i32,
375) -> Result<TaskStartedEvent, MuninError> {
376 let fields = read_build_event_args_fields(reader, strings, file_format_version, false)?;
377 let task_name = read_optional_string(reader, strings, file_format_version)?;
378 let project_file = read_optional_string(reader, strings, file_format_version)?;
379 let task_file = read_optional_string(reader, strings, file_format_version)?;
380 let task_assembly_location = if file_format_version > 19 {
381 read_optional_string(reader, strings, file_format_version)?
382 } else {
383 None
384 };
385 Ok(TaskStartedEvent {
386 fields,
387 task_name,
388 project_file,
389 task_file,
390 task_assembly_location,
391 })
392}
393
394#[derive(Debug, Clone, Default, Serialize, Deserialize)]
396pub struct TaskFinishedEvent {
397 pub fields: BuildEventArgsFields,
398 pub succeeded: bool,
399 pub task_name: Option<String>,
400 pub project_file: Option<String>,
401 pub task_file: Option<String>,
402}
403
404pub fn read_task_finished(
406 reader: &mut impl Read,
407 strings: &StringTable,
408 file_format_version: i32,
409) -> Result<TaskFinishedEvent, MuninError> {
410 let fields = read_build_event_args_fields(reader, strings, file_format_version, false)?;
411 let succeeded = read_bool(reader)?;
412 let task_name = read_optional_string(reader, strings, file_format_version)?;
413 let project_file = read_optional_string(reader, strings, file_format_version)?;
414 let task_file = read_optional_string(reader, strings, file_format_version)?;
415 Ok(TaskFinishedEvent {
416 fields,
417 succeeded,
418 task_name,
419 project_file,
420 task_file,
421 })
422}
423
424#[derive(Debug, Clone, Default, Serialize, Deserialize)]
426pub struct TaskCommandLineEvent {
427 pub fields: BuildEventArgsFields,
428 pub command_line: Option<String>,
429 pub task_name: Option<String>,
430}
431
432pub fn read_task_command_line(
434 reader: &mut impl Read,
435 strings: &StringTable,
436 file_format_version: i32,
437) -> Result<TaskCommandLineEvent, MuninError> {
438 let fields = read_build_event_args_fields(reader, strings, file_format_version, true)?;
439 let command_line = read_optional_string(reader, strings, file_format_version)?;
440 let task_name = read_optional_string(reader, strings, file_format_version)?;
441 Ok(TaskCommandLineEvent {
442 fields,
443 command_line,
444 task_name,
445 })
446}
447
448#[derive(Debug, Clone, Default, Serialize, Deserialize)]
450pub struct TaskParameterEvent {
451 pub fields: BuildEventArgsFields,
452 pub kind: i32,
454 pub item_type: Option<String>,
455 pub items: Option<Vec<TaskItem>>,
456 pub parameter_name: Option<String>,
457 pub property_name: Option<String>,
458}
459
460pub fn read_task_parameter(
462 reader: &mut impl Read,
463 strings: &StringTable,
464 nvl_table: &NameValueListTable,
465 file_format_version: i32,
466) -> Result<TaskParameterEvent, MuninError> {
467 let fields = read_build_event_args_fields(reader, strings, file_format_version, true)?;
468 let kind = read_7bit_int(reader)?;
469 let item_type = read_dedup_string(reader, strings)?;
470 let items = read_task_item_list(reader, strings, nvl_table, file_format_version)?;
471 let (parameter_name, property_name) = if file_format_version >= 21 {
472 (
473 read_dedup_string(reader, strings)?,
474 read_dedup_string(reader, strings)?,
475 )
476 } else {
477 (None, None)
478 };
479 Ok(TaskParameterEvent {
480 fields,
481 kind,
482 item_type,
483 items,
484 parameter_name,
485 property_name,
486 })
487}
488
489#[derive(Debug, Clone, Default, Serialize, Deserialize)]
495pub struct BuildErrorEvent {
496 pub fields: BuildEventArgsFields,
497 pub location: DiagnosticLocation,
498}
499
500pub fn read_build_error(
502 reader: &mut impl Read,
503 strings: &StringTable,
504 file_format_version: i32,
505) -> Result<BuildErrorEvent, MuninError> {
506 let fields = read_build_event_args_fields(reader, strings, file_format_version, false)?;
507 let location = read_diagnostic_fields(reader, strings, file_format_version)?;
508 Ok(BuildErrorEvent { fields, location })
509}
510
511#[derive(Debug, Clone, Default, Serialize, Deserialize)]
513pub struct BuildWarningEvent {
514 pub fields: BuildEventArgsFields,
515 pub location: DiagnosticLocation,
516}
517
518pub fn read_build_warning(
520 reader: &mut impl Read,
521 strings: &StringTable,
522 file_format_version: i32,
523) -> Result<BuildWarningEvent, MuninError> {
524 let fields = read_build_event_args_fields(reader, strings, file_format_version, false)?;
525 let location = read_diagnostic_fields(reader, strings, file_format_version)?;
526 Ok(BuildWarningEvent { fields, location })
527}
528
529#[derive(Debug, Clone, Default, Serialize, Deserialize)]
531pub struct BuildMessageEvent {
532 pub fields: BuildEventArgsFields,
533}
534
535pub fn read_build_message(
537 reader: &mut impl Read,
538 strings: &StringTable,
539 file_format_version: i32,
540) -> Result<BuildMessageEvent, MuninError> {
541 let fields = read_build_event_args_fields(reader, strings, file_format_version, true)?;
542 Ok(BuildMessageEvent { fields })
543}
544
545#[derive(Debug, Clone, Default, Serialize, Deserialize)]
547pub struct CriticalBuildMessageEvent {
548 pub fields: BuildEventArgsFields,
549}
550
551pub fn read_critical_build_message(
553 reader: &mut impl Read,
554 strings: &StringTable,
555 file_format_version: i32,
556) -> Result<CriticalBuildMessageEvent, MuninError> {
557 let fields = read_build_event_args_fields(reader, strings, file_format_version, true)?;
558 Ok(CriticalBuildMessageEvent { fields })
559}
560
561#[derive(Debug, Clone, Default, Serialize, Deserialize)]
567pub struct ProjectEvaluationStartedEvent {
568 pub fields: BuildEventArgsFields,
569 pub project_file: Option<String>,
570}
571
572pub fn read_project_evaluation_started(
574 reader: &mut impl Read,
575 strings: &StringTable,
576 file_format_version: i32,
577) -> Result<ProjectEvaluationStartedEvent, MuninError> {
578 let fields = read_build_event_args_fields(reader, strings, file_format_version, false)?;
579 let project_file = read_dedup_string(reader, strings)?;
580 Ok(ProjectEvaluationStartedEvent {
581 fields,
582 project_file,
583 })
584}
585
586#[derive(Debug, Clone, Default, Serialize, Deserialize)]
588pub struct ProjectEvaluationFinishedEvent {
589 pub fields: BuildEventArgsFields,
590 pub project_file: Option<String>,
591 pub global_properties: Option<Vec<(String, String)>>,
592 pub property_list: Option<Vec<(String, String)>>,
593 pub item_list: Option<Vec<ItemGroup>>,
594 pub has_profile_data: bool,
595 pub profile_data: Option<Vec<ProfileEntry>>,
596}
597
598#[derive(Debug, Clone, Default, Serialize, Deserialize)]
600pub struct ProfileEntry {
601 pub location: EvaluationLocation,
602 pub profiled_location: ProfiledLocation,
603}
604
605#[derive(Debug, Clone, Default, Serialize, Deserialize)]
607pub struct EvaluationLocation {
608 pub element_name: Option<String>,
609 pub description: Option<String>,
610 pub evaluation_description: Option<String>,
611 pub file: Option<String>,
612 pub kind: i32,
613 pub evaluation_pass: i32,
614 pub line: Option<i32>,
615 pub id: i64,
616 pub parent_id: Option<i64>,
617}
618
619#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)]
621pub struct ProfiledLocation {
622 pub number_of_hits: i32,
623 pub exclusive_time_ticks: i64,
625 pub inclusive_time_ticks: i64,
627}
628
629pub fn read_project_evaluation_finished(
631 reader: &mut impl Read,
632 strings: &StringTable,
633 nvl_table: &NameValueListTable,
634 file_format_version: i32,
635) -> Result<ProjectEvaluationFinishedEvent, MuninError> {
636 let fields = read_build_event_args_fields(reader, strings, file_format_version, false)?;
637 let project_file = read_dedup_string(reader, strings)?;
638
639 let mut global_properties = None;
640 let mut property_list = None;
641 let mut item_list = None;
642 let mut has_profile_data = false;
643 let mut profile_data = None;
644
645 if file_format_version >= 12 {
646 if file_format_version >= 18 || read_bool(reader)? {
648 global_properties =
649 read_string_dictionary(reader, strings, nvl_table, file_format_version)?;
650 }
651
652 property_list = read_property_list(reader, strings, nvl_table, file_format_version)?;
653 item_list = read_project_items(reader, strings, nvl_table, file_format_version)?;
654 }
655
656 if file_format_version > 4 {
658 has_profile_data = read_bool(reader)?;
659 if has_profile_data {
660 let count = read_7bit_count(reader, "profile entry count")?;
661 let mut entries = Vec::with_capacity(count);
662 for _ in 0..count {
663 let location = read_evaluation_location(reader, strings, file_format_version)?;
664 let profiled = read_profiled_location(reader)?;
665 entries.push(ProfileEntry {
666 location,
667 profiled_location: profiled,
668 });
669 }
670 profile_data = Some(entries);
671 }
672 }
673
674 Ok(ProjectEvaluationFinishedEvent {
675 fields,
676 project_file,
677 global_properties,
678 property_list,
679 item_list,
680 has_profile_data,
681 profile_data,
682 })
683}
684
685#[derive(Debug, Clone, Default, Serialize, Deserialize)]
691pub struct PropertyReassignmentEvent {
692 pub fields: BuildEventArgsFields,
693 pub property_name: Option<String>,
694 pub previous_value: Option<String>,
695 pub new_value: Option<String>,
696 pub location: Option<String>,
697}
698
699pub fn read_property_reassignment(
701 reader: &mut impl Read,
702 strings: &StringTable,
703 file_format_version: i32,
704) -> Result<PropertyReassignmentEvent, MuninError> {
705 let fields = read_build_event_args_fields(reader, strings, file_format_version, true)?;
706 let property_name = read_dedup_string(reader, strings)?;
707 let previous_value = read_dedup_string(reader, strings)?;
708 let new_value = read_dedup_string(reader, strings)?;
709 let location = read_dedup_string(reader, strings)?;
710 Ok(PropertyReassignmentEvent {
711 fields,
712 property_name,
713 previous_value,
714 new_value,
715 location,
716 })
717}
718
719#[derive(Debug, Clone, Default, Serialize, Deserialize)]
721pub struct UninitializedPropertyReadEvent {
722 pub fields: BuildEventArgsFields,
723 pub property_name: Option<String>,
724}
725
726pub fn read_uninitialized_property_read(
728 reader: &mut impl Read,
729 strings: &StringTable,
730 file_format_version: i32,
731) -> Result<UninitializedPropertyReadEvent, MuninError> {
732 let fields = read_build_event_args_fields(reader, strings, file_format_version, true)?;
733 let property_name = read_dedup_string(reader, strings)?;
734 Ok(UninitializedPropertyReadEvent {
735 fields,
736 property_name,
737 })
738}
739
740#[derive(Debug, Clone, Default, Serialize, Deserialize)]
742pub struct PropertyInitialValueSetEvent {
743 pub fields: BuildEventArgsFields,
744 pub property_name: Option<String>,
745 pub property_value: Option<String>,
746 pub property_source: Option<String>,
747}
748
749pub fn read_property_initial_value_set(
751 reader: &mut impl Read,
752 strings: &StringTable,
753 file_format_version: i32,
754) -> Result<PropertyInitialValueSetEvent, MuninError> {
755 let fields = read_build_event_args_fields(reader, strings, file_format_version, true)?;
756 let property_name = read_dedup_string(reader, strings)?;
757 let property_value = read_dedup_string(reader, strings)?;
758 let property_source = read_dedup_string(reader, strings)?;
759 Ok(PropertyInitialValueSetEvent {
760 fields,
761 property_name,
762 property_value,
763 property_source,
764 })
765}
766
767#[derive(Debug, Clone, Default, Serialize, Deserialize)]
773pub struct EnvironmentVariableReadEvent {
774 pub fields: BuildEventArgsFields,
775 pub environment_variable_name: Option<String>,
776 pub line: i32,
778 pub column: i32,
780 pub file_name: Option<String>,
782}
783
784pub fn read_environment_variable_read(
786 reader: &mut impl Read,
787 strings: &StringTable,
788 file_format_version: i32,
789) -> Result<EnvironmentVariableReadEvent, MuninError> {
790 let fields = read_build_event_args_fields(reader, strings, file_format_version, true)?;
791 let environment_variable_name = read_dedup_string(reader, strings)?;
792 let (line, column, file_name) = if file_format_version >= 22 {
793 let line = read_7bit_int(reader)?;
794 let column = read_7bit_int(reader)?;
795 let file_name = read_dedup_string(reader, strings)?;
796 (line, column, file_name)
797 } else {
798 (0, 0, None)
799 };
800 Ok(EnvironmentVariableReadEvent {
801 fields,
802 environment_variable_name,
803 line,
804 column,
805 file_name,
806 })
807}
808
809#[derive(Debug, Clone, Default, Serialize, Deserialize)]
811pub struct ResponseFileUsedEvent {
812 pub fields: BuildEventArgsFields,
813 pub response_file_path: Option<String>,
814}
815
816pub fn read_response_file_used(
818 reader: &mut impl Read,
819 strings: &StringTable,
820 file_format_version: i32,
821) -> Result<ResponseFileUsedEvent, MuninError> {
822 let fields = read_build_event_args_fields(reader, strings, file_format_version, false)?;
823 let response_file_path = read_dedup_string(reader, strings)?;
824 Ok(ResponseFileUsedEvent {
825 fields,
826 response_file_path,
827 })
828}
829
830#[derive(Debug, Clone, Default, Serialize, Deserialize)]
836pub struct AssemblyLoadEvent {
837 pub fields: BuildEventArgsFields,
838 pub context: i32,
840 pub loading_initiator: Option<String>,
841 pub assembly_name: Option<String>,
842 pub assembly_path: Option<String>,
843 pub mvid: [u8; 16],
845 pub app_domain_name: Option<String>,
846}
847
848pub fn read_assembly_load(
850 reader: &mut impl Read,
851 strings: &StringTable,
852 file_format_version: i32,
853) -> Result<AssemblyLoadEvent, MuninError> {
854 let fields = read_build_event_args_fields(reader, strings, file_format_version, false)?;
855 let context = read_7bit_int(reader)?;
856 let loading_initiator = read_dedup_string(reader, strings)?;
857 let assembly_name = read_dedup_string(reader, strings)?;
858 let assembly_path = read_dedup_string(reader, strings)?;
859 let mvid = crate::primitives::read_guid(reader)?;
860 let app_domain_name = read_dedup_string(reader, strings)?;
861 Ok(AssemblyLoadEvent {
862 fields,
863 context,
864 loading_initiator,
865 assembly_name,
866 assembly_path,
867 mvid,
868 app_domain_name,
869 })
870}
871
872#[derive(Debug, Clone, Default, Serialize, Deserialize)]
874pub struct ProjectImportedEvent {
875 pub fields: BuildEventArgsFields,
876 pub import_ignored: bool,
878 pub imported_project_file: Option<String>,
879 pub unexpanded_project: Option<String>,
880}
881
882pub fn read_project_imported(
884 reader: &mut impl Read,
885 strings: &StringTable,
886 file_format_version: i32,
887) -> Result<ProjectImportedEvent, MuninError> {
888 let fields = read_build_event_args_fields(reader, strings, file_format_version, true)?;
889 let import_ignored = if file_format_version > 2 {
890 read_bool(reader)?
891 } else {
892 false
893 };
894 let imported_project_file = read_optional_string(reader, strings, file_format_version)?;
895 let unexpanded_project = read_optional_string(reader, strings, file_format_version)?;
896 Ok(ProjectImportedEvent {
897 fields,
898 import_ignored,
899 imported_project_file,
900 unexpanded_project,
901 })
902}
903
904pub type BuildCheckMessageEvent = BuildMessageEvent;
916
917pub type BuildCheckWarningEvent = BuildWarningEvent;
919
920pub type BuildCheckErrorEvent = BuildErrorEvent;
922
923#[derive(Debug, Clone, Default, Serialize, Deserialize)]
925pub struct BuildCheckTracingEvent {
926 pub fields: BuildEventArgsFields,
927 pub tracing_data: Option<Vec<(String, String)>>,
929}
930
931pub fn read_build_check_tracing(
933 reader: &mut impl Read,
934 strings: &StringTable,
935 nvl_table: &NameValueListTable,
936 file_format_version: i32,
937) -> Result<BuildCheckTracingEvent, MuninError> {
938 let fields = read_build_event_args_fields(reader, strings, file_format_version, false)?;
939 let tracing_data = read_string_dictionary(reader, strings, nvl_table, file_format_version)?;
940 Ok(BuildCheckTracingEvent {
941 fields,
942 tracing_data,
943 })
944}
945
946#[derive(Debug, Clone, Default, Serialize, Deserialize)]
948pub struct BuildCheckAcquisitionEvent {
949 pub fields: BuildEventArgsFields,
950 pub acquisition_path: String,
951 pub project_path: String,
952}
953
954pub fn read_build_check_acquisition(
956 reader: &mut impl Read,
957 strings: &StringTable,
958 file_format_version: i32,
959) -> Result<BuildCheckAcquisitionEvent, MuninError> {
960 let fields = read_build_event_args_fields(reader, strings, file_format_version, false)?;
961 let acquisition_path = crate::primitives::read_dotnet_string(reader)?;
962 let project_path = crate::primitives::read_dotnet_string(reader)?;
963 Ok(BuildCheckAcquisitionEvent {
964 fields,
965 acquisition_path,
966 project_path,
967 })
968}
969
970#[derive(Debug, Clone, Default, Serialize, Deserialize)]
976pub struct BuildSubmissionStartedEvent {
977 pub fields: BuildEventArgsFields,
978 pub global_properties: Option<Vec<(String, String)>>,
979 pub entry_projects_full_path: Option<Vec<String>>,
980 pub target_names: Option<Vec<String>>,
981 pub flags: i32,
983 pub submission_id: i32,
984}
985
986pub fn read_build_submission_started(
988 reader: &mut impl Read,
989 strings: &StringTable,
990 nvl_table: &NameValueListTable,
991 file_format_version: i32,
992) -> Result<BuildSubmissionStartedEvent, MuninError> {
993 let fields = read_build_event_args_fields(reader, strings, file_format_version, false)?;
994 let global_properties =
995 read_string_dictionary(reader, strings, nvl_table, file_format_version)?;
996 let entry_projects_full_path = read_string_list(reader, strings)?;
997 let target_names = read_string_list(reader, strings)?;
998 let flags = read_7bit_int(reader)?;
999 let submission_id = read_7bit_int(reader)?;
1000 Ok(BuildSubmissionStartedEvent {
1001 fields,
1002 global_properties,
1003 entry_projects_full_path,
1004 target_names,
1005 flags,
1006 submission_id,
1007 })
1008}
1009
1010#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1012pub struct BuildCanceledEvent {
1013 pub fields: BuildEventArgsFields,
1014}
1015
1016pub fn read_build_canceled(
1018 reader: &mut impl Read,
1019 strings: &StringTable,
1020 file_format_version: i32,
1021) -> Result<BuildCanceledEvent, MuninError> {
1022 let fields = read_build_event_args_fields(reader, strings, file_format_version, false)?;
1023 Ok(BuildCanceledEvent { fields })
1024}
1025
1026#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1032pub struct TaskItem {
1033 pub item_spec: Option<String>,
1034 pub metadata: Option<Vec<(String, String)>>,
1035}
1036
1037#[derive(Debug, Clone, Default, Serialize, Deserialize)]
1039pub struct ItemGroup {
1040 pub item_type: String,
1041 pub items: Vec<TaskItem>,
1042}
1043
1044fn read_string_list(
1052 reader: &mut impl Read,
1053 strings: &StringTable,
1054) -> Result<Option<Vec<String>>, MuninError> {
1055 let count = read_7bit_count(reader, "string-list count")?;
1056 if count == 0 {
1057 return Ok(None);
1058 }
1059 let mut list = Vec::with_capacity(count);
1060 for _ in 0..count {
1061 if let Some(s) = read_dedup_string(reader, strings)? {
1062 list.push(s);
1063 }
1064 }
1065 if list.is_empty() {
1066 Ok(None)
1067 } else {
1068 Ok(Some(list))
1069 }
1070}
1071
1072fn read_property_list(
1074 reader: &mut impl Read,
1075 strings: &StringTable,
1076 nvl_table: &NameValueListTable,
1077 file_format_version: i32,
1078) -> Result<Option<Vec<(String, String)>>, MuninError> {
1079 read_string_dictionary(reader, strings, nvl_table, file_format_version)
1080}
1081
1082fn read_task_item(
1084 reader: &mut impl Read,
1085 strings: &StringTable,
1086 nvl_table: &NameValueListTable,
1087 file_format_version: i32,
1088) -> Result<TaskItem, MuninError> {
1089 let item_spec = read_dedup_string(reader, strings)?;
1090 let metadata = read_string_dictionary(reader, strings, nvl_table, file_format_version)?;
1091 Ok(TaskItem {
1092 item_spec,
1093 metadata,
1094 })
1095}
1096
1097fn read_task_item_list(
1099 reader: &mut impl Read,
1100 strings: &StringTable,
1101 nvl_table: &NameValueListTable,
1102 file_format_version: i32,
1103) -> Result<Option<Vec<TaskItem>>, MuninError> {
1104 let count = read_7bit_count(reader, "task-item count")?;
1105 if count == 0 {
1106 return Ok(None);
1107 }
1108 let mut items = Vec::with_capacity(count);
1109 for _ in 0..count {
1110 items.push(read_task_item(
1111 reader,
1112 strings,
1113 nvl_table,
1114 file_format_version,
1115 )?);
1116 }
1117 Ok(Some(items))
1118}
1119
1120fn read_project_items(
1127 reader: &mut impl Read,
1128 strings: &StringTable,
1129 nvl_table: &NameValueListTable,
1130 file_format_version: i32,
1131) -> Result<Option<Vec<ItemGroup>>, MuninError> {
1132 if file_format_version < 10 {
1133 let count = read_7bit_count(reader, "item count")?;
1134 if count == 0 {
1135 return Ok(None);
1136 }
1137 let mut groups: Vec<ItemGroup> = Vec::new();
1138 let mut group_index: std::collections::HashMap<String, usize> =
1139 std::collections::HashMap::new();
1140 for _ in 0..count {
1141 let item_name = read_dotnet_string_via_reader(reader)?;
1142 let item = read_task_item(reader, strings, nvl_table, file_format_version)?;
1143 if let Some(&idx) = group_index.get(&item_name) {
1145 groups[idx].items.push(item);
1146 } else {
1147 let idx = groups.len();
1148 group_index.insert(item_name.clone(), idx);
1149 groups.push(ItemGroup {
1150 item_type: item_name,
1151 items: vec![item],
1152 });
1153 }
1154 }
1155 Ok(Some(groups))
1156 } else if file_format_version < 12 {
1157 let count = read_7bit_count(reader, "item-group count")?;
1158 if count == 0 {
1159 return Ok(None);
1160 }
1161 let mut groups = Vec::with_capacity(count);
1162 for _ in 0..count {
1163 let item_type = read_dedup_string(reader, strings)?.unwrap_or_default();
1164 let items = read_task_item_list(reader, strings, nvl_table, file_format_version)?
1165 .unwrap_or_default();
1166 groups.push(ItemGroup { item_type, items });
1167 }
1168 if groups.is_empty() {
1169 Ok(None)
1170 } else {
1171 Ok(Some(groups))
1172 }
1173 } else {
1174 let mut groups = Vec::new();
1176 loop {
1177 let item_type = read_dedup_string(reader, strings)?.unwrap_or_default();
1178 if item_type.is_empty() {
1179 break;
1180 }
1181 let items = read_task_item_list(reader, strings, nvl_table, file_format_version)?
1182 .unwrap_or_default();
1183 groups.push(ItemGroup { item_type, items });
1184 }
1185 if groups.is_empty() {
1186 Ok(None)
1187 } else {
1188 Ok(Some(groups))
1189 }
1190 }
1191}
1192
1193fn read_dotnet_string_via_reader(reader: &mut impl Read) -> Result<String, MuninError> {
1195 crate::primitives::read_dotnet_string(reader)
1196}
1197
1198fn read_evaluation_location(
1200 reader: &mut impl Read,
1201 strings: &StringTable,
1202 file_format_version: i32,
1203) -> Result<EvaluationLocation, MuninError> {
1204 let element_name = read_optional_string(reader, strings, file_format_version)?;
1205 let description = read_optional_string(reader, strings, file_format_version)?;
1206 let evaluation_description = read_optional_string(reader, strings, file_format_version)?;
1207 let file = read_optional_string(reader, strings, file_format_version)?;
1208 let kind = read_7bit_int(reader)?;
1209 let evaluation_pass = read_7bit_int(reader)?;
1210
1211 let line = if read_bool(reader)? {
1212 Some(read_7bit_int(reader)?)
1213 } else {
1214 None
1215 };
1216
1217 let (id, parent_id) = if file_format_version > 5 {
1219 let id = crate::primitives::read_i64_le(reader)?;
1220 let parent_id = if read_bool(reader)? {
1221 Some(crate::primitives::read_i64_le(reader)?)
1222 } else {
1223 None
1224 };
1225 (id, parent_id)
1226 } else {
1227 (0, None)
1228 };
1229
1230 Ok(EvaluationLocation {
1231 element_name,
1232 description,
1233 evaluation_description,
1234 file,
1235 kind,
1236 evaluation_pass,
1237 line,
1238 id,
1239 parent_id,
1240 })
1241}
1242
1243fn read_profiled_location(reader: &mut impl Read) -> Result<ProfiledLocation, MuninError> {
1245 let number_of_hits = read_7bit_int(reader)?;
1246 let exclusive_time_ticks = crate::primitives::read_i64_le(reader)?;
1247 let inclusive_time_ticks = crate::primitives::read_i64_le(reader)?;
1248 Ok(ProfiledLocation {
1249 number_of_hits,
1250 exclusive_time_ticks,
1251 inclusive_time_ticks,
1252 })
1253}
1254
1255fn write_diagnostic_fields<W: Write>(
1260 w: &mut W,
1261 ctx: &mut WriteContext,
1262 loc: &DiagnosticLocation,
1263) -> std::io::Result<()> {
1264 write_optional_string(w, ctx, loc.subcategory.as_deref())?;
1265 write_optional_string(w, ctx, loc.code.as_deref())?;
1266 write_optional_string(w, ctx, loc.file.as_deref())?;
1267 write_optional_string(w, ctx, loc.project_file.as_deref())?;
1268 write_7bit_int(w, loc.line_number)?;
1269 write_7bit_int(w, loc.column_number)?;
1270 write_7bit_int(w, loc.end_line_number)?;
1271 write_7bit_int(w, loc.end_column_number)
1272}
1273
1274fn write_string_list<W: Write>(
1275 w: &mut W,
1276 ctx: &mut WriteContext,
1277 list: Option<&[String]>,
1278) -> std::io::Result<()> {
1279 match list {
1280 None => write_7bit_int(w, 0),
1281 Some(items) => {
1282 write_7bit_int(w, items.len() as i32)?;
1283 for s in items {
1284 write_dedup_string(w, ctx, Some(s))?;
1285 }
1286 Ok(())
1287 }
1288 }
1289}
1290
1291fn write_task_item<W: Write>(
1292 w: &mut W,
1293 ctx: &mut WriteContext,
1294 item: &TaskItem,
1295) -> std::io::Result<()> {
1296 write_dedup_string(w, ctx, item.item_spec.as_deref())?;
1297 write_string_dictionary(w, ctx, item.metadata.as_deref())
1298}
1299
1300fn write_task_item_list<W: Write>(
1301 w: &mut W,
1302 ctx: &mut WriteContext,
1303 items: Option<&[TaskItem]>,
1304) -> std::io::Result<()> {
1305 match items {
1306 None => write_7bit_int(w, 0),
1307 Some(items) => {
1308 write_7bit_int(w, items.len() as i32)?;
1309 for it in items {
1310 write_task_item(w, ctx, it)?;
1311 }
1312 Ok(())
1313 }
1314 }
1315}
1316
1317fn write_project_items<W: Write>(
1318 w: &mut W,
1319 ctx: &mut WriteContext,
1320 items: Option<&[ItemGroup]>,
1321) -> std::io::Result<()> {
1322 let v = ctx.file_format_version;
1323 if v < 10 {
1324 let total: usize = items
1325 .map(|g| g.iter().map(|gr| gr.items.len()).sum())
1326 .unwrap_or(0);
1327 write_7bit_int(w, total as i32)?;
1328 if let Some(groups) = items {
1329 for g in groups {
1330 for it in &g.items {
1331 write_dotnet_string(w, &g.item_type)?;
1332 write_task_item(w, ctx, it)?;
1333 }
1334 }
1335 }
1336 Ok(())
1337 } else if v < 12 {
1338 match items {
1339 None => write_7bit_int(w, 0),
1340 Some(groups) => {
1341 write_7bit_int(w, groups.len() as i32)?;
1342 for g in groups {
1343 write_dedup_string(w, ctx, Some(&g.item_type))?;
1344 write_task_item_list(w, ctx, Some(&g.items))?;
1345 }
1346 Ok(())
1347 }
1348 }
1349 } else {
1350 if let Some(groups) = items {
1352 for g in groups {
1353 write_dedup_string(w, ctx, Some(&g.item_type))?;
1354 write_task_item_list(w, ctx, Some(&g.items))?;
1355 }
1356 }
1357 write_dedup_string(w, ctx, Some(""))
1360 }
1361}
1362
1363fn write_evaluation_location<W: Write>(
1364 w: &mut W,
1365 ctx: &mut WriteContext,
1366 loc: &EvaluationLocation,
1367) -> std::io::Result<()> {
1368 write_optional_string(w, ctx, loc.element_name.as_deref())?;
1369 write_optional_string(w, ctx, loc.description.as_deref())?;
1370 write_optional_string(w, ctx, loc.evaluation_description.as_deref())?;
1371 write_optional_string(w, ctx, loc.file.as_deref())?;
1372 write_7bit_int(w, loc.kind)?;
1373 write_7bit_int(w, loc.evaluation_pass)?;
1374 match loc.line {
1375 Some(line) => {
1376 write_bool(w, true)?;
1377 write_7bit_int(w, line)?;
1378 }
1379 None => write_bool(w, false)?,
1380 }
1381 if ctx.file_format_version > 5 {
1382 write_i64_le(w, loc.id)?;
1383 match loc.parent_id {
1384 Some(pid) => {
1385 write_bool(w, true)?;
1386 write_i64_le(w, pid)?;
1387 }
1388 None => write_bool(w, false)?,
1389 }
1390 }
1391 Ok(())
1392}
1393
1394fn write_profiled_location<W: Write>(w: &mut W, pl: &ProfiledLocation) -> std::io::Result<()> {
1395 write_7bit_int(w, pl.number_of_hits)?;
1396 write_i64_le(w, pl.exclusive_time_ticks)?;
1397 write_i64_le(w, pl.inclusive_time_ticks)
1398}
1399
1400pub fn write_build_started<W: Write>(
1402 w: &mut W,
1403 ctx: &mut WriteContext,
1404 ev: &BuildStartedEvent,
1405) -> std::io::Result<()> {
1406 write_build_event_args_fields(w, ctx, &ev.fields, false)?;
1407 write_string_dictionary(w, ctx, ev.environment.as_deref())
1408}
1409
1410pub fn write_build_finished<W: Write>(
1412 w: &mut W,
1413 ctx: &mut WriteContext,
1414 ev: &BuildFinishedEvent,
1415) -> std::io::Result<()> {
1416 write_build_event_args_fields(w, ctx, &ev.fields, false)?;
1417 write_bool(w, ev.succeeded)
1418}
1419
1420pub fn write_project_started<W: Write>(
1422 w: &mut W,
1423 ctx: &mut WriteContext,
1424 ev: &ProjectStartedEvent,
1425) -> std::io::Result<()> {
1426 write_build_event_args_fields(w, ctx, &ev.fields, false)?;
1427 match &ev.parent_context {
1428 Some(pc) => {
1429 write_bool(w, true)?;
1430 write_build_event_context(w, pc, ctx.file_format_version)?;
1431 }
1432 None => write_bool(w, false)?,
1433 }
1434 write_optional_string(w, ctx, ev.project_file.as_deref())?;
1435 write_7bit_int(w, ev.project_id)?;
1436 write_dedup_string(w, ctx, ev.target_names.as_deref())?;
1437 write_optional_string(w, ctx, ev.tools_version.as_deref())?;
1438
1439 let v = ctx.file_format_version;
1440 if v > 6 {
1441 if v >= 18 {
1442 write_string_dictionary(w, ctx, ev.global_properties.as_deref())?;
1443 } else {
1444 match &ev.global_properties {
1445 Some(gp) => {
1446 write_bool(w, true)?;
1447 write_string_dictionary(w, ctx, Some(gp))?;
1448 }
1449 None => write_bool(w, false)?,
1450 }
1451 }
1452 }
1453 write_string_dictionary(w, ctx, ev.property_list.as_deref())?;
1454 write_project_items(w, ctx, ev.item_list.as_deref())
1455}
1456
1457pub fn write_project_finished<W: Write>(
1459 w: &mut W,
1460 ctx: &mut WriteContext,
1461 ev: &ProjectFinishedEvent,
1462) -> std::io::Result<()> {
1463 write_build_event_args_fields(w, ctx, &ev.fields, false)?;
1464 write_optional_string(w, ctx, ev.project_file.as_deref())?;
1465 write_bool(w, ev.succeeded)
1466}
1467
1468pub fn write_target_started<W: Write>(
1470 w: &mut W,
1471 ctx: &mut WriteContext,
1472 ev: &TargetStartedEvent,
1473) -> std::io::Result<()> {
1474 write_build_event_args_fields(w, ctx, &ev.fields, false)?;
1475 write_optional_string(w, ctx, ev.target_name.as_deref())?;
1476 write_optional_string(w, ctx, ev.project_file.as_deref())?;
1477 write_optional_string(w, ctx, ev.target_file.as_deref())?;
1478 write_optional_string(w, ctx, ev.parent_target.as_deref())?;
1479 if ctx.file_format_version > 3 {
1480 write_7bit_int(w, ev.build_reason)?;
1481 }
1482 Ok(())
1483}
1484
1485pub fn write_target_finished<W: Write>(
1487 w: &mut W,
1488 ctx: &mut WriteContext,
1489 ev: &TargetFinishedEvent,
1490) -> std::io::Result<()> {
1491 write_build_event_args_fields(w, ctx, &ev.fields, false)?;
1492 write_bool(w, ev.succeeded)?;
1493 write_optional_string(w, ctx, ev.project_file.as_deref())?;
1494 write_optional_string(w, ctx, ev.target_file.as_deref())?;
1495 write_optional_string(w, ctx, ev.target_name.as_deref())?;
1496 write_task_item_list(w, ctx, ev.target_outputs.as_deref())
1497}
1498
1499pub fn write_target_skipped<W: Write>(
1501 w: &mut W,
1502 ctx: &mut WriteContext,
1503 ev: &TargetSkippedEvent,
1504) -> std::io::Result<()> {
1505 write_build_event_args_fields(w, ctx, &ev.fields, true)?;
1506 write_optional_string(w, ctx, ev.target_file.as_deref())?;
1507 write_optional_string(w, ctx, ev.target_name.as_deref())?;
1508 write_optional_string(w, ctx, ev.parent_target.as_deref())?;
1509
1510 let v = ctx.file_format_version;
1511 if v >= 13 {
1512 write_optional_string(w, ctx, ev.condition.as_deref())?;
1513 write_optional_string(w, ctx, ev.evaluated_condition.as_deref())?;
1514 write_bool(w, ev.originally_succeeded)?;
1515 }
1516 write_7bit_int(w, ev.build_reason)?;
1517 if v >= 14 {
1518 write_7bit_int(w, ev.skip_reason)?;
1519 match &ev.original_build_event_context {
1520 Some(bec) => {
1521 write_bool(w, true)?;
1522 write_build_event_context(w, bec, ctx.file_format_version)?;
1523 }
1524 None => write_bool(w, false)?,
1525 }
1526 }
1527 Ok(())
1528}
1529
1530pub fn write_task_started<W: Write>(
1532 w: &mut W,
1533 ctx: &mut WriteContext,
1534 ev: &TaskStartedEvent,
1535) -> std::io::Result<()> {
1536 write_build_event_args_fields(w, ctx, &ev.fields, false)?;
1537 write_optional_string(w, ctx, ev.task_name.as_deref())?;
1538 write_optional_string(w, ctx, ev.project_file.as_deref())?;
1539 write_optional_string(w, ctx, ev.task_file.as_deref())?;
1540 if ctx.file_format_version > 19 {
1541 write_optional_string(w, ctx, ev.task_assembly_location.as_deref())?;
1542 }
1543 Ok(())
1544}
1545
1546pub fn write_task_finished<W: Write>(
1548 w: &mut W,
1549 ctx: &mut WriteContext,
1550 ev: &TaskFinishedEvent,
1551) -> std::io::Result<()> {
1552 write_build_event_args_fields(w, ctx, &ev.fields, false)?;
1553 write_bool(w, ev.succeeded)?;
1554 write_optional_string(w, ctx, ev.task_name.as_deref())?;
1555 write_optional_string(w, ctx, ev.project_file.as_deref())?;
1556 write_optional_string(w, ctx, ev.task_file.as_deref())
1557}
1558
1559pub fn write_task_command_line<W: Write>(
1561 w: &mut W,
1562 ctx: &mut WriteContext,
1563 ev: &TaskCommandLineEvent,
1564) -> std::io::Result<()> {
1565 write_build_event_args_fields(w, ctx, &ev.fields, true)?;
1566 write_optional_string(w, ctx, ev.command_line.as_deref())?;
1567 write_optional_string(w, ctx, ev.task_name.as_deref())
1568}
1569
1570pub fn write_task_parameter<W: Write>(
1572 w: &mut W,
1573 ctx: &mut WriteContext,
1574 ev: &TaskParameterEvent,
1575) -> std::io::Result<()> {
1576 write_build_event_args_fields(w, ctx, &ev.fields, true)?;
1577 write_7bit_int(w, ev.kind)?;
1578 write_dedup_string(w, ctx, ev.item_type.as_deref())?;
1579 write_task_item_list(w, ctx, ev.items.as_deref())?;
1580 if ctx.file_format_version >= 21 {
1581 write_dedup_string(w, ctx, ev.parameter_name.as_deref())?;
1582 write_dedup_string(w, ctx, ev.property_name.as_deref())?;
1583 }
1584 Ok(())
1585}
1586
1587pub fn write_build_error<W: Write>(
1589 w: &mut W,
1590 ctx: &mut WriteContext,
1591 ev: &BuildErrorEvent,
1592) -> std::io::Result<()> {
1593 write_build_event_args_fields(w, ctx, &ev.fields, false)?;
1594 write_diagnostic_fields(w, ctx, &ev.location)
1595}
1596
1597pub fn write_build_warning<W: Write>(
1599 w: &mut W,
1600 ctx: &mut WriteContext,
1601 ev: &BuildWarningEvent,
1602) -> std::io::Result<()> {
1603 write_build_event_args_fields(w, ctx, &ev.fields, false)?;
1604 write_diagnostic_fields(w, ctx, &ev.location)
1605}
1606
1607pub fn write_build_message<W: Write>(
1609 w: &mut W,
1610 ctx: &mut WriteContext,
1611 ev: &BuildMessageEvent,
1612) -> std::io::Result<()> {
1613 write_build_event_args_fields(w, ctx, &ev.fields, true)
1614}
1615
1616pub fn write_critical_build_message<W: Write>(
1618 w: &mut W,
1619 ctx: &mut WriteContext,
1620 ev: &CriticalBuildMessageEvent,
1621) -> std::io::Result<()> {
1622 write_build_event_args_fields(w, ctx, &ev.fields, true)
1623}
1624
1625pub fn write_project_evaluation_started<W: Write>(
1627 w: &mut W,
1628 ctx: &mut WriteContext,
1629 ev: &ProjectEvaluationStartedEvent,
1630) -> std::io::Result<()> {
1631 write_build_event_args_fields(w, ctx, &ev.fields, false)?;
1632 write_dedup_string(w, ctx, ev.project_file.as_deref())
1633}
1634
1635pub fn write_project_evaluation_finished<W: Write>(
1637 w: &mut W,
1638 ctx: &mut WriteContext,
1639 ev: &ProjectEvaluationFinishedEvent,
1640) -> std::io::Result<()> {
1641 write_build_event_args_fields(w, ctx, &ev.fields, false)?;
1642 write_dedup_string(w, ctx, ev.project_file.as_deref())?;
1643
1644 let v = ctx.file_format_version;
1645 if v >= 12 {
1646 if v >= 18 {
1647 write_string_dictionary(w, ctx, ev.global_properties.as_deref())?;
1648 } else {
1649 match &ev.global_properties {
1650 Some(gp) => {
1651 write_bool(w, true)?;
1652 write_string_dictionary(w, ctx, Some(gp))?;
1653 }
1654 None => write_bool(w, false)?,
1655 }
1656 }
1657 write_string_dictionary(w, ctx, ev.property_list.as_deref())?;
1658 write_project_items(w, ctx, ev.item_list.as_deref())?;
1659 }
1660
1661 if v > 4 {
1662 write_bool(w, ev.has_profile_data)?;
1663 if ev.has_profile_data {
1664 let entries = ev.profile_data.as_deref().unwrap_or(&[]);
1665 write_7bit_int(w, entries.len() as i32)?;
1666 for e in entries {
1667 write_evaluation_location(w, ctx, &e.location)?;
1668 write_profiled_location(w, &e.profiled_location)?;
1669 }
1670 }
1671 }
1672 Ok(())
1673}
1674
1675pub fn write_property_reassignment<W: Write>(
1677 w: &mut W,
1678 ctx: &mut WriteContext,
1679 ev: &PropertyReassignmentEvent,
1680) -> std::io::Result<()> {
1681 write_build_event_args_fields(w, ctx, &ev.fields, true)?;
1682 write_dedup_string(w, ctx, ev.property_name.as_deref())?;
1683 write_dedup_string(w, ctx, ev.previous_value.as_deref())?;
1684 write_dedup_string(w, ctx, ev.new_value.as_deref())?;
1685 write_dedup_string(w, ctx, ev.location.as_deref())
1686}
1687
1688pub fn write_uninitialized_property_read<W: Write>(
1690 w: &mut W,
1691 ctx: &mut WriteContext,
1692 ev: &UninitializedPropertyReadEvent,
1693) -> std::io::Result<()> {
1694 write_build_event_args_fields(w, ctx, &ev.fields, true)?;
1695 write_dedup_string(w, ctx, ev.property_name.as_deref())
1696}
1697
1698pub fn write_property_initial_value_set<W: Write>(
1700 w: &mut W,
1701 ctx: &mut WriteContext,
1702 ev: &PropertyInitialValueSetEvent,
1703) -> std::io::Result<()> {
1704 write_build_event_args_fields(w, ctx, &ev.fields, true)?;
1705 write_dedup_string(w, ctx, ev.property_name.as_deref())?;
1706 write_dedup_string(w, ctx, ev.property_value.as_deref())?;
1707 write_dedup_string(w, ctx, ev.property_source.as_deref())
1708}
1709
1710pub fn write_environment_variable_read<W: Write>(
1712 w: &mut W,
1713 ctx: &mut WriteContext,
1714 ev: &EnvironmentVariableReadEvent,
1715) -> std::io::Result<()> {
1716 write_build_event_args_fields(w, ctx, &ev.fields, true)?;
1717 write_dedup_string(w, ctx, ev.environment_variable_name.as_deref())?;
1718 if ctx.file_format_version >= 22 {
1719 write_7bit_int(w, ev.line)?;
1720 write_7bit_int(w, ev.column)?;
1721 write_dedup_string(w, ctx, ev.file_name.as_deref())?;
1722 }
1723 Ok(())
1724}
1725
1726pub fn write_response_file_used<W: Write>(
1728 w: &mut W,
1729 ctx: &mut WriteContext,
1730 ev: &ResponseFileUsedEvent,
1731) -> std::io::Result<()> {
1732 write_build_event_args_fields(w, ctx, &ev.fields, false)?;
1733 write_dedup_string(w, ctx, ev.response_file_path.as_deref())
1734}
1735
1736pub fn write_assembly_load<W: Write>(
1738 w: &mut W,
1739 ctx: &mut WriteContext,
1740 ev: &AssemblyLoadEvent,
1741) -> std::io::Result<()> {
1742 write_build_event_args_fields(w, ctx, &ev.fields, false)?;
1743 write_7bit_int(w, ev.context)?;
1744 write_dedup_string(w, ctx, ev.loading_initiator.as_deref())?;
1745 write_dedup_string(w, ctx, ev.assembly_name.as_deref())?;
1746 write_dedup_string(w, ctx, ev.assembly_path.as_deref())?;
1747 write_guid(w, &ev.mvid)?;
1748 write_dedup_string(w, ctx, ev.app_domain_name.as_deref())
1749}
1750
1751pub fn write_project_imported<W: Write>(
1753 w: &mut W,
1754 ctx: &mut WriteContext,
1755 ev: &ProjectImportedEvent,
1756) -> std::io::Result<()> {
1757 write_build_event_args_fields(w, ctx, &ev.fields, true)?;
1758 if ctx.file_format_version > 2 {
1759 write_bool(w, ev.import_ignored)?;
1760 }
1761 write_optional_string(w, ctx, ev.imported_project_file.as_deref())?;
1762 write_optional_string(w, ctx, ev.unexpanded_project.as_deref())
1763}
1764
1765pub fn write_build_check_tracing<W: Write>(
1767 w: &mut W,
1768 ctx: &mut WriteContext,
1769 ev: &BuildCheckTracingEvent,
1770) -> std::io::Result<()> {
1771 write_build_event_args_fields(w, ctx, &ev.fields, false)?;
1772 write_string_dictionary(w, ctx, ev.tracing_data.as_deref())
1773}
1774
1775pub fn write_build_check_acquisition<W: Write>(
1777 w: &mut W,
1778 ctx: &mut WriteContext,
1779 ev: &BuildCheckAcquisitionEvent,
1780) -> std::io::Result<()> {
1781 write_build_event_args_fields(w, ctx, &ev.fields, false)?;
1782 write_dotnet_string(w, &ev.acquisition_path)?;
1783 write_dotnet_string(w, &ev.project_path)
1784}
1785
1786pub fn write_build_submission_started<W: Write>(
1788 w: &mut W,
1789 ctx: &mut WriteContext,
1790 ev: &BuildSubmissionStartedEvent,
1791) -> std::io::Result<()> {
1792 write_build_event_args_fields(w, ctx, &ev.fields, false)?;
1793 write_string_dictionary(w, ctx, ev.global_properties.as_deref())?;
1794 write_string_list(w, ctx, ev.entry_projects_full_path.as_deref())?;
1795 write_string_list(w, ctx, ev.target_names.as_deref())?;
1796 write_7bit_int(w, ev.flags)?;
1797 write_7bit_int(w, ev.submission_id)
1798}
1799
1800pub fn write_build_canceled<W: Write>(
1802 w: &mut W,
1803 ctx: &mut WriteContext,
1804 ev: &BuildCanceledEvent,
1805) -> std::io::Result<()> {
1806 write_build_event_args_fields(w, ctx, &ev.fields, false)
1807}
1808
1809#[cfg(test)]
1810mod tests;
1811
1812#[cfg(test)]
1813mod write_tests;