updates, clippy, formatting master
authorTim "tim3z" Zeitz <dev@tim3z.net>
Thu, 16 Dec 2021 09:47:11 +0000 (10:47 +0100)
committerTim "tim3z" Zeitz <dev@tim3z.net>
Thu, 16 Dec 2021 09:47:11 +0000 (10:47 +0100)
13 files changed:
Cargo.lock
Cargo.toml
README.md
rustfmt.toml [new file with mode: 0644]
src/bin/compare_vector.rs
src/bin/decode_vector.rs
src/bin/encode_vector.rs
src/bin/example.rs
src/cli.rs
src/index_heap.rs
src/io.rs
src/lib.rs
src/time.rs

index bc66e435e97dec10d38b28973db2bfbf46c6840b..b98a97af9fe86b83741d7eb803e6197a7c051b3e 100644 (file)
@@ -1,53 +1,7 @@
-[[package]]
-name = "libc"
-version = "0.2.43"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "redox_syscall"
-version = "0.1.40"
-source = "registry+https://github.com/rust-lang/crates.io-index"
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
 
 [[package]]
 name = "stud-rust-base"
 version = "0.1.0"
-dependencies = [
- "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "time"
-version = "0.1.40"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "winapi"
-version = "0.3.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "winapi-i686-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "winapi-x86_64-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[metadata]
-"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d"
-"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1"
-"checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b"
-"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
-"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
-"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
index efe5553b4b81d8ee327c7cee68ba711ab3acddc6..42ddd252d4bddd132747c2bd269c197fc556bef8 100644 (file)
@@ -2,6 +2,4 @@
 name = "stud-rust-base"
 version = "0.1.0"
 authors = ["Tim Zeitz <tim.zeitz@kit.edu>"]
-
-[dependencies]
-time = "0.1.40"
+edition = '2021'
index 4e8cb7613652d14b36498da5a8b224f174c69a5f..59210f995419a2f09f8040d6c7482f6ab35ca5ed 100644 (file)
--- a/README.md
+++ b/README.md
@@ -35,7 +35,7 @@ Mit `cargo check` kann man das Programm checken ohne zu bauen, das kann einem ei
 
 Rust hat einen exzellenten Linter, der einem sehr hilft idiomatischen und performanten Code zu schreiben.
 Das ist insbesondere wenn man noch nicht viel Erfahrung mit der Sprache hat extrem sinnvoll!
-Installieren kann man Clippy mit `rustup component add clippy-preview`.
+Installieren kann man Clippy mit `rustup component add clippy`.
 Anstatt `cargo check` ruft man dann `cargo clippy` auf und kann sich auf viel hilfreiches Feedback freuen.
 
 # Rust Routenplanungs-Basis-Framework
@@ -53,12 +53,11 @@ Die entsprechenden Funktionen sind über Traits definiert und können so direkt
 Das kann z.B. so aussehen:
 
 ```Rust
-extern crate stud_rust_base;
 use stud_rust_base::io::*;
 
-let head = Vec::<u32>::load_from("head_file_name").expect("could not read head");
-let lat = Vec::<f32>::load_from("node_latitude_file_name").expect("could not read lat");
-head.write_to("output_file").expect("could not write head");
+let head = Vec::<u32>::load_from("head_file_name")?;
+let lat = Vec::<f32>::load_from("node_latitude_file_name")?;
+head.write_to(&"output_file")?;
 ```
 
 Die Dateien in `src/bin/` sind einmal ein Beispielprogramm sowieso Hilfsprogramme.
@@ -79,12 +78,11 @@ Diese heißen `first_out`, `head` und `weight`.
 Um über die ausgehenden Kanten eines Knoten zu iterieren können Sie den folgenden Code verwenden:
 
 ```Rust
-extern crate stud_rust_base;
 use stud_rust_base::{types::*, io::*};
 
-let first_out = Vec::<EdgeId>::load_from("first_out_file_name").expect("could not read first_out");
-let head = Vec::<NodeId>::load_from("head_file_name").expect("could not read head");
-let travel_time = Vec::<Weight>::load_from("weight_file_name").expect("could not read travel_time");
+let first_out = Vec::<EdgeId>::load_from("first_out_file_name")?;
+let head = Vec::<NodeId>::load_from("head_file_name")?;
+let travel_time = Vec::<Weight>::load_from("weight_file_name")?;
 
 let node_id = 42;
 for edge_id in first_out[node_id] .. first_out[node_id + 1] {
@@ -108,9 +106,9 @@ Die Aufgabengraphen haben die Größe des Deutschlandgraphen.
 
 ## Hinweise zur Nutzung im Routenplanungspraktikum
 
-Der Quellcode soll durch das Ausführen von `cargo build --all` mit dem aktuellen stabilen Compiler (1.29.2) übersetzt werden können.
+Der Quellcode soll durch das Ausführen von `cargo build --all` mit dem aktuellen stabilen Compiler (1.38.0) übersetzt werden können.
 Auf den Poolraumrechner ist kein Rust Compiler vorinstalliert.
 Sie können aber für ihren Nutzer lokal `rustup` und damit dann einen aktuellen Compiler installieren.
 Die Nutzung von nicht stabilen nightly Features ist nicht erlaubt.
 Das verwenden externer crates ist nicht erlaubt.
-Die Rust-Standardbibliothek ist nicht extern.
+Die Rust-Standardbibliothek gilt nicht als extern.
diff --git a/rustfmt.toml b/rustfmt.toml
new file mode 100644 (file)
index 0000000..b28d8cf
--- /dev/null
@@ -0,0 +1 @@
+max_width = 160
index 5d42c182cd790390255d46bf2cae732ff59a893b..9aab0301c928e64eb807f76c803f8c431abe1bad 100644 (file)
@@ -1,49 +1,38 @@
-extern crate stud_rust_base;
-use stud_rust_base::{io::*, cli::CliErr};
-use std::{env, fmt::Display, error::Error};
+use std::{env, error::Error, fmt::Display};
+use stud_rust_base::{cli::CliErr, io::*};
 
 fn main() -> Result<(), Box<dyn Error>> {
-    let mut args = env::args();
-    args.next();
-
-    match &args.collect::<Vec<String>>()[..] {
-        [data_type, input1, input2] => {
+    let mut args = env::args().skip(1);
+    match &(args.next(), args.next(), args.next()) {
+        (Some(data_type), Some(input1), Some(input2)) => {
             match data_type.as_ref() {
-                "i8" => { compare_values(&Vec::<i8>::load_from(input1)?, &Vec::<i8>::load_from(input2)?); Ok(()) },
-                "u8" => { compare_values(&Vec::<u8>::load_from(input1)?, &Vec::<u8>::load_from(input2)?); Ok(()) },
-                "i16" => { compare_values(&Vec::<i16>::load_from(input1)?, &Vec::<i16>::load_from(input2)?); Ok(()) },
-                "u16" => { compare_values(&Vec::<u16>::load_from(input1)?, &Vec::<u16>::load_from(input2)?); Ok(()) },
-                "i32" => { compare_values(&Vec::<i32>::load_from(input1)?, &Vec::<i32>::load_from(input2)?); Ok(()) },
-                "u32" => { compare_values(&Vec::<u32>::load_from(input1)?, &Vec::<u32>::load_from(input2)?); Ok(()) },
-                "i64" => { compare_values(&Vec::<i64>::load_from(input1)?, &Vec::<i64>::load_from(input2)?); Ok(()) },
-                "u64" => { compare_values(&Vec::<u64>::load_from(input1)?, &Vec::<u64>::load_from(input2)?); Ok(()) },
-                "f32" => { compare_values(&Vec::<f32>::load_from(input1)?, &Vec::<f32>::load_from(input2)?); Ok(()) },
-                "f64" => { compare_values(&Vec::<f64>::load_from(input1)?, &Vec::<f64>::load_from(input2)?); Ok(()) },
-                "int8" => { compare_values(&Vec::<i8>::load_from(input1)?, &Vec::<i8>::load_from(input2)?); Ok(()) },
-                "uint8" => { compare_values(&Vec::<u8>::load_from(input1)?, &Vec::<u8>::load_from(input2)?); Ok(()) },
-                "int16" => { compare_values(&Vec::<i16>::load_from(input1)?, &Vec::<i16>::load_from(input2)?); Ok(()) },
-                "uint16" => { compare_values(&Vec::<u16>::load_from(input1)?, &Vec::<u16>::load_from(input2)?); Ok(()) },
-                "int32" => { compare_values(&Vec::<i32>::load_from(input1)?, &Vec::<i32>::load_from(input2)?); Ok(()) },
-                "uint32" => { compare_values(&Vec::<u32>::load_from(input1)?, &Vec::<u32>::load_from(input2)?); Ok(()) },
-                "int64" => { compare_values(&Vec::<i64>::load_from(input1)?, &Vec::<i64>::load_from(input2)?); Ok(()) },
-                "uint64" => { compare_values(&Vec::<u64>::load_from(input1)?, &Vec::<u64>::load_from(input2)?); Ok(()) },
-                "float32" => { compare_values(&Vec::<f32>::load_from(input1)?, &Vec::<f32>::load_from(input2)?); Ok(()) },
-                "float64" => { compare_values(&Vec::<f64>::load_from(input1)?, &Vec::<f64>::load_from(input2)?); Ok(()) },
+                "i8" | "int8" => compare_values::<i8>(&Vec::load_from(input1)?, &Vec::load_from(input2)?),
+                "u8" | "uint8" => compare_values::<u8>(&Vec::load_from(input1)?, &Vec::load_from(input2)?),
+                "i16" | "int16" => compare_values::<i16>(&Vec::load_from(input1)?, &Vec::load_from(input2)?),
+                "u16" | "uint16" => compare_values::<u16>(&Vec::load_from(input1)?, &Vec::load_from(input2)?),
+                "i32" | "int32" => compare_values::<i32>(&Vec::load_from(input1)?, &Vec::load_from(input2)?),
+                "u32" | "uint32" => compare_values::<u32>(&Vec::load_from(input1)?, &Vec::load_from(input2)?),
+                "i64" | "int64" => compare_values::<i64>(&Vec::load_from(input1)?, &Vec::load_from(input2)?),
+                "u64" | "uint64" => compare_values::<u64>(&Vec::load_from(input1)?, &Vec::load_from(input2)?),
+                "f32" | "float32" => compare_values::<f32>(&Vec::load_from(input1)?, &Vec::load_from(input2)?),
+                "f64" | "float64" => compare_values::<f64>(&Vec::load_from(input1)?, &Vec::load_from(input2)?),
                 _ => {
                     print_usage();
-                    Err(Box::new(CliErr("Invalid data type")))
+                    return Err(Box::new(CliErr("Invalid data type")));
                 }
-            }
-        },
+            };
+            Ok(())
+        }
         _ => {
             print_usage();
             Err(Box::new(CliErr("Invalid arguments")))
-        },
+        }
     }
 }
 
 fn print_usage() {
-    eprintln!("Usage: decode_vector data_type vector1_file vector2_file
+    eprintln!(
+        "Usage: decode_vector data_type vector1_file vector2_file
 
 Compares two vectors of elements in binary format. data_type can be one of
 * i8
@@ -57,17 +46,23 @@ Compares two vectors of elements in binary format. data_type can be one of
 * f32
 * f64
 
-");
+"
+    );
 }
 
-fn compare_values<T>(values1: &[T], values2: &[T]) where
+fn compare_values<T>(values1: &[T], values2: &[T])
+where
     T: Display,
-    T: PartialOrd
+    T: PartialOrd,
 {
     if values1.len() != values2.len() {
         println!("0");
-        eprintln!("Can only compare vectors of equal size. The first vector has {} elements. The second vector has {} elements.", values1.len(), values2.len());
-        return
+        eprintln!(
+            "Can only compare vectors of equal size. The first vector has {} elements. The second vector has {} elements.",
+            values1.len(),
+            values2.len()
+        );
+        return;
     }
 
     let mut v1_smaller_count = 0;
@@ -75,8 +70,12 @@ fn compare_values<T>(values1: &[T], values2: &[T]) where
     let mut first_diff = None;
 
     for (i, (v1, v2)) in values1.iter().zip(values2.iter()).enumerate() {
-        if v1 < v2 { v1_smaller_count += 1; }
-        if v2 < v1 { v2_smaller_count += 1; }
+        if v1 < v2 {
+            v1_smaller_count += 1;
+        }
+        if v2 < v1 {
+            v2_smaller_count += 1;
+        }
 
         if first_diff.is_none() && v1 != v2 {
             first_diff = Some(i)
@@ -93,10 +92,10 @@ fn compare_values<T>(values1: &[T], values2: &[T]) where
             eprintln!("{} elements are different.", v1_smaller_count + v2_smaller_count);
             eprintln!("The vectors have {} elements.", values1.len());
             eprintln!("The first element that differs is at index {}.", index);
-        },
+        }
         None => {
             println!("{}", values1.len());
             eprintln!("The vectors are the same and have {} elements.", values1.len());
-        },
+        }
     }
 }
index 691a7a09d2966084c50c74b492638c2c696c5c6d..6169732dfdf346eabdbd57adc421a8f27251170e 100644 (file)
@@ -1,49 +1,36 @@
-extern crate stud_rust_base;
-use stud_rust_base::{io::*, cli::CliErr};
 use std::{env, error::Error};
+use stud_rust_base::{cli::CliErr, io::*};
 
 fn main() -> Result<(), Box<dyn Error>> {
-    let mut args = env::args();
-    args.next();
-
-    match &args.collect::<Vec<String>>()[..] {
-        [data_type, input] => {
-            match data_type.as_ref() {
-                "i8" => { print_values(Vec::<i8>::load_from(input)?); Ok(()) },
-                "u8" => { print_values(Vec::<u8>::load_from(input)?); Ok(()) },
-                "i16" => { print_values(Vec::<i16>::load_from(input)?); Ok(()) },
-                "u16" => { print_values(Vec::<u16>::load_from(input)?); Ok(()) },
-                "i32" => { print_values(Vec::<i32>::load_from(input)?); Ok(()) },
-                "u32" => { print_values(Vec::<u32>::load_from(input)?); Ok(()) },
-                "i64" => { print_values(Vec::<i64>::load_from(input)?); Ok(()) },
-                "u64" => { print_values(Vec::<u64>::load_from(input)?); Ok(()) },
-                "f32" => { print_values(Vec::<f32>::load_from(input)?); Ok(()) },
-                "f64" => { print_values(Vec::<f64>::load_from(input)?); Ok(()) },
-                "int8" => { print_values(Vec::<i8>::load_from(input)?); Ok(()) },
-                "uint8" => { print_values(Vec::<u8>::load_from(input)?); Ok(()) },
-                "int16" => { print_values(Vec::<i16>::load_from(input)?); Ok(()) },
-                "uint16" => { print_values(Vec::<u16>::load_from(input)?); Ok(()) },
-                "int32" => { print_values(Vec::<i32>::load_from(input)?); Ok(()) },
-                "uint32" => { print_values(Vec::<u32>::load_from(input)?); Ok(()) },
-                "int64" => { print_values(Vec::<i64>::load_from(input)?); Ok(()) },
-                "uint64" => { print_values(Vec::<u64>::load_from(input)?); Ok(()) },
-                "float32" => { print_values(Vec::<f32>::load_from(input)?); Ok(()) },
-                "float64" => { print_values(Vec::<f64>::load_from(input)?); Ok(()) },
-                _ => {
-                    print_usage();
-                    Err(Box::new(CliErr("Invalid data type")))
-                }
+    let mut args = env::args().skip(1);
+    match (args.next(), args.next()) {
+        (Some(data_type), Some(ref input)) => match data_type.as_ref() {
+            "i8" | "int8" => print_values(Vec::<i8>::load_from(input)?),
+            "u8" | "uint8" => print_values(Vec::<u8>::load_from(input)?),
+            "i16" | "int16" => print_values(Vec::<i16>::load_from(input)?),
+            "u16" | "uint16" => print_values(Vec::<u16>::load_from(input)?),
+            "i32" | "int32" => print_values(Vec::<i32>::load_from(input)?),
+            "u32" | "uint32" => print_values(Vec::<u32>::load_from(input)?),
+            "i64" | "int64" => print_values(Vec::<i64>::load_from(input)?),
+            "u64" | "uint64" => print_values(Vec::<u64>::load_from(input)?),
+            "f32" | "float32" => print_values(Vec::<f32>::load_from(input)?),
+            "f64" | "float64" => print_values(Vec::<f64>::load_from(input)?),
+            _ => {
+                print_usage();
+                return Err(Box::new(CliErr("Invalid data type")));
             }
         },
         _ => {
             print_usage();
-            Err(Box::new(CliErr("Invalid arguments")))
-        },
-    }
+            return Err(Box::new(CliErr("Invalid arguments")));
+        }
+    };
+    Ok(())
 }
 
 fn print_usage() {
-    eprintln!("Usage: decode_vector data_type input_vector_file
+    eprintln!(
+        "Usage: decode_vector data_type input_vector_file
 
 Reads binary data from input_vector_file and writes the data to the standard output. data_type can be one of
 * i8
@@ -57,13 +44,15 @@ Reads binary data from input_vector_file and writes the data to the standard out
 * f32
 * f64
 
-");
+"
+    );
 }
 
 use std::fmt::Display;
 
-fn print_values<T>(values: Vec<T>) where
-    T: Display
+fn print_values<T>(values: Vec<T>)
+where
+    T: Display,
 {
     for v in values {
         println!("{}", v);
index c3996693d8e69ed279c6d68a341007ad26184f83..a56eb82c1f6f02a20b7239463ba4d58b737a4cb8 100644 (file)
@@ -1,44 +1,32 @@
-extern crate stud_rust_base;
-use stud_rust_base::{io::*, cli::CliErr};
 use std::{env, error::Error};
+use stud_rust_base::{cli::CliErr, io::*};
 
 fn main() -> Result<(), Box<dyn Error>> {
-    let mut args = env::args();
-    args.next();
-
-    match &args.collect::<Vec<String>>()[..] {
-        [data_type, output] => {
+    let mut args = env::args().skip(1);
+    match (args.next(), args.next()) {
+        (Some(data_type), Some(ref output)) => {
             match data_type.as_ref() {
-                "i8" => { parse_input::<i8>()?.write_to(output)?; Ok(()) },
-                "u8" => { parse_input::<u8>()?.write_to(output)?; Ok(()) },
-                "i16" => { parse_input::<i16>()?.write_to(output)?; Ok(()) },
-                "u16" => { parse_input::<u16>()?.write_to(output)?; Ok(()) },
-                "i32" => { parse_input::<i32>()?.write_to(output)?; Ok(()) },
-                "u32" => { parse_input::<u32>()?.write_to(output)?; Ok(()) },
-                "i64" => { parse_input::<i64>()?.write_to(output)?; Ok(()) },
-                "u64" => { parse_input::<u64>()?.write_to(output)?; Ok(()) },
-                "f32" => { parse_input::<f32>()?.write_to(output)?; Ok(()) },
-                "f64" => { parse_input::<f64>()?.write_to(output)?; Ok(()) },
-                "int8" => { parse_input::<i8>()?.write_to(output)?; Ok(()) },
-                "uint8" => { parse_input::<u8>()?.write_to(output)?; Ok(()) },
-                "int16" => { parse_input::<i16>()?.write_to(output)?; Ok(()) },
-                "uint16" => { parse_input::<u16>()?.write_to(output)?; Ok(()) },
-                "int32" => { parse_input::<i32>()?.write_to(output)?; Ok(()) },
-                "uint32" => { parse_input::<u32>()?.write_to(output)?; Ok(()) },
-                "int64" => { parse_input::<i64>()?.write_to(output)?; Ok(()) },
-                "uint64" => { parse_input::<u64>()?.write_to(output)?; Ok(()) },
-                "float32" => { parse_input::<f32>()?.write_to(output)?; Ok(()) },
-                "float64" => { parse_input::<f64>()?.write_to(output)?; Ok(()) },
+                "i8" | "int8" => parse_input::<i8>()?.write_to(output)?,
+                "u8" | "uint8" => parse_input::<u8>()?.write_to(output)?,
+                "i16" | "int16" => parse_input::<i16>()?.write_to(output)?,
+                "u16" | "uint16" => parse_input::<u16>()?.write_to(output)?,
+                "i32" | "int32" => parse_input::<i32>()?.write_to(output)?,
+                "u32" | "uint32" => parse_input::<u32>()?.write_to(output)?,
+                "i64" | "int64" => parse_input::<i64>()?.write_to(output)?,
+                "u64" | "uint64" => parse_input::<u64>()?.write_to(output)?,
+                "f32" | "float32" => parse_input::<f32>()?.write_to(output)?,
+                "f64" | "float64" => parse_input::<f64>()?.write_to(output)?,
                 _ => {
                     print_usage();
-                    Err(Box::new(CliErr("Invalid data type")))
+                    return Err(Box::new(CliErr("Invalid data type")));
                 }
-            }
-        },
+            };
+            Ok(())
+        }
         _ => {
             print_usage();
             Err(Box::new(CliErr("Invalid arguments")))
-        },
+        }
     }
 }
 
@@ -62,11 +50,12 @@ Reads textual data from the standard input and writes it in a binary format to o
 
 use std::str::FromStr;
 
-fn parse_input<T>() -> Result<Vec<T>, Box<dyn Error>> where
+fn parse_input<T>() -> Result<Vec<T>, Box<dyn Error>>
+where
     T: FromStr,
-    <T as FromStr>::Err: Error + 'static
+    <T as FromStr>::Err: Error + 'static,
 {
-    use std::io::{BufRead, stdin};
+    use std::io::{stdin, BufRead};
 
     let mut values = Vec::new();
 
index c0dbaf7b577faceac53b68e8bf778a57c370b325..e1eb51f5362223956d84d3ddee8d86ef6c51d088 100644 (file)
@@ -1,30 +1,26 @@
-extern crate stud_rust_base;
+use stud_rust_base::{io::*, time::report_time, types::*};
 
-use stud_rust_base::{
-    types::*,
-    io::*,
-    time::report_time,
-};
+use std::{env, error::Error, path::Path};
 
-use std::{env, path::Path};
-
-fn main() {
-    let mut args = env::args();
-    args.next();
-
-    let arg = &args.next().expect("No directory arg given");
+fn main() -> Result<(), Box<dyn Error>> {
+    let arg = &env::args().nth(1).expect("No directory arg given");
     let path = Path::new(arg);
 
-    let first_out = Vec::<EdgeId>::load_from(path.join("first_out").to_str().unwrap()).expect("could not read first_out");
-    let head = Vec::<NodeId>::load_from(path.join("head").to_str().unwrap()).expect("could not read head");
-    let travel_time = Vec::<Weight>::load_from(path.join("travel_time").to_str().unwrap()).expect("could not read travel_time");
+    let first_out = Vec::<EdgeId>::load_from(path.join("first_out"))?;
+    let head = Vec::<NodeId>::load_from(path.join("head"))?;
+    let travel_time = Vec::<Weight>::load_from(path.join("travel_time"))?;
 
     report_time("iterating over arcs of some node", || {
         let node_id = 42;
-        for edge_id in first_out[node_id] .. first_out[node_id + 1] {
-            println!("There is an arc from {} to {} with weight {}", node_id, head[edge_id as usize], travel_time[edge_id as usize]);
+        for edge_id in first_out[node_id]..first_out[node_id + 1] {
+            println!(
+                "There is an arc from {} to {} with weight {}",
+                node_id, head[edge_id as usize], travel_time[edge_id as usize]
+            );
         }
     });
 
-    vec![42; 42].write_to(path.join("distances").to_str().unwrap()).expect("could not write distances");
+    vec![42; 42].write_to(&path.join("distances"))?;
+
+    Ok(())
 }
index e66421d7fe9a46368fb4905884892fdcd21087d8..fc083d1b7fd72fb23add1c61cb9640caa164b678 100644 (file)
@@ -1,6 +1,6 @@
 //! Utility module for command line interfaces
 
-use std::{fmt, fmt::Display, error::Error};
+use std::{error::Error, fmt, fmt::Display};
 
 /// An error struct to wrap simple static error messages
 #[derive(Debug)]
index a7af9ca1d84892a390a6342c859be9a3a0bbd3c8..2c6f61397984a7719e9d3156440d3ea28adbee7a 100644 (file)
 //!     }
 //! }
 //!
-//! fn main() {
-//!     let mut heap = IndexdMinHeap::new(3);
-//!     heap.push(State { node: 0, distance: 42 });
-//!     heap.push(State { node: 1, distance: 23 });
-//!     heap.push(State { node: 2, distance: 50000 });
-//!     assert_eq!(heap.peek().cloned(), Some(State { node: 1, distance: 23 }));
-//!     heap.decrease_key(State { node: 0, distance: 1 });
-//!     assert_eq!(heap.pop(), Some(State { node: 0, distance: 1 }));
-//! }
+//! let mut heap = IndexdMinHeap::new(3);
+//! heap.push(State { node: 0, distance: 42 });
+//! heap.push(State { node: 1, distance: 23 });
+//! heap.push(State { node: 2, distance: 50000 });
+//! assert_eq!(heap.peek().cloned(), Some(State { node: 1, distance: 23 }));
+//! heap.decrease_key(State { node: 0, distance: 1 });
+//! assert_eq!(heap.pop(), Some(State { node: 0, distance: 1 }));
 //!
 //! ```
 
@@ -55,7 +53,7 @@ pub trait Indexing {
 #[derive(Debug)]
 pub struct IndexdMinHeap<T: Ord + Indexing> {
     positions: Vec<usize>,
-    data: Vec<T>
+    data: Vec<T>,
 }
 
 const TREE_ARITY: usize = 4;
@@ -68,7 +66,7 @@ impl<T: Ord + Indexing> IndexdMinHeap<T> {
     pub fn new(max_index: usize) -> IndexdMinHeap<T> {
         IndexdMinHeap {
             positions: vec![INVALID_POSITION; max_index],
-            data: Vec::new()
+            data: Vec::new(),
         }
     }
 
@@ -125,19 +123,19 @@ impl<T: Ord + Indexing> IndexdMinHeap<T> {
     }
 
     /// Updates the key of an element if the new key is smaller than the old key.
-    /// Does nothing if the new key is larger.
-    /// Panics if the element is not part of the queue.
+    /// Panics if the element is not part of the queue or if the new key is larger.
     pub fn decrease_key(&mut self, element: T) {
         let position = self.positions[element.as_index()];
+        assert!(element <= self.data[position]);
         self.data[position] = element;
         self.move_up_in_tree(position);
     }
 
     /// Updates the key of an element if the new key is larger than the old key.
-    /// Does nothing if the new key is smaller.
-    /// Panics if the element is not part of the queue.
+    /// Panics if the element is not part of the queue or if the new key is smaller.
     pub fn increase_key(&mut self, element: T) {
         let position = self.positions[element.as_index()];
+        assert!(element >= self.data[position]);
         self.data[position] = element;
         self.move_down_in_tree(position);
     }
@@ -194,12 +192,10 @@ impl<T: Ord + Indexing> IndexdMinHeap<T> {
     }
 }
 
-
 // This is an optimization copied straight from the rust stdlib binary heap
 // it allows to avoid always swapping elements pairwise and rather
 // move each element only once.
 
-
 /// Hole represents a hole in a slice i.e. an index without valid value
 /// (because it was moved from or duplicated).
 /// In drop, `Hole` will restore the slice by filling the hole
@@ -219,11 +215,7 @@ impl<'a, T> Hole<'a, T> {
     unsafe fn new(data: &'a mut [T], pos: usize) -> Self {
         debug_assert!(pos < data.len());
         let elt = ptr::read(&data[pos]);
-        Hole {
-            data,
-            elt: Some(elt),
-            pos,
-        }
+        Hole { data, elt: Some(elt), pos }
     }
 
     /// Returns a reference to the element removed.
index 419fa4520eb67ed5cbf3337bd1824586cc769257..3c4d73276be9e703cc68245f50e37cddb695bf57 100644 (file)
--- a/src/io.rs
+++ b/src/io.rs
@@ -1,26 +1,26 @@
 //! This module contains a few traits and blanket implementations
-//! for (de)serializing and writing/reading numeric data to/from the disc.
+//! for (de)serializing and writing/reading data to/from the disc.
 //! To use it you should import the `Load` and `Store` traits and use the
 //! `load_from` and `write_to` methods.
 //!
 //! # Example
 //!
-//! ```
-//! use stud_rust_base::io::*;
+//! ```no_run
+//! use stud_rust_base::io::*;
 //!
-//! fn test() {
-//!     let head = Vec::<u32>::load_from("head_file_name").expect("could not read head");
-//!     let lat = Vec::<f32>::load_from("node_latitude_file_name").expect("could not read lat");
-//!     head.write_to("output_file").expect("could not write head");
-//! }
+//! let head = Vec::<u32>::load_from("head_file_name")?;
+//! let lat = Vec::<f32>::load_from("node_latitude_file_name")?;
+//! head.write_to(&"output_file")?;
+//! # Ok::<(), Box<dyn std::error::Error>>(())
 //! ```
 
-use std::fs;
-use std::fs::File;
-use std::io::prelude::*;
-use std::io::Result;
-use std::mem;
-use std::slice;
+use std::{
+    fs::{metadata, File},
+    io::{prelude::*, Result},
+    mem,
+    path::Path,
+    slice,
+};
 
 /// A trait which allows accessing the data of an object as a slice of bytes.
 /// The bytes should represent a serialization of the object and allow
@@ -49,6 +49,12 @@ impl<T: Copy> DataBytes for [T] {
     }
 }
 
+impl<T: Copy> DataBytes for Vec<T> {
+    fn data_bytes(&self) -> &[u8] {
+        self[..].data_bytes()
+    }
+}
+
 impl<T: Copy> DataBytesMut for [T] {
     fn data_bytes_mut(&mut self) -> &mut [u8] {
         let num_bytes = self.len() * mem::size_of::<T>();
@@ -64,10 +70,10 @@ impl<T: Copy> DataBytesMut for Vec<T> {
 }
 
 /// A trait which extends the `DataBytes` trait and exposes a method to write objects to disk.
-pub trait Store : DataBytes {
-    /// Writes the serialized object to the file with the given filename
-    fn write_to(&self, filename: &str) -> Result<()> {
-        File::create(filename)?.write_all(self.data_bytes())
+pub trait Store: DataBytes {
+    /// Writes the serialized object to the file with the given path
+    fn write_to(&self, path: &dyn AsRef<Path>) -> Result<()> {
+        File::create(path)?.write_all(self.data_bytes())
     }
 }
 
@@ -75,16 +81,16 @@ impl<T: DataBytes> Store for T {}
 impl<T> Store for [T] where [T]: DataBytes {}
 
 /// A trait to load serialized data back into objects.
-pub trait Load : DataBytesMut + Sized {
+pub trait Load: DataBytesMut + Sized {
     /// This method must create an object of the correct size for serialized data with the given number of bytes.
     /// It should not be necessary to call this method directly.
     fn new_with_bytes(num_bytes: usize) -> Self;
 
     /// This method will load serialized data from the disk, create an object of the appropriate size,
     /// deserialize the bytes into the object and return the object.
-    fn load_from(filename: &str) -> Result<Self> {
-        let metadata = fs::metadata(filename)?;
-        let mut file = File::open(filename)?;
+    fn load_from<P: AsRef<Path>>(path: P) -> Result<Self> {
+        let metadata = metadata(path.as_ref())?;
+        let mut file = File::open(path)?;
 
         let mut object = Self::new_with_bytes(metadata.len() as usize);
         assert_eq!(metadata.len() as usize, object.data_bytes_mut().len());
index 85f3191635b60074e19146630fea710639a520a1..d0ab4df6877dcd0ffb1140dc66cc1038286deda9 100644 (file)
@@ -1,7 +1,5 @@
 //! A small base framework for route planning student projects.
 
-extern crate time as time_crate;
-
 pub mod cli;
 pub mod index_heap;
 pub mod io;
index 8a3843c37641c72832c70eceec81f3b845d29b55..33c720c83b3ec2a8eef407d87e94f08f9b7b8d39 100644 (file)
@@ -1,30 +1,29 @@
 //! This module contains a few utilities to measure how long executing algorithms takes.
-//! It utilizes the `time` crate.
 
-use time_crate as time;
+use std::time::*;
 
 /// This function will measure how long it takes to execute the given lambda,
 /// print the time and return the result of the lambda.
 pub fn report_time<Out, F: FnOnce() -> Out>(name: &str, f: F) -> Out {
-    let start = time::now();
-    println!("starting {}", name);
+    let start = Instant::now();
+    eprintln!("starting {}", name);
     let res = f();
-    println!("done {} - took: {}", name, (time::now() - start));
+    eprintln!("done {} - took: {}s", name, start.elapsed().as_secs_f64());
     res
 }
 
 /// This function will measure how long it takes to execute the given lambda
 /// and return a tuple of the result of the lambda and a duration object.
-pub fn measure<Out, F: FnOnce() -> Out>(f: F) -> (Out, time::Duration) {
-    let start = time::now();
+pub fn measure<Out, F: FnOnce() -> Out>(f: F) -> (Out, Duration) {
+    let start = Instant::now();
     let res = f();
-    (res, time::now() - start)
+    (res, start.elapsed())
 }
 
 /// A struct to repeatedly measure the time passed since the timer was started
 #[derive(Debug)]
 pub struct Timer {
-    start: time::Tm
+    start: Instant,
 }
 
 impl Default for Timer {
@@ -36,21 +35,26 @@ impl Default for Timer {
 impl Timer {
     /// Create and start a new `Timer`
     pub fn new() -> Timer {
-        Timer { start: time::now() }
+        Timer { start: Instant::now() }
     }
 
     /// Reset the `Timer`
     pub fn restart(&mut self) {
-        self.start = time::now();
+        self.start = Instant::now();
     }
 
     /// Print the passed time in ms since the timer was started
     pub fn report_passed_ms(&self) {
-        println!("{}ms", (time::now() - self.start).num_milliseconds());
+        eprintln!("{}ms", self.start.elapsed().as_secs_f64() * 1000.0);
     }
 
     /// Return the number of ms passed since the timer was started as a `i64`
-    pub fn get_passed_ms(&self) -> i64 {
-        (time::now() - self.start).num_milliseconds()
+    pub fn get_passed_ms(&self) -> f64 {
+        self.start.elapsed().as_secs_f64() * 1000.0
+    }
+
+    /// Return the number of ms passed since the timer was started as a `std::time::Duration`
+    pub fn get_passed(&self) -> Duration {
+        self.start.elapsed()
     }
 }