rust_pgdatadiff/diff/table/query/output/
mod.rs1use colored::{ColoredString, Colorize};
2use std::fmt::Display;
3
4use crate::diff::diff_output::DiffOutput;
5use crate::diff::types::DiffOutputMarker;
6use std::time::Duration;
7
8#[cfg_attr(test, derive(PartialEq))]
10#[derive(Debug, Clone)]
11pub enum TableSource {
12 First,
13 Second,
14}
15
16impl Display for TableSource {
17 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18 match self {
19 Self::First => write!(f, "first"),
20 Self::Second => write!(f, "second"),
21 }
22 }
23}
24
25#[cfg_attr(test, derive(PartialEq))]
27#[derive(Debug, Clone)]
28pub struct TableCountDiff(i64, i64);
29
30impl TableCountDiff {
31 pub fn new(first: i64, second: i64) -> Self {
33 Self(first, second)
34 }
35
36 pub fn first(&self) -> i64 {
37 self.0
38 }
39
40 pub fn second(&self) -> i64 {
41 self.1
42 }
43}
44
45#[cfg_attr(test, derive(PartialEq))]
47#[derive(Debug, Clone)]
48pub enum TableDiffOutput {
49 NoCountDiff(String, i64),
51 NoDiffWithDuration(String, Duration),
53 NotExists(String, TableSource),
55 Diff(String, TableCountDiff),
57 NoPrimaryKeyFound(String),
59 DataDiffWithDuration(String, i64, i64, Duration),
61}
62
63impl TableDiffOutput {
64 pub fn skip_table_diff(&self) -> bool {
66 matches!(self, Self::Diff(_, _) | Self::NotExists(_, _))
67 }
68
69 pub fn to_string(&self) -> ColoredString {
71 match self {
72 Self::NoCountDiff(table, count) => {
73 format!("{} - No difference. Total rows: {}", table, count)
74 .green()
75 .bold()
76 }
77 Self::NotExists(table, source) => format!("{} - Does not exist in {}", table, source)
78 .red()
79 .bold()
80 .underline(),
81 Self::Diff(table, diffs) => format!(
82 "{} - First table rows: {}, Second table rows: {}",
83 table,
84 diffs.first(),
85 diffs.second()
86 )
87 .red()
88 .bold(),
89 TableDiffOutput::NoPrimaryKeyFound(table) => {
90 format!("{} - No primary key found", table).red().bold()
91 }
92 TableDiffOutput::NoDiffWithDuration(table, duration) => {
93 format!("{} - No difference in {}ms", table, duration.as_millis())
94 .green()
95 .bold()
96 }
97 TableDiffOutput::DataDiffWithDuration(table_name, position, offset, duration) => {
98 format!(
99 "{} - Data diff between rows [{},{}] - in {}ms",
100 table_name,
101 position,
102 offset,
103 duration.as_millis()
104 )
105 .red()
106 .bold()
107 }
108 }
109 }
110}
111
112impl DiffOutputMarker for TableDiffOutput {
113 fn convert(self) -> DiffOutput {
114 DiffOutput::TableDiff(self.clone())
115 }
116}
117
118impl From<TableDiffOutput> for DiffOutput {
119 fn from(val: TableDiffOutput) -> Self {
120 DiffOutput::TableDiff(val)
121 }
122}
123
124#[cfg(test)]
125mod tests {
126 use super::*;
127
128 #[test]
129 fn test_skip_table_when_needed() {
130 let no_count_diff = TableDiffOutput::NoCountDiff("test".to_string(), 1000);
131 let not_exists = TableDiffOutput::NotExists("test".to_string(), TableSource::First);
132 let diff = TableDiffOutput::Diff("test".to_string(), TableCountDiff::new(1, 2));
133 let no_primary_key = TableDiffOutput::NoPrimaryKeyFound("test".to_string());
134 let no_diff_with_duration =
135 TableDiffOutput::NoDiffWithDuration("test".to_string(), Duration::from_millis(1));
136 let data_diff_with_duration = TableDiffOutput::DataDiffWithDuration(
137 "test".to_string(),
138 1,
139 2,
140 Duration::from_millis(1),
141 );
142
143 assert!(not_exists.skip_table_diff());
144 assert!(diff.skip_table_diff());
145 assert!(!no_count_diff.skip_table_diff());
146 assert!(!no_primary_key.skip_table_diff());
147 assert!(!no_diff_with_duration.skip_table_diff());
148 assert!(!data_diff_with_duration.skip_table_diff());
149 }
150}