1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
use crate::diff_row::*;
#[derive(Debug, PartialEq)]
pub struct DiffByteRecords(pub(crate) Vec<DiffByteRecord>);
impl DiffByteRecords {
pub fn sort_by_line(&mut self) {
self.0.sort_by(|a, b| match (a.line_num(), b.line_num()) {
(LineNum::OneSide(line_num_a), LineNum::OneSide(line_num_b)) => {
line_num_a.cmp(&line_num_b)
}
(
LineNum::OneSide(line_num_a),
LineNum::BothSides {
for_deleted,
for_added,
},
) => line_num_a.cmp(if for_deleted < for_added {
&for_deleted
} else {
&for_added
}),
(
LineNum::BothSides {
for_deleted,
for_added,
},
LineNum::OneSide(line_num_b),
) => if for_deleted < for_added {
&for_deleted
} else {
&for_added
}
.cmp(&line_num_b),
(
LineNum::BothSides {
for_deleted: for_deleted_a,
for_added: for_added_a,
},
LineNum::BothSides {
for_deleted: for_deleted_b,
for_added: for_added_b,
},
) => if for_deleted_a < for_added_a {
&for_deleted_a
} else {
&for_added_a
}
.cmp(if for_deleted_b < for_added_b {
&for_deleted_b
} else {
&for_added_b
}),
})
}
#[cfg_attr(
feature = "rayon-threads",
doc = r##"
use std::io::Cursor;
use csv_diff::{csv_diff::CsvByteDiff, csv::Csv};
use std::collections::HashSet;
use std::iter::FromIterator;
# fn main() -> Result<(), Box<dyn std::error::Error>> {
// some csv data with a header, where the first column is a unique id
let csv_data_left = "id,name,kind\n\
1,lemon,fruit\n\
2,strawberry,fruit";
let csv_data_right = "id,name,kind\n\
1,lemon,fruit\n\
2,strawberry,nut\n\
3,cherry,fruit";
let csv_byte_diff = CsvByteDiff::new()?;
let mut diff_byte_records = csv_byte_diff.diff(
Csv::new(Cursor::new(csv_data_left.as_bytes())),
Csv::new(Cursor::new(csv_data_right.as_bytes())),
)?;
let diff_byte_record_slice = diff_byte_records.as_slice();
assert_eq!(
diff_byte_record_slice.len(),
2
);
Ok(())
# }
"##
)]
pub fn as_slice(&self) -> &[DiffByteRecord] {
self.0.as_slice()
}
pub fn iter(&self) -> core::slice::Iter<'_, DiffByteRecord> {
self.0.iter()
}
}
impl IntoIterator for DiffByteRecords {
type Item = DiffByteRecord;
type IntoIter = DiffByteRecordsIntoIterator;
fn into_iter(self) -> Self::IntoIter {
DiffByteRecordsIntoIterator {
inner: self.0.into_iter(),
}
}
}
pub struct DiffByteRecordsIntoIterator {
inner: std::vec::IntoIter<DiffByteRecord>,
}
impl Iterator for DiffByteRecordsIntoIterator {
type Item = DiffByteRecord;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
}