updates, clippy, formatting
[Mitarbeiter/Tim-Zeitz/stud-rust-base.git] / src / bin / compare_vector.rs
1 use std::{env, error::Error, fmt::Display};
2 use stud_rust_base::{cli::CliErr, io::*};
3
4 fn main() -> Result<(), Box<dyn Error>> {
5     let mut args = env::args().skip(1);
6     match &(args.next(), args.next(), args.next()) {
7         (Some(data_type), Some(input1), Some(input2)) => {
8             match data_type.as_ref() {
9                 "i8" | "int8" => compare_values::<i8>(&Vec::load_from(input1)?, &Vec::load_from(input2)?),
10                 "u8" | "uint8" => compare_values::<u8>(&Vec::load_from(input1)?, &Vec::load_from(input2)?),
11                 "i16" | "int16" => compare_values::<i16>(&Vec::load_from(input1)?, &Vec::load_from(input2)?),
12                 "u16" | "uint16" => compare_values::<u16>(&Vec::load_from(input1)?, &Vec::load_from(input2)?),
13                 "i32" | "int32" => compare_values::<i32>(&Vec::load_from(input1)?, &Vec::load_from(input2)?),
14                 "u32" | "uint32" => compare_values::<u32>(&Vec::load_from(input1)?, &Vec::load_from(input2)?),
15                 "i64" | "int64" => compare_values::<i64>(&Vec::load_from(input1)?, &Vec::load_from(input2)?),
16                 "u64" | "uint64" => compare_values::<u64>(&Vec::load_from(input1)?, &Vec::load_from(input2)?),
17                 "f32" | "float32" => compare_values::<f32>(&Vec::load_from(input1)?, &Vec::load_from(input2)?),
18                 "f64" | "float64" => compare_values::<f64>(&Vec::load_from(input1)?, &Vec::load_from(input2)?),
19                 _ => {
20                     print_usage();
21                     return Err(Box::new(CliErr("Invalid data type")));
22                 }
23             };
24             Ok(())
25         }
26         _ => {
27             print_usage();
28             Err(Box::new(CliErr("Invalid arguments")))
29         }
30     }
31 }
32
33 fn print_usage() {
34     eprintln!(
35         "Usage: decode_vector data_type vector1_file vector2_file
36
37 Compares two vectors of elements in binary format. data_type can be one of
38 * i8
39 * u8
40 * i16
41 * u16
42 * i32
43 * u32
44 * i64
45 * u64
46 * f32
47 * f64
48
49 "
50     );
51 }
52
53 fn compare_values<T>(values1: &[T], values2: &[T])
54 where
55     T: Display,
56     T: PartialOrd,
57 {
58     if values1.len() != values2.len() {
59         println!("0");
60         eprintln!(
61             "Can only compare vectors of equal size. The first vector has {} elements. The second vector has {} elements.",
62             values1.len(),
63             values2.len()
64         );
65         return;
66     }
67
68     let mut v1_smaller_count = 0;
69     let mut v2_smaller_count = 0;
70     let mut first_diff = None;
71
72     for (i, (v1, v2)) in values1.iter().zip(values2.iter()).enumerate() {
73         if v1 < v2 {
74             v1_smaller_count += 1;
75         }
76         if v2 < v1 {
77             v2_smaller_count += 1;
78         }
79
80         if first_diff.is_none() && v1 != v2 {
81             first_diff = Some(i)
82         }
83     }
84
85     match first_diff {
86         Some(index) => {
87             eprintln!("The vectors differ.");
88             eprintln!("{} elements are smaller in the first vector.", v1_smaller_count);
89             eprintln!("{} elements are smaller in the second vector.", v2_smaller_count);
90             eprintln!("{} elements are the same.", values1.len() - v1_smaller_count - v2_smaller_count);
91             println!("{}", values1.len() - v1_smaller_count - v2_smaller_count);
92             eprintln!("{} elements are different.", v1_smaller_count + v2_smaller_count);
93             eprintln!("The vectors have {} elements.", values1.len());
94             eprintln!("The first element that differs is at index {}.", index);
95         }
96         None => {
97             println!("{}", values1.len());
98             eprintln!("The vectors are the same and have {} elements.", values1.len());
99         }
100     }
101 }