### is_ok_and Example Source: https://docs.rs/csv-diff/latest/csv_diff/type.Result.html Example demonstrating the `is_ok_and` method. ```rust let x: Result = Ok(2); assert_eq!(x.is_ok_and(|x| x > 1), true); let x: Result = Ok(0); assert_eq!(x.is_ok_and(|x| x > 1), false); let x: Result = Err("hey"); assert_eq!(x.is_ok_and(|x| x > 1), false); let x: Result = Ok("ownership".to_string()); assert_eq!(x.as_ref().is_ok_and(|x| x.len() > 1), true); println!("still alive {:?}", x); ``` -------------------------------- ### transpose Example Source: https://docs.rs/csv-diff/latest/csv_diff/type.Result.html Example demonstrating the `transpose` method for `Result, E>`. ```rust #[derive(Debug, Eq, PartialEq)] struct SomeErr; let x: Result, SomeErr> = Ok(Some(5)); let y: Option> = Some(Ok(5)); assert_eq!(x.transpose(), y); ``` -------------------------------- ### is_ok Example Source: https://docs.rs/csv-diff/latest/csv_diff/type.Result.html Example demonstrating the `is_ok` method. ```rust let x: Result = Ok(-3); assert_eq!(x.is_ok(), true); let x: Result = Err("Some error message"); assert_eq!(x.is_ok(), false); ``` -------------------------------- ### expect example (recommended message style) Source: https://docs.rs/csv-diff/latest/csv_diff/type.Result.html Provides an example of a recommended message style for expect, explaining why a certain condition is expected. ```rust let path = std::env::var("IMPORTANT_PATH") .expect("env variable `IMPORTANT_PATH` should be set by `wrapper_script.sh`"); ``` -------------------------------- ### flatten Example Source: https://docs.rs/csv-diff/latest/csv_diff/type.Result.html Example demonstrating the `flatten` method for `Result, E>`. ```rust let x: Result, u32> = Ok(Ok("hello")); assert_eq!(Ok("hello"), x.flatten()); let x: Result, u32> = Ok(Err(6)); assert_eq!(Err(6), x.flatten()); let x: Result, u32> = Err(6); assert_eq!(Err(6), x.flatten()); ``` -------------------------------- ### Example: create a CsvByteDiffLocal Source: https://docs.rs/csv-diff/latest/csv_diff/csv_diff/struct.CsvByteDiffLocalBuilder.html Example demonstrating how to create a CsvByteDiffLocal where column 1 and column 3 are treated as a compound primary key. ```rust use csv_diff::{csv_diff::{CsvByteDiffLocal, CsvByteDiffLocalBuilder}, csv::Csv}; use csv_diff::diff_row::{ByteRecordLineInfo, DiffByteRecord}; use std::collections::HashSet; use std::iter::FromIterator; // some csv data with a header, where the first column and third column represent a compound key let csv_data_left = "\ id,name,commit_sha\n\ 1,lemon,efae52\n\ 2,strawberry,a33411"; // this csv line is seen as "Deleted" and not "Modified" // because "id" and "commit_sha" are different and both columns // _together_ represent the primary key let csv_data_right = "\ id,name,commit_sha\n\ 1,lemon,efae52\n\ 2,strawberry,ddef23"; // this csv line is seen as "Added" and not "Modified", // because "id" and "commit_sha" are different and both columns // _together_ represent the primary key let csv_byte_diff = CsvByteDiffLocalBuilder::new() .primary_key_columns(vec![0usize, 2]) .build()?; let mut diff_byte_records = csv_byte_diff.diff( Csv::with_reader_seek(csv_data_left.as_bytes()), Csv::with_reader_seek(csv_data_right.as_bytes()), )?; diff_byte_records.sort_by_line(); let diff_byte_rows = diff_byte_records.as_slice(); assert_eq!( diff_byte_rows, &[ DiffByteRecord::Delete(ByteRecordLineInfo::new( csv::ByteRecord::from(vec!["2", "strawberry", "a33411"]), 3 )), DiffByteRecord::Add(ByteRecordLineInfo::new( csv::ByteRecord::from(vec!["2", "strawberry", "ddef23"]), 3 )) ] ); Ok(()) ``` -------------------------------- ### unwrap_or_default example Source: https://docs.rs/csv-diff/latest/csv_diff/type.Result.html Shows how `unwrap_or_default` can be used to get the `Ok` value or a default value if the `Result` is `Err`. This example converts strings to integers, using 0 as the default for invalid strings. ```Rust let good_year_from_input = "1909"; let bad_year_from_input = "190blarg"; let good_year = good_year_from_input.parse().unwrap_or_default(); let bad_year = bad_year_from_input.parse().unwrap_or_default(); assert_eq!(1909, good_year); assert_eq!(0, bad_year); ``` -------------------------------- ### cloned Example for &mut T Source: https://docs.rs/csv-diff/latest/csv_diff/type.Result.html Example demonstrating the `cloned` method for `Result<&mut T, E>`. ```rust let mut val = 12; let x: Result<&mut i32, i32> = Ok(&mut val); assert_eq!(x, Ok(&mut 12)); let cloned = x.cloned(); assert_eq!(cloned, Ok(12)); ``` -------------------------------- ### cloned Example Source: https://docs.rs/csv-diff/latest/csv_diff/type.Result.html Example demonstrating the `cloned` method for `Result<&T, E>`. ```rust let val = 12; let x: Result<&i32, i32> = Ok(&val); assert_eq!(x, Ok(&12)); let cloned = x.cloned(); assert_eq!(cloned, Ok(12)); ``` -------------------------------- ### copied Example for &mut T Source: https://docs.rs/csv-diff/latest/csv_diff/type.Result.html Example demonstrating the `copied` method for `Result<&mut T, E>`. ```rust let mut val = 12; let x: Result<&mut i32, i32> = Ok(&mut val); assert_eq!(x, Ok(&mut 12)); let copied = x.copied(); assert_eq!(copied, Ok(12)); ``` -------------------------------- ### copied Example Source: https://docs.rs/csv-diff/latest/csv_diff/type.Result.html Example demonstrating the `copied` method for `Result<&T, E>`. ```rust let val = 12; let x: Result<&i32, i32> = Ok(&val); assert_eq!(x, Ok(&12)); let copied = x.copied(); assert_eq!(copied, Ok(12)); ``` -------------------------------- ### into_ok example Source: https://docs.rs/csv-diff/latest/csv_diff/type.Result.html Demonstrates the usage of the experimental `into_ok` method, which returns the `Ok` value and is guaranteed not to panic. ```Rust fn only_good_news() -> Result { Ok("this is fine".into()) } let s: String = only_good_news().into_ok(); println!("{s}"); ``` -------------------------------- ### or() examples Source: https://docs.rs/csv-diff/latest/csv_diff/type.Result.html Illustrates the behavior of the `or` method. ```rust let x: Result = Ok(2); let y: Result = Err("late error"); assert_eq!(x.or(y), Ok(2)); let x: Result = Err("early error"); let y: Result = Ok(2); assert_eq!(x.or(y), Ok(2)); let x: Result = Err("not a 2"); let y: Result = Err("late error"); assert_eq!(x.or(y), Err("late error")); let x: Result = Ok(2); let y: Result = Ok(100); assert_eq!(x.or(y), Ok(2)); ``` -------------------------------- ### iter example Source: https://docs.rs/csv-diff/latest/csv_diff/type.Result.html Illustrates using iter to get an iterator over the contained value if the Result is Ok. ```rust let x: Result = Ok(7); assert_eq!(x.iter().next(), Some(&7)); let x: Result = Err("nothing!"); assert_eq!(x.iter().next(), None); ``` -------------------------------- ### is_err Example Source: https://docs.rs/csv-diff/latest/csv_diff/type.Result.html Example demonstrating the `is_err` method. ```rust let x: Result = Ok(-3); assert_eq!(x.is_err(), false); let x: Result = Err("Some error message"); assert_eq!(x.is_err(), true); ``` -------------------------------- ### Example: create a CsvByteDiffLocal, where column 1 and column 3 are treated as a compound primary key. Source: https://docs.rs/csv-diff/latest/src/csv_diff/csv_diff.rs.html This example shows how to configure `CsvByteDiffLocalBuilder` to use a compound primary key consisting of columns at index 1 and 3 for CSV comparison. ```rust use csv_diff::{csv_diff::{CsvByteDiffLocal, CsvByteDiffLocalBuilder}, csv::Csv}; use csv_diff::diff_row::{ByteRecordLineInfo, DiffByteRecord}; use std::collections::HashSet; use std::iter::FromIterator; # fn main() -> Result<(), Box> { ``` -------------------------------- ### File metadata example Source: https://docs.rs/csv-diff/latest/csv_diff/type.Result.html Shows how to use `and_then` with file metadata operations. ```rust use std::{io::ErrorKind, path::Path}; // Note: on Windows "/" maps to "C:\" let root_modified_time = Path::new("/").metadata().and_then(|md| md.modified()); assert!(root_modified_time.is_ok()); let should_fail = Path::new("/bad/path").metadata().and_then(|md| md.modified()); assert!(should_fail.is_err()); assert_eq!(should_fail.unwrap_err().kind(), ErrorKind::NotFound); ``` -------------------------------- ### Example: create CsvByteDiffLocal with default values and compare two CSVs byte-wise eagerly Source: https://docs.rs/csv-diff/latest/src/csv_diff/csv_diff.rs.html This example demonstrates how to create a `CsvByteDiffLocal` with default settings and then use it to compare two CSV byte strings. It highlights the use of `Csv::with_reader_seek` for handling CSV data that might not be directly seekable and asserts the expected difference in the output. ```rust use csv_diff::{csv_diff::CsvByteDiffLocal, csv::Csv}; use csv_diff::diff_row::{ByteRecordLineInfo, DiffByteRecord}; use std::collections::HashSet; use std::iter::FromIterator; # fn main() -> Result<(), Box> { // 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"; let csv_byte_diff = CsvByteDiffLocal::new()?; let mut diff_byte_records = csv_byte_diff.diff( Csv::with_reader_seek(csv_data_left.as_bytes()), Csv::with_reader_seek(csv_data_right.as_bytes()), )?; let diff_byte_rows = diff_byte_records.as_slice(); assert_eq!( diff_byte_rows, &[DiffByteRecord::Modify { delete: ByteRecordLineInfo::new( csv::ByteRecord::from(vec!["2", "strawberry", "fruit"]), 3 ), add: ByteRecordLineInfo::new(csv::ByteRecord::from(vec!["2", "strawberry", "nut"])), 3), field_indices: vec![2] }] ); Ok(()) # } ``` -------------------------------- ### Compound Primary Key Example Source: https://docs.rs/csv-diff/latest/src/csv_diff/csv_diff.rs.html This example shows how to define a compound primary key using two columns (column 0 and column 2) and then diff two CSV datasets. It highlights how records are identified as 'Deleted' or 'Added' based on the compound key. ```rust let csv_data_left = "\\ id,name,commit_sha\n\\ 1,lemon,efae52\n\\ 2,strawberry,a33411"; // this csv line is seen as "Deleted" and not "Modified" and not "Modified" // because "id" and "commit_sha" are different and both columns // _together_ represent the primary key let csv_data_right = "\\ id,name,commit_sha\n\\ 1,lemon,efae52\n\\ 2,strawberry,ddef23"; // this csv line is seen as "Added" and not "Modified", // because "id" and "commit_sha" are different and both columns // _together_ represent the primary key let csv_byte_diff = CsvByteDiffLocalBuilder::new() .primary_key_columns(vec![0usize, 2]) .build()?; let mut diff_byte_records = csv_byte_diff.diff( Csv::with_reader_seek(csv_data_left.as_bytes()), Csv::with_reader_seek(csv_data_right.as_bytes()), )?; diff_byte_records.sort_by_line(); let diff_byte_rows = diff_byte_records.as_slice(); assert_eq!( diff_byte_rows, &[ DiffByteRecord::Delete(ByteRecordLineInfo::new( csv::ByteRecord::from(vec!["2", "strawberry", "a33411"]), 3 ),), DiffByteRecord::Add(ByteRecordLineInfo::new( csv::ByteRecord::from(vec!["2", "strawberry", "ddef23"]), 3 ),) ] ); Ok(()) # } ``` -------------------------------- ### CSV Diff Example Source: https://docs.rs/csv-diff/latest/src/csv_diff/csv_diff.rs.html Demonstrates how to use CsvByteDiffBuilder to compare two CSV files and assert the differences. ```Rust let mut csv_left = String::new(); let mut csv_right = String::new(); csv_left.push_str("header1,header2,header3\n"); csv_left.push_str("a,b,c\n"); csv_left.push_str("d,e,f\n"); csv_right.push_str("header1,header2,header3\n"); csv_right.push_str("a,b,x\n"); csv_right.push_str("g,h,i\n"); csv_right.push_str("d,f,f\n"); csv_right.push_str("m,n,o\n"); let diff_res_iter = CsvByteDiffBuilder::::new( CsvHashTaskSpawnerBuilderStdThreads::new(), ) .primary_key_columns(vec![0, 1]) .build()? .diff( Csv::with_reader_seek(csv_left.as_bytes()), Csv::with_reader_seek(csv_right.as_bytes()), ); let mut diff_res_actual: DiffByteRecords = diff_res_iter.try_to_diff_byte_records()?; let mut diff_res_expected = DiffByteRecords::new( vec![ DiffByteRecord::Modify { delete: ByteRecordLineInfo::new(csv::ByteRecord::from(vec!["a", "b", "c"] ), 2), add: ByteRecordLineInfo::new(csv::ByteRecord::from(vec!["a", "b", "x"] ), 2), field_indices: vec![2], }, DiffByteRecord::Delete(ByteRecordLineInfo::new( csv::ByteRecord::from(vec!["d", "e", "f"]), 3, )), DiffByteRecord::Add(ByteRecordLineInfo::new( csv::ByteRecord::from(vec!["d", "f", "f"]), 4, )), ], ( Some(vec!["header1", "header2", "header3"].into()), Some(vec!["header1", "header2", "header3"].into()), ) .into(), Some(3), ); diff_res_actual.sort_by_line(); diff_res_expected.sort_by_line(); assert_eq!(diff_res_actual, diff_res_expected); Ok(()) } ``` -------------------------------- ### flattening multiple levels Example Source: https://docs.rs/csv-diff/latest/csv_diff/type.Result.html Example showing how `flatten` removes one level of nesting at a time. ```rust let x: Result, u32>, u32> = Ok(Ok(Ok("hello"))); assert_eq!(Ok(Ok("hello")), x.flatten()); assert_eq!(Ok("hello"), x.flatten().flatten()); ``` -------------------------------- ### expect example (panic) Source: https://docs.rs/csv-diff/latest/csv_diff/type.Result.html Demonstrates the behavior of expect when the Result is an Err, causing a panic. ```rust let x: Result = Err("emergency failure"); x.expect("Testing expect"); // panics with `Testing expect: emergency failure` ``` -------------------------------- ### unwrap_or() examples Source: https://docs.rs/csv-diff/latest/csv_diff/type.Result.html Shows how `unwrap_or` provides a default value. ```rust let default = 2; let x: Result = Ok(9); assert_eq!(x.unwrap_or(default), 9); let x: Result = Err("error"); assert_eq!(x.unwrap_or(default), default); ``` -------------------------------- ### unwrap_unchecked() example Source: https://docs.rs/csv-diff/latest/csv_diff/type.Result.html Demonstrates the usage of `unwrap_unchecked`. ```rust let x: Result = Ok(2); assert_eq!(unsafe { x.unwrap_unchecked() }, 2); ``` -------------------------------- ### Example: Create a CsvByteDiff with a compound primary key Source: https://docs.rs/csv-diff/latest/csv_diff/csv_diff/struct.CsvByteDiffBuilder.html This example demonstrates how to create a CsvByteDiff where column 1 (index 0) and column 3 (index 2) are treated as a compound primary key. It shows how changes in rows with different compound keys are identified as 'Deleted' or 'Added' rather than 'Modified'. ```rust use csv_diff::{csv_diff::{CsvByteDiff, CsvByteDiffBuilder}, csv::Csv}; use csv_diff::diff_row::{ByteRecordLineInfo, DiffByteRecord}; use csv_diff::diff_result::DiffByteRecords; use std::convert::TryInto; // some csv data with a header, where the first column and third column represent a compound key let csv_data_left = "\ id,name,commit_sha\n\ 1,lemon,efae52\n\ 2,strawberry,a33411"; // this csv line is seen as "Deleted" and not "Modified" // because "id" and "commit_sha" are different and both columns // _together_ represent the primary key let csv_data_right = "\ id,name,commit_sha\n\ 1,lemon,efae52\n\ 2,strawberry,ddef23"; // this csv line is seen as "Added" and not "Modified", // because "id" and "commit_sha" are different and both columns // _together_ represent the primary key let csv_byte_diff = CsvByteDiffBuilder::new() .primary_key_columns(vec![0usize, 2]) .build()?; let mut diff_byte_records: DiffByteRecords = csv_byte_diff .diff( Csv::with_reader(csv_data_left.as_bytes()), Csv::with_reader(csv_data_right.as_bytes()), ) .try_to_diff_byte_records()?; diff_byte_records.sort_by_line(); let diff_byte_rows = diff_byte_records.as_slice(); assert_eq!( diff_byte_rows, &[ DiffByteRecord::Delete(ByteRecordLineInfo::new( csv::ByteRecord::from(vec!["2", "strawberry", "a33411"]), 3 ),), DiffByteRecord::Add(ByteRecordLineInfo::new( csv::ByteRecord::from(vec!["2", "strawberry", "ddef23"]), 3 ),) ] ); Ok(()) ``` -------------------------------- ### Example: create CsvByteDiff with default values and compare two CSVs byte-wise lazily Source: https://docs.rs/csv-diff/latest/csv_diff/csv_diff/struct.CsvByteDiff.html This example demonstrates how to create a CsvByteDiff instance with default settings and then use it to compare two CSV strings. It shows how to iterate over the differences and asserts that a specific modification is found. ```rust use csv_diff::{csv_diff::CsvByteDiff, csv::Csv}; use csv_diff::diff_row::{ByteRecordLineInfo, DiffByteRecord}; use std::collections::HashSet; use std::iter::FromIterator; // some csv data with a header, where the first column is a unique id let csv_left = "\ header1,header2,header3\n\ a,b,c"; let csv_right = "\ header1,header2,header3\n\ a,b,d"; let csv_diff = CsvByteDiff::new()?; let mut diff_iterator = csv_diff.diff( Csv::with_reader(csv_left.as_bytes()), Csv::with_reader(csv_right.as_bytes()), ); let diff_row_actual = diff_iterator .next() .ok_or("Expected a difference between the two CSVs, but got none".to_string())??; let diff_row_expected = DiffByteRecord::Modify { delete: ByteRecordLineInfo::new(csv::ByteRecord::from(vec!["a", "b", "c"]), 2), add: ByteRecordLineInfo::new(csv::ByteRecord::from(vec!["a", "b", "d"]), 2), field_indices: vec![2], }; assert_eq!(diff_row_actual, diff_row_expected); Ok(()) ``` -------------------------------- ### or_else() examples Source: https://docs.rs/csv-diff/latest/csv_diff/type.Result.html Demonstrates the usage of the `or_else` method for lazy evaluation. ```rust fn sq(x: u32) -> Result { Ok(x * x) } fn err(x: u32) -> Result { Err(x) } assert_eq!(Ok(2).or_else(sq).or_else(sq), Ok(2)); assert_eq!(Ok(2).or_else(err).or_else(sq), Ok(2)); assert_eq!(Err(3).or_else(sq).or_else(err), Ok(9)); assert_eq!(Err(3).or_else(err).or_else(err), Err(3)); ``` -------------------------------- ### Example: use `Csv` together with `CsvByteDiffLocal` to compare CSV data Source: https://docs.rs/csv-diff/latest/src/csv_diff/csv.rs.html This example demonstrates how to use the `Csv` struct with `CsvByteDiffLocal` to compare CSV data. It shows creating `Csv` instances from byte slices using `Csv::with_reader_seek` and then performing a diff operation. ```rust use csv_diff::{csv_diff::CsvByteDiffLocal, csv::Csv}; # fn main() -> Result<(), Box> { 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,fruit"; let csv_byte_diff = CsvByteDiffLocal::new()?; let mut diff_byte_records = csv_byte_diff.diff( // bytes are not `Seek`able by default, but trait `CsvReadSeek` makes them seekable Csv::with_reader_seek(csv_data_left.as_bytes()), Csv::with_reader_seek(csv_data_right.as_bytes()), )?; let num_of_rows_different = diff_byte_records.as_slice().len(); assert_eq!( num_of_rows_different, 0 ); Ok(()) # } ``` -------------------------------- ### as_deref_mut example Source: https://docs.rs/csv-diff/latest/csv_diff/type.Result.html Shows converting a mutable Result to Result<&mut ::Target, &mut E> by coercing the Ok variant via DerefMut. ```rust let mut s = "HELLO".to_string(); let mut x: Result = Ok("hello".to_string()); let y: Result<&mut str, &mut u32> = Ok(&mut s); assert_eq!(x.as_deref_mut().map(|x| { x.make_ascii_uppercase(); x }), y); let mut i = 42; let mut x: Result = Err(42); let y: Result<&mut str, &mut u32> = Err(&mut i); assert_eq!(x.as_deref_mut().map(|x| { x.make_ascii_uppercase(); x }), y); ``` -------------------------------- ### Example: create CsvByteDiffLocal with default values and compare two CSVs byte-wise eagerly Source: https://docs.rs/csv-diff/latest/csv_diff/csv_diff/struct.CsvByteDiffLocal.html This example demonstrates how to instantiate CsvByteDiffLocal with default settings and then use its diff method to compare two CSV byte strings, highlighting the differences found. ```rust use csv_diff::{csv_diff::CsvByteDiffLocal, csv::Csv}; use csv_diff::diff_row::{ByteRecordLineInfo, DiffByteRecord}; use std::collections::HashSet; use std::iter::FromIterator; // 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"; let csv_byte_diff = CsvByteDiffLocal::new()?; let mut diff_byte_records = csv_byte_diff.diff( Csv::with_reader_seek(csv_data_left.as_bytes()), Csv::with_reader_seek(csv_data_right.as_bytes()), )?; let diff_byte_rows = diff_byte_records.as_slice(); assert_eq!( diff_byte_rows, &[DiffByteRecord::Modify { delete: ByteRecordLineInfo::new( csv::ByteRecord::from(vec!["2", "strawberry", "fruit"]), 3 ), add: ByteRecordLineInfo::new(csv::ByteRecord::from(vec!["2", "strawberry", "nut"]), 3), field_indices: vec![2] }] ); Ok(()) ``` -------------------------------- ### unwrap_err_unchecked() example Source: https://docs.rs/csv-diff/latest/csv_diff/type.Result.html Demonstrates the usage of `unwrap_err_unchecked`. ```rust let x: Result = Err("emergency failure"); assert_eq!(unsafe { x.unwrap_err_unchecked() }, "emergency failure"); ``` -------------------------------- ### and method example Source: https://docs.rs/csv-diff/latest/csv_diff/type.Result.html Illustrates the behavior of the `and` method, which returns the second `Result` if the first is `Ok`, otherwise returns the `Err` from the first `Result`. ```Rust let x: Result = Ok(2); let y: Result<&str, &str> = Err("late error"); assert_eq!(x.and(y), Err("late error")); let x: Result = Err("early error"); let y: Result<&str, &str> = Ok("foo"); assert_eq!(x.and(y), Err("early error")); let x: Result = Err("not a 2"); let y: Result<&str, &str> = Err("late error"); assert_eq!(x.and(y), Err("not a 2")); let x: Result = Ok(2); let y: Result<&str, &str> = Ok("different result type"); assert_eq!(x.and(y), Ok("different result type")); ``` -------------------------------- ### inspect example Source: https://docs.rs/csv-diff/latest/csv_diff/type.Result.html Shows how to use inspect to perform a side effect (like printing) when the Result is Ok, without changing the Result itself. ```rust let x: u8 = "4" .parse::() .inspect(|x| println!("original: {x}")) .map(|x| x.pow(3)) .expect("failed to parse number"); ``` -------------------------------- ### as_deref example Source: https://docs.rs/csv-diff/latest/csv_diff/type.Result.html Demonstrates converting a Result to Result<&::Target, &E> by coercing the Ok variant via Deref. ```rust let x: Result = Ok("hello".to_string()); let y: Result<&str, &u32> = Ok("hello"); assert_eq!(x.as_deref(), y); let x: Result = Err(42); let y: Result<&str, &u32> = Err(&42); assert_eq!(x.as_deref(), y); ``` -------------------------------- ### unwrap_or_else() examples Source: https://docs.rs/csv-diff/latest/csv_diff/type.Result.html Illustrates `unwrap_or_else` for computing a default value lazily. ```rust fn count(x: &str) -> usize { x.len() } assert_eq!(Ok(2).unwrap_or_else(count), 2); assert_eq!(Err("foo").unwrap_or_else(count), 3); ``` -------------------------------- ### Product Examples Source: https://docs.rs/csv-diff/latest/csv_diff/type.Result.html This multiplies each number in a vector of strings, if a string could not be parsed the operation returns Err. ```rust let nums = vec!["5", "10", "1", "2"]; let total: Result = nums.iter().map(|w| w.parse::()).product(); assert_eq!(total, Ok(100)); let nums = vec!["5", "10", "one", "2"]; let total: Result = nums.iter().map(|w| w.parse::()).product(); assert!(total.is_err()); ``` -------------------------------- ### into_err example Source: https://docs.rs/csv-diff/latest/csv_diff/type.Result.html Demonstrates the usage of the experimental `into_err` method, which returns the `Err` value and is guaranteed not to panic. ```Rust fn only_bad_news() -> Result { Err("Oops, it failed".into()) } let error: String = only_bad_news().into_err(); println!("{error}"); ``` -------------------------------- ### Sum Examples Source: https://docs.rs/csv-diff/latest/csv_diff/type.Result.html This sums up every integer in a vector, rejecting the sum if a negative element is encountered. ```rust let f = |&x: &i32| if x < 0 { Err("Negative element found") } else { Ok(x) }; let v = vec![1, 2]; let res: Result = v.iter().map(f).sum(); assert_eq!(res, Ok(3)); let v = vec![1, -2]; let res: Result = v.iter().map(f).sum(); assert_eq!(res, Err("Negative element found")); ``` -------------------------------- ### Example: use Csv together with CsvByteDiffLocal to compare CSV data Source: https://docs.rs/csv-diff/latest/csv_diff/csv/struct.Csv.html Demonstrates how to use the Csv struct with CsvByteDiffLocal to compare two CSV datasets represented as byte strings. ```rust use csv_diff::{csv_diff::CsvByteDiffLocal, csv::Csv}; 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,fruit"; let csv_byte_diff = CsvByteDiffLocal::new()?; let mut diff_byte_records = csv_byte_diff.diff( // bytes are not `Seek`able by default, but trait `CsvReadSeek` makes them seekable Csv::with_reader_seek(csv_data_left.as_bytes()), Csv::with_reader_seek(csv_data_right.as_bytes()), )?; let num_of_rows_different = diff_byte_records.as_slice().len(); assert_eq!( num_of_rows_different, 0 ); Ok(()) ``` -------------------------------- ### Example of using as_slice() Source: https://docs.rs/csv-diff/latest/csv_diff/diff_result/struct.DiffByteRecords.html Demonstrates how to get the DiffByteRecords as a slice and assert its length. ```rust use csv_diff::{csv_diff::CsvByteDiffLocal, csv::Csv}; use std::collections::HashSet; use std::iter::FromIterator; // 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 = CsvByteDiffLocal::new()?; let mut diff_byte_records = csv_byte_diff.diff( Csv::with_reader_seek(csv_data_left.as_bytes()), Csv::with_reader_seek(csv_data_right.as_bytes()), )?; let diff_byte_record_slice = diff_byte_records.as_slice(); assert_eq!( diff_byte_record_slice.len(), 2 ); Ok(()) ``` -------------------------------- ### Example of using CsvByteDiffLocal::new() and diff() Source: https://docs.rs/csv-diff/latest/src/csv_diff/csv_diff.rs.html Demonstrates how to create a `CsvByteDiffLocal` instance using the default constructor and then compare two CSV datasets. It highlights the process of reading CSV data, performing the diff, sorting the results, and asserting the expected differences. ```rust use csv_diff::{csv_diff::CsvByteDiffLocal, csv::Csv}; use csv_diff::diff_row::{ByteRecordLineInfo, DiffByteRecord}; use std::collections::HashSet; use std::iter::FromIterator; # fn main() -> Result<(), Box> { // 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"; let csv_byte_diff = CsvByteDiffLocal::new()?; let mut diff_byte_records = csv_byte_diff.diff( Csv::with_reader_seek(csv_data_left.as_bytes()), Csv::with_reader_seek(csv_data_right.as_bytes()), )?; diff_byte_records.sort_by_line(); let diff_byte_rows = diff_byte_records.as_slice(); assert_eq!( diff_byte_rows, &[DiffByteRecord::Modify { delete: ByteRecordLineInfo::new( csv::ByteRecord::from(vec!["2", "strawberry", "fruit"]), 3 ), add: ByteRecordLineInfo::new(csv::ByteRecord::from(vec!["2", "strawberry", "nut"])), field_indices: vec![2] }] ); Ok(()) # } ``` -------------------------------- ### iter_mut example Source: https://docs.rs/csv-diff/latest/csv_diff/type.Result.html Shows using iter_mut to get a mutable iterator over the contained value if the Result is Ok. ```rust let mut x: Result = Ok(7); match x.iter_mut().next() { Some(v) => *v = 40, None => {}, } assert_eq!(x, Ok(40)); let mut x: Result = Err("nothing!"); assert_eq!(x.iter_mut().next(), None); ``` -------------------------------- ### Keyboard Shortcuts Source: https://docs.rs/csv-diff/latest/help.html A list of keyboard shortcuts available in Rustdoc for navigation and interaction. ```text `?` Show this help dialog `S` / `/` Focus the search field `↑` Move up in search results `↓` Move down in search results `←` / `→` Switch result tab (when results focused) `⏎` Go to active search result `+` / `=` Expand all sections `-` Collapse all sections `_` Collapse all sections, including impl blocks ``` -------------------------------- ### Search Tricks Source: https://docs.rs/csv-diff/latest/help.html Tips for using the search functionality in Rustdoc, including type prefixes and exact name matching. ```text Prefix searches with a type followed by a colon (e.g., `fn:`) to restrict the search to a given item kind. Accepted kinds are: `fn`, `mod`, `struct`, `enum`, `trait`, `type`, `macro`, and `const`. Search functions by type signature (e.g., `vec -> usize` or `-> vec` or `String, enum:Cow -> bool`) You can look for items with an exact name by putting double quotes around your request: `"string"` Look for functions that accept or return slices and arrays by writing square brackets (e.g., `-> [u8]` or `[] -> Option`) Look for items inside another one by searching for a path: `vec::Vec` ``` -------------------------------- ### Example Usage of CsvByteDiffLocal Source: https://docs.rs/csv-diff/latest/csv_diff/csv_diff/struct.CsvByteDiffLocal.html This example demonstrates how to use CsvByteDiffLocal to compare two CSV datasets, identify modified rows, and assert the differences. ```rust use csv_diff::{csv_diff::CsvByteDiffLocal, csv::Csv}; use csv_diff::diff_row::{ByteRecordLineInfo, DiffByteRecord}; use std::collections::HashSet; use std::iter::FromIterator; // 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"; let csv_byte_diff = CsvByteDiffLocal::new()?; let mut diff_byte_records = csv_byte_diff.diff( Csv::with_reader_seek(csv_data_left.as_bytes()), Csv::with_reader_seek(csv_data_right.as_bytes()), )?; diff_byte_records.sort_by_line(); let diff_byte_rows = diff_byte_records.as_slice(); assert_eq!( diff_byte_rows, &[DiffByteRecord::Modify { delete: ByteRecordLineInfo::new( csv::ByteRecord::from(vec!["2", "strawberry", "fruit"]), 3 ), add: ByteRecordLineInfo::new(csv::ByteRecord::from(vec!["2", "strawberry", "nut"]), 3), field_indices: vec![2] }] ); Ok(()) ``` -------------------------------- ### DiffResult as Slice Source: https://docs.rs/csv-diff/latest/src/csv_diff/diff_result.rs.html Demonstrates how to get a slice of `DiffByteRecord`s from a `DiffResult`. ```rust use csv_diff::{csv_diff::CsvByteDiffLocal, csv::Csv}; use std::collections::HashSet; use std::iter::FromIterator; # fn main() -> Result<(), Box> { // 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 = CsvByteDiffLocal::new()?; let mut diff_byte_records = csv_byte_diff.diff( Csv::with_reader_seek(csv_data_left.as_bytes()), Csv::with_reader_seek(csv_data_right.as_bytes()), )?; let diff_byte_record_slice = diff_byte_records.as_slice(); assert_eq!( diff_byte_record_slice.len(), 2 ); Ok(()) # } ``` -------------------------------- ### Create a CsvByteDiff with compound primary key Source: https://docs.rs/csv-diff/latest/src/csv_diff/csv_diff.rs.html This example demonstrates how to create a `CsvByteDiff` where a compound primary key (columns 1 and 3) is used for comparison. It shows how lines with different compound keys are treated as 'Deleted' or 'Added' rather than 'Modified'. ```Rust use csv_diff::{csv_diff::{CsvByteDiff, CsvByteDiffBuilder}, csv::Csv}; use csv_diff::diff_row::{ByteRecordLineInfo, DiffByteRecord}; use csv_diff::diff_result::DiffByteRecords; use std::convert::TryInto; fn main() -> Result<(), Box> { // some csv data with a header, where the first column and third column represent a compound key let csv_data_left = "\ id,name,commit_sha\n\ 1,lemon,efae52\n\ 2,strawberry,a33411"; // this csv line is seen as "Deleted" and not "Modified" // because "id" and "commit_sha" are different and both columns // _together_ represent the primary key let csv_data_right = "\ id,name,commit_sha\n\ 1,lemon,efae52\n\ 2,strawberry,ddef23"; // this csv line is seen as "Added" and not "Modified", // because "id" and "commit_sha" are different and both columns // _together_ represent the primary key let csv_byte_diff = CsvByteDiffBuilder::new() .primary_key_columns(vec![0usize, 2]) .build()?; let mut diff_byte_records: DiffByteRecords = csv_byte_diff .diff( Csv::with_reader(csv_data_left.as_bytes()), Csv::with_reader(csv_data_right.as_bytes()), ) .try_to_diff_byte_records()?; diff_byte_records.sort_by_line(); let diff_byte_rows = diff_byte_records.as_slice(); assert_eq!( diff_byte_rows, &[ DiffByteRecord::Delete(ByteRecordLineInfo::new( csv::ByteRecord::from(vec!["2", "strawberry", "a33411"]), 3 ),), DiffByteRecord::Add(ByteRecordLineInfo::new( csv::ByteRecord::from(vec!["2", "strawberry", "ddef23"]), 3 ),) ] ); Ok(()) } ``` -------------------------------- ### Basic usage of unwrap Source: https://docs.rs/csv-diff/latest/csv_diff/type.Result.html Demonstrates the basic usage of the `unwrap` method on a `Result` type, extracting the `Ok` value. ```Rust let x: Result = Ok(2); assert_eq!(x.unwrap(), 2); ``` -------------------------------- ### Pointable::init method Source: https://docs.rs/csv-diff/latest/csv_diff/csv_hash_task_spawner/struct.CsvHashTaskSpawnerLocalBuilderRayon.html Implementation of the init method from the Pointable trait. ```rust unsafe fn init(init: ::Init) -> usize ``` -------------------------------- ### csv_diff/lib.rs Source: https://docs.rs/csv-diff/latest/src/csv_diff/lib.rs.html Find the difference between two CSVs - with ludicrous speed!🚀 `csv-diff` finds the difference between two CSVs. It is the fastest CSV-diffing library in the world! Comparing two 1,000,000 rows x 9 columns CSVs takes __under 600ms__ (when using [raw bytes](csv_diff::CsvByteDiffLocal::diff)). It is *thread-pool-agnostic*, meaning you can provide your own existing thread-pool or you can use the default [rayon thread-pool](https://docs.rs/rayon/1.5.0/rayon/struct.ThreadPool.html) that is used in this crate. # Use Case This crate should be used on CSV data that has some sort of *primary key* for uniquely identifying a record. It is __not__ a general line-by-line diffing crate. You can imagine dumping a database table in CSV format from your *test* and *production* system and comparing it with each other to find differences. # Overview The most important types you will use are: 1. [`CsvByteDiffLocal`](csv_diff::CsvByteDiffLocal) for comparing two CSVs byte-wise in a blocking fashion and getting the result as [`DiffByteRecords`](diff_result::DiffByteRecords). 2. [`CsvByteDiff`](csv_diff::CsvByteDiff) for comparing two CSVs byte-wise lazily and getting the result as an [`Iterator`](diff_result::DiffByteRecordsIterator). ```rust /*! Find the difference between two CSVs - with ludicrous speed!🚀 `csv-diff` finds the difference between two CSVs. It is the fastest CSV-diffing library in the world! Comparing two 1,000,000 rows x 9 columns CSVs takes __under 600ms__ (when using [raw bytes](csv_diff::CsvByteDiffLocal::diff)). It is *thread-pool-agnostic*, meaning you can provide your own existing thread-pool or you can use the default [rayon thread-pool](https://docs.rs/rayon/1.5.0/rayon/struct.ThreadPool.html) that is used in this crate. # Use Case This crate should be used on CSV data that has some sort of *primary key* for uniquely identifying a record. It is __not__ a general line-by-line diffing crate. You can imagine dumping a database table in CSV format from your *test* and *production* system and comparing it with each other to find differences. # Overview The most important types you will use are: 1. [`CsvByteDiffLocal`](csv_diff::CsvByteDiffLocal) for comparing two CSVs byte-wise in a blocking fashion and getting the result as [`DiffByteRecords`](diff_result::DiffByteRecords). 2. [`CsvByteDiff`](csv_diff::CsvByteDiff) for comparing two CSVs byte-wise lazily and getting the result as an [`Iterator`](diff_result::DiffByteRecordsIterator). */ #![forbid(unsafe_code)] pub mod csv; pub mod csv_diff; mod csv_hash_comparer; pub mod csv_headers; // TODO: try to make it more private pub mod csv_hash_receiver_comparer; pub mod csv_hash_task_spawner; mod csv_hasher; pub mod csv_parse_result; mod csv_parser_hasher; pub mod diff_result; pub mod diff_row; mod thread_scope_strategy; // TODO: do we really need this? #[doc(inline)] pub use ::csv::Result; ```