minimap2_paf_io/output/
mod.rs1use crate::data::{
2 AlignmentDifference, AlignmentType, Cigar, CigarColumn, DifferenceColumn, PAFLine,
3};
4use std::fmt::{Display, Formatter};
5
6impl Display for PAFLine {
7 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
8 write!(f, "{}", self.query_sequence_name)?;
10 write!(f, "\t{}", self.query_sequence_length)?;
11 write!(f, "\t{}", self.query_start_coordinate)?;
12 write!(f, "\t{}", self.query_end_coordinate)?;
13 write!(f, "\t{}", if self.strand { '+' } else { '-' })?;
14 write!(f, "\t{}", self.target_sequence_name)?;
15 write!(f, "\t{}", self.target_sequence_length)?;
16 write!(f, "\t{}", self.target_start_coordinate_on_original_strand)?;
17 write!(f, "\t{}", self.target_end_coordinate_on_original_strand)?;
18 write!(f, "\t{}", self.number_of_matching_bases)?;
19 write!(f, "\t{}", self.number_of_bases_and_gaps)?;
20 write!(f, "\t{}", self.mapping_quality)?;
21
22 if let Some(x) = self.total_number_of_mismatches_and_gaps {
24 write!(f, "\tNM:i:{x}")?;
25 }
26 if let Some(x) = self.best_segment_dp_score {
27 write!(f, "\tms:i:{x}")?;
28 }
29 if let Some(x) = self.dp_alignment_score {
30 write!(f, "\tAS:i:{x}")?;
31 }
32 if let Some(x) = self.number_of_ambiguous_bases {
33 write!(f, "\tnn:i:{x}")?;
34 }
35 if let Some(x) = &self.alignment_type {
36 write!(f, "\ttp:A:{x}")?;
37 }
38 if let Some(x) = self.number_of_minimisers {
39 write!(f, "\tcm:i:{x}")?;
40 }
41 if let Some(x) = self.chaining_score {
42 write!(f, "\ts1:i:{x}")?;
43 }
44 if let Some(x) = self.best_secondary_chaining_score {
45 write!(f, "\ts2:i:{x}")?;
46 }
47 if let Some(x) = self.gap_compressed_per_base_sequence_divergence {
48 write!(f, "\tde:f:{x}")?;
49 }
50 if let Some(x) = self.length_of_query_regions_with_repetitive_seeds {
51 write!(f, "\trl:i:{x}")?;
52 }
53
54 if let Some(x) = &self.unknown_md {
57 write!(f, "\tMD:Z:{x}")?;
58 }
59 if let Some(x) = &self.supplementary_alignments {
60 write!(f, "\tSA:Z:{x}")?;
61 }
62 if let Some(x) = &self.transcript_strand {
63 write!(f, "\tts:A:{x}")?;
64 }
65 if let Some(x) = &self.cigar_string {
66 write!(f, "\tcg:Z:{x}")?;
67 }
68 if let Some(x) = &self.difference_string {
69 write!(f, "\tcs:Z:{x}")?;
70 }
71 if let Some(x) = self.approximate_per_base_sequence_divergence {
72 write!(f, "\tdv:f:{x}")?;
73 }
74
75 for unknown_field in &self.unknown_fields {
77 write!(f, "\t{unknown_field}")?;
78 }
79
80 Ok(())
81 }
82}
83
84impl Display for AlignmentType {
85 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
86 write!(
87 f,
88 "{}",
89 match self {
90 AlignmentType::Primary => "P",
91 AlignmentType::Secondary => "S",
92 AlignmentType::PrimaryInversion => "I",
93 AlignmentType::SecondaryInversion => "i",
94 }
95 )
96 }
97}
98
99impl Display for Cigar {
100 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
101 for cigar_column in &self.0 {
102 write!(
103 f,
104 "{}{}",
105 match cigar_column {
106 CigarColumn::Match(length)
107 | CigarColumn::Insertion(length)
108 | CigarColumn::Deletion(length)
109 | CigarColumn::Mismatch(length) => length,
110 },
111 match cigar_column {
112 CigarColumn::Match(_) => "M",
113 CigarColumn::Insertion(_) => "I",
114 CigarColumn::Deletion(_) => "D",
115 CigarColumn::Mismatch(_) => "X",
116 }
117 )?;
118 }
119
120 Ok(())
121 }
122}
123
124impl Display for AlignmentDifference {
125 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
126 for difference_column in &self.0 {
127 match difference_column {
128 DifferenceColumn::Match { length } => write!(f, ":{length}")?,
129 DifferenceColumn::Insertion {
130 superfluous_query_characters,
131 } => write!(f, "+{superfluous_query_characters}")?,
132 DifferenceColumn::Deletion {
133 missing_query_characters,
134 } => write!(f, "-{missing_query_characters}")?,
135 DifferenceColumn::Mismatch { reference, query } => {
136 write!(f, "*{reference}{query}")?
137 }
138 }
139 }
140
141 Ok(())
142 }
143}