From: Tim "tim3z" Zeitz Date: Thu, 16 Dec 2021 09:47:11 +0000 (+0100) Subject: updates, clippy, formatting X-Git-Url: https://i11git.iti.kit.edu/anon-gitweb/?p=Mitarbeiter%2FTim-Zeitz%2Fstud-rust-base.git;a=commitdiff_plain;h=HEAD;hp=70c3d16d15df7a8f4b4f4dde818add5cae0ebd0d updates, clippy, formatting --- diff --git a/Cargo.lock b/Cargo.lock index 52822a5..b98a97a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,55 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -[[package]] -name = "libc" -version = "0.2.62" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "redox_syscall" -version = "0.1.56" -source = "registry+https://github.com/rust-lang/crates.io-index" +version = 3 [[package]] name = "stud-rust-base" version = "0.1.0" -dependencies = [ - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "time" -version = "0.1.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "winapi" -version = "0.3.8" -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.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba" -"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" -"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" -"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" -"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" diff --git a/Cargo.toml b/Cargo.toml index 344beb8..42ddd25 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,4 @@ name = "stud-rust-base" version = "0.1.0" authors = ["Tim Zeitz "] -edition = '2018' - -[dependencies] -time = "^0.1.40" +edition = '2021' diff --git a/README.md b/README.md index 7239043..59210f9 100644 --- a/README.md +++ b/README.md @@ -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::::load_from("head_file_name").expect("could not read head"); -let lat = Vec::::load_from("node_latitude_file_name").expect("could not read lat"); -head.write_to("output_file").expect("could not write head"); +let head = Vec::::load_from("head_file_name")?; +let lat = Vec::::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::::load_from("first_out_file_name").expect("could not read first_out"); -let head = Vec::::load_from("head_file_name").expect("could not read head"); -let travel_time = Vec::::load_from("weight_file_name").expect("could not read travel_time"); +let first_out = Vec::::load_from("first_out_file_name")?; +let head = Vec::::load_from("head_file_name")?; +let travel_time = Vec::::load_from("weight_file_name")?; let node_id = 42; for edge_id in first_out[node_id] .. first_out[node_id + 1] { diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..b28d8cf --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1 @@ +max_width = 160 diff --git a/src/bin/compare_vector.rs b/src/bin/compare_vector.rs index 2f566ed..9aab030 100644 --- a/src/bin/compare_vector.rs +++ b/src/bin/compare_vector.rs @@ -1,48 +1,38 @@ -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> { - let mut args = env::args(); - args.next(); - - match &args.collect::>()[..] { - [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::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "u8" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "i16" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "u16" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "i32" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "u32" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "i64" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "u64" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "f32" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "f64" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "int8" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "uint8" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "int16" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "uint16" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "int32" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "uint32" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "int64" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "uint64" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "float32" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "float64" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, + "i8" | "int8" => compare_values::(&Vec::load_from(input1)?, &Vec::load_from(input2)?), + "u8" | "uint8" => compare_values::(&Vec::load_from(input1)?, &Vec::load_from(input2)?), + "i16" | "int16" => compare_values::(&Vec::load_from(input1)?, &Vec::load_from(input2)?), + "u16" | "uint16" => compare_values::(&Vec::load_from(input1)?, &Vec::load_from(input2)?), + "i32" | "int32" => compare_values::(&Vec::load_from(input1)?, &Vec::load_from(input2)?), + "u32" | "uint32" => compare_values::(&Vec::load_from(input1)?, &Vec::load_from(input2)?), + "i64" | "int64" => compare_values::(&Vec::load_from(input1)?, &Vec::load_from(input2)?), + "u64" | "uint64" => compare_values::(&Vec::load_from(input1)?, &Vec::load_from(input2)?), + "f32" | "float32" => compare_values::(&Vec::load_from(input1)?, &Vec::load_from(input2)?), + "f64" | "float64" => compare_values::(&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 @@ -56,17 +46,23 @@ Compares two vectors of elements in binary format. data_type can be one of * f32 * f64 -"); +" + ); } -fn compare_values(values1: &[T], values2: &[T]) where +fn compare_values(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; @@ -74,8 +70,12 @@ fn compare_values(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) @@ -92,10 +92,10 @@ fn compare_values(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()); - }, + } } } diff --git a/src/bin/decode_vector.rs b/src/bin/decode_vector.rs index 4dca2e7..6169732 100644 --- a/src/bin/decode_vector.rs +++ b/src/bin/decode_vector.rs @@ -1,48 +1,36 @@ -use stud_rust_base::{io::*, cli::CliErr}; use std::{env, error::Error}; +use stud_rust_base::{cli::CliErr, io::*}; fn main() -> Result<(), Box> { - let mut args = env::args(); - args.next(); - - match &args.collect::>()[..] { - [data_type, input] => { - match data_type.as_ref() { - "i8" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "u8" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "i16" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "u16" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "i32" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "u32" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "i64" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "u64" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "f32" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "f64" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "int8" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "uint8" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "int16" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "uint16" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "int32" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "uint32" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "int64" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "uint64" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "float32" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "float64" => { print_values(Vec::::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::::load_from(input)?), + "u8" | "uint8" => print_values(Vec::::load_from(input)?), + "i16" | "int16" => print_values(Vec::::load_from(input)?), + "u16" | "uint16" => print_values(Vec::::load_from(input)?), + "i32" | "int32" => print_values(Vec::::load_from(input)?), + "u32" | "uint32" => print_values(Vec::::load_from(input)?), + "i64" | "int64" => print_values(Vec::::load_from(input)?), + "u64" | "uint64" => print_values(Vec::::load_from(input)?), + "f32" | "float32" => print_values(Vec::::load_from(input)?), + "f64" | "float64" => print_values(Vec::::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 @@ -56,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(values: Vec) where - T: Display +fn print_values(values: Vec) +where + T: Display, { for v in values { println!("{}", v); diff --git a/src/bin/encode_vector.rs b/src/bin/encode_vector.rs index a51a63a..a56eb82 100644 --- a/src/bin/encode_vector.rs +++ b/src/bin/encode_vector.rs @@ -1,43 +1,32 @@ -use stud_rust_base::{io::*, cli::CliErr}; use std::{env, error::Error}; +use stud_rust_base::{cli::CliErr, io::*}; fn main() -> Result<(), Box> { - let mut args = env::args(); - args.next(); - - match &args.collect::>()[..] { - [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::()?.write_to(output)?; Ok(()) }, - "u8" => { parse_input::()?.write_to(output)?; Ok(()) }, - "i16" => { parse_input::()?.write_to(output)?; Ok(()) }, - "u16" => { parse_input::()?.write_to(output)?; Ok(()) }, - "i32" => { parse_input::()?.write_to(output)?; Ok(()) }, - "u32" => { parse_input::()?.write_to(output)?; Ok(()) }, - "i64" => { parse_input::()?.write_to(output)?; Ok(()) }, - "u64" => { parse_input::()?.write_to(output)?; Ok(()) }, - "f32" => { parse_input::()?.write_to(output)?; Ok(()) }, - "f64" => { parse_input::()?.write_to(output)?; Ok(()) }, - "int8" => { parse_input::()?.write_to(output)?; Ok(()) }, - "uint8" => { parse_input::()?.write_to(output)?; Ok(()) }, - "int16" => { parse_input::()?.write_to(output)?; Ok(()) }, - "uint16" => { parse_input::()?.write_to(output)?; Ok(()) }, - "int32" => { parse_input::()?.write_to(output)?; Ok(()) }, - "uint32" => { parse_input::()?.write_to(output)?; Ok(()) }, - "int64" => { parse_input::()?.write_to(output)?; Ok(()) }, - "uint64" => { parse_input::()?.write_to(output)?; Ok(()) }, - "float32" => { parse_input::()?.write_to(output)?; Ok(()) }, - "float64" => { parse_input::()?.write_to(output)?; Ok(()) }, + "i8" | "int8" => parse_input::()?.write_to(output)?, + "u8" | "uint8" => parse_input::()?.write_to(output)?, + "i16" | "int16" => parse_input::()?.write_to(output)?, + "u16" | "uint16" => parse_input::()?.write_to(output)?, + "i32" | "int32" => parse_input::()?.write_to(output)?, + "u32" | "uint32" => parse_input::()?.write_to(output)?, + "i64" | "int64" => parse_input::()?.write_to(output)?, + "u64" | "uint64" => parse_input::()?.write_to(output)?, + "f32" | "float32" => parse_input::()?.write_to(output)?, + "f64" | "float64" => parse_input::()?.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"))) - }, + } } } @@ -61,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() -> Result, Box> where +fn parse_input() -> Result, Box> +where T: FromStr, - ::Err: Error + 'static + ::Err: Error + 'static, { - use std::io::{BufRead, stdin}; + use std::io::{stdin, BufRead}; let mut values = Vec::new(); diff --git a/src/bin/example.rs b/src/bin/example.rs index f8e9434..e1eb51f 100644 --- a/src/bin/example.rs +++ b/src/bin/example.rs @@ -1,28 +1,26 @@ -use stud_rust_base::{ - types::*, - io::*, - time::report_time, -}; +use stud_rust_base::{io::*, time::report_time, types::*}; -use std::{env, path::Path}; +use std::{env, error::Error, path::Path}; -fn main() { - let mut args = env::args(); - args.next(); - - let arg = &args.next().expect("No directory arg given"); +fn main() -> Result<(), Box> { + let arg = &env::args().nth(1).expect("No directory arg given"); let path = Path::new(arg); - let first_out = Vec::::load_from(path.join("first_out").to_str().unwrap()).expect("could not read first_out"); - let head = Vec::::load_from(path.join("head").to_str().unwrap()).expect("could not read head"); - let travel_time = Vec::::load_from(path.join("travel_time").to_str().unwrap()).expect("could not read travel_time"); + let first_out = Vec::::load_from(path.join("first_out"))?; + let head = Vec::::load_from(path.join("head"))?; + let travel_time = Vec::::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(()) } diff --git a/src/cli.rs b/src/cli.rs index e66421d..fc083d1 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -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)] diff --git a/src/index_heap.rs b/src/index_heap.rs index a7af9ca..2c6f613 100644 --- a/src/index_heap.rs +++ b/src/index_heap.rs @@ -23,15 +23,13 @@ //! } //! } //! -//! 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 { positions: Vec, - data: Vec + data: Vec, } const TREE_ARITY: usize = 4; @@ -68,7 +66,7 @@ impl IndexdMinHeap { pub fn new(max_index: usize) -> IndexdMinHeap { IndexdMinHeap { positions: vec![INVALID_POSITION; max_index], - data: Vec::new() + data: Vec::new(), } } @@ -125,19 +123,19 @@ impl IndexdMinHeap { } /// 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 IndexdMinHeap { } } - // 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. diff --git a/src/io.rs b/src/io.rs index 419fa45..3c4d732 100644 --- 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::::load_from("head_file_name").expect("could not read head"); -//! let lat = Vec::::load_from("node_latitude_file_name").expect("could not read lat"); -//! head.write_to("output_file").expect("could not write head"); -//! } +//! let head = Vec::::load_from("head_file_name")?; +//! let lat = Vec::::load_from("node_latitude_file_name")?; +//! head.write_to(&"output_file")?; +//! # Ok::<(), Box>(()) //! ``` -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 DataBytes for [T] { } } +impl DataBytes for Vec { + fn data_bytes(&self) -> &[u8] { + self[..].data_bytes() + } +} + impl DataBytesMut for [T] { fn data_bytes_mut(&mut self) -> &mut [u8] { let num_bytes = self.len() * mem::size_of::(); @@ -64,10 +70,10 @@ impl DataBytesMut for Vec { } /// 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) -> Result<()> { + File::create(path)?.write_all(self.data_bytes()) } } @@ -75,16 +81,16 @@ impl Store for T {} impl 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 { - let metadata = fs::metadata(filename)?; - let mut file = File::open(filename)?; + fn load_from>(path: P) -> Result { + 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()); diff --git a/src/time.rs b/src/time.rs index 687f3e4..33c720c 100644 --- a/src/time.rs +++ b/src/time.rs @@ -1,28 +1,29 @@ //! This module contains a few utilities to measure how long executing algorithms takes. -//! It utilizes the `time` crate. + +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>(name: &str, f: F) -> Out { - let start = time::now(); + let start = Instant::now(); eprintln!("starting {}", name); let res = f(); - eprintln!("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: F) -> (Out, time::Duration) { - let start = time::now(); +pub fn measure 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 { @@ -34,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) { - eprintln!("{}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() } }