1use csv::ByteRecord;
2use std::cmp::max;
3
4#[derive(Debug, Default)]
7pub struct HeadersParsed {
8 pub(crate) headers_left: Option<csv::Result<ByteRecord>>,
9 pub(crate) headers_right: Option<csv::Result<ByteRecord>>,
10}
11
12impl HeadersParsed {
13 pub(crate) fn new(
14 headers_left: Option<csv::Result<ByteRecord>>,
15 headers_right: Option<csv::Result<ByteRecord>>,
16 ) -> Self {
17 Self {
18 headers_left,
19 headers_right,
20 }
21 }
22
23 pub fn headers_left(&self) -> Option<Result<&ByteRecord, &csv::Error>> {
27 Some(self.headers_left.as_ref()?.as_ref())
28 }
29
30 pub fn headers_right(&self) -> Option<Result<&ByteRecord, &csv::Error>> {
34 Some(self.headers_right.as_ref()?.as_ref())
35 }
36
37 pub(crate) fn max_num_cols(&self) -> Option<usize> {
38 max(
39 self.headers_left()
40 .and_then(|hl| hl.as_ref().map(|csv| csv.len()).ok()),
41 self.headers_right()
42 .and_then(|hr| hr.as_ref().map(|csv| csv.len()).ok()),
43 )
44 }
45}
46
47impl
48 From<(
49 Option<csv::Result<ByteRecord>>,
50 Option<csv::Result<ByteRecord>>,
51 )> for HeadersParsed
52{
53 fn from(
54 (headers_left, headers_right): (
55 Option<csv::Result<ByteRecord>>,
56 Option<csv::Result<ByteRecord>>,
57 ),
58 ) -> Self {
59 Self::new(headers_left, headers_right)
60 }
61}
62
63#[derive(Debug, Default, PartialEq, Clone)]
66pub struct Headers {
67 pub(crate) headers_left: Option<ByteRecord>,
68 pub(crate) headers_right: Option<ByteRecord>,
69}
70impl Headers {
71 pub(crate) fn new(headers_left: Option<ByteRecord>, headers_right: Option<ByteRecord>) -> Self {
72 Self {
73 headers_left,
74 headers_right,
75 }
76 }
77
78 pub fn headers_left(&self) -> Option<&ByteRecord> {
82 self.headers_left.as_ref()
83 }
84
85 pub fn headers_right(&self) -> Option<&ByteRecord> {
89 self.headers_right.as_ref()
90 }
91
92 pub(crate) fn max_num_cols(&self) -> Option<usize> {
93 max(
94 self.headers_left().map(|hl| hl.len()),
95 self.headers_right().map(|hr| hr.len()),
96 )
97 }
98}
99
100impl From<(Option<ByteRecord>, Option<ByteRecord>)> for Headers {
101 fn from((headers_left, headers_right): (Option<ByteRecord>, Option<ByteRecord>)) -> Self {
102 Self::new(headers_left, headers_right)
103 }
104}
105
106impl TryFrom<HeadersParsed> for Headers {
107 type Error = csv::Error;
108
109 fn try_from(value: HeadersParsed) -> Result<Self, Self::Error> {
110 Ok((
111 value.headers_left.transpose()?,
112 value.headers_right.transpose()?,
113 )
114 .into())
115 }
116}