diff --git a/Cargo.lock b/Cargo.lock index 519c7fd..d9ffcc7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,15 +65,6 @@ dependencies = [ "libc", ] -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - [[package]] name = "anstream" version = "0.6.4" @@ -137,17 +128,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", -] - [[package]] name = "autocfg" version = "0.1.8" @@ -370,21 +350,6 @@ dependencies = [ "phf_codegen 0.11.2", ] -[[package]] -name = "clap" -version = "2.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" -dependencies = [ - "ansi_term", - "atty", - "bitflags 1.3.2", - "strsim 0.8.0", - "textwrap", - "unicode-width", - "vec_map", -] - [[package]] name = "clap" version = "4.4.6" @@ -404,7 +369,7 @@ dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim 0.10.0", + "strsim", ] [[package]] @@ -857,7 +822,7 @@ dependencies = [ "build_html", "bytes", "chrono", - "clap 4.4.6", + "clap", "cookie", "cool_asserts", "futures-util", @@ -1642,15 +1607,6 @@ dependencies = [ "unicode-segmentation", ] -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - [[package]] name = "hermit-abi" version = "0.3.3" @@ -1969,20 +1925,11 @@ version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ - "hermit-abi 0.3.3", + "hermit-abi", "rustix", "windows-sys", ] -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.11.0" @@ -2025,21 +1972,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "jsonwebtoken" -version = "5.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d438ea707d465c230305963b67f8357a1d56fcfad9434797d7cb1c46c2e41df" -dependencies = [ - "base64 0.9.3", - "chrono", - "ring", - "serde 1.0.188", - "serde_derive", - "serde_json", - "untrusted", -] - [[package]] name = "kifu-core" version = "0.1.0" @@ -2150,12 +2082,6 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "linked-hash-map" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" - [[package]] name = "linux-raw-sys" version = "0.4.8" @@ -2465,7 +2391,7 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.3.3", + "hermit-abi", "libc", ] @@ -2528,23 +2454,6 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "orizentic" -version = "1.0.1" -dependencies = [ - "chrono", - "clap 2.34.0", - "itertools 0.10.5", - "jsonwebtoken", - "serde 1.0.188", - "serde_derive", - "serde_json", - "thiserror", - "uuid 0.8.2", - "version_check 0.1.5", - "yaml-rust", -] - [[package]] name = "pango" version = "0.17.10" @@ -3210,18 +3119,6 @@ dependencies = [ "winreg", ] -[[package]] -name = "ring" -version = "0.13.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c4db68a2e35f3497146b7e4563df7d4773a2433230c5e4b448328e31740458a" -dependencies = [ - "cc", - "lazy_static", - "libc", - "untrusted", -] - [[package]] name = "rsa" version = "0.9.2" @@ -3575,7 +3472,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b7b278788e7be4d0d29c0f39497a0eef3fba6bbc8e70d8bf7fde46edeaa9e85" dependencies = [ - "itertools 0.11.0", + "itertools", "nom", "unicode_categories", ] @@ -3785,12 +3682,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "strsim" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" - [[package]] name = "strsim" version = "0.10.0" @@ -3897,15 +3788,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "textwrap" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] - [[package]] name = "thiserror" version = "1.0.49" @@ -4324,12 +4206,6 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" -[[package]] -name = "unicode-width" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" - [[package]] name = "unicode_categories" version = "0.1.1" @@ -4345,12 +4221,6 @@ dependencies = [ "traitobject", ] -[[package]] -name = "untrusted" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f" - [[package]] name = "url" version = "1.7.2" @@ -4420,12 +4290,6 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - [[package]] name = "version-compare" version = "0.1.1" @@ -4718,15 +4582,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "yaml-rust" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" -dependencies = [ - "linked-hash-map", -] - [[package]] name = "zeroize" version = "1.6.0" diff --git a/Cargo.toml b/Cargo.toml index f2c4da9..8a3c4df 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,6 @@ members = [ "kifu/core", "kifu/gtk", "memorycache", - "orizentic", "screenplay", "sgf", "nom-training", diff --git a/build.sh b/build.sh index 41eee5c..ad92ff2 100755 --- a/build.sh +++ b/build.sh @@ -20,7 +20,6 @@ RUST_ALL_TARGETS=( "kifu-core" "kifu-gtk" "memorycache" - "orizentic" "screenplay" "sgf" ) @@ -39,6 +38,7 @@ build_dist() { for target in $TARGETS; do if [ -f $target/dist.sh ]; then + build_rust_targets release ${TARGETS[*]} cd $target && ./dist.sh fi done diff --git a/builders/rust.sh b/builders/rust.sh index 0394805..e9c63ea 100755 --- a/builders/rust.sh +++ b/builders/rust.sh @@ -14,6 +14,9 @@ case $CMD in build) $CARGO build $MODULE $PARAMS ;; + lint) + $CARGO clippy $MODULE $PARAMS -- -Dwarnings + ;; test) $CARGO test $MODULE $PARAMS ;; @@ -21,16 +24,18 @@ case $CMD in $CARGO run $MODULE $PARAMS ;; release) + $CARGO clippy $MODULE $PARAMS -- -Dwarnings $CARGO build --release $MODULE $PARAMS + $CARGO test --release $MODULE $PARAMS ;; clean) $CARGO clean $MODULE ;; "") - echo "No command specified. Use build | test | run | release | clean" + echo "No command specified. Use build | lint | test | run | release | clean" ;; *) - echo "$CMD is unknown. Use build | test | run | release | clean" + echo "$CMD is unknown. Use build | lint | test | run | release | clean" ;; esac diff --git a/changeset/Cargo.toml b/changeset/Cargo.toml index 0e02630..450fd56 100644 --- a/changeset/Cargo.toml +++ b/changeset/Cargo.toml @@ -3,7 +3,6 @@ name = "changeset" version = "0.1.0" edition = "2021" license = "GPL-3.0-only" -license-file = "../COPYING" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/changeset/src/lib.rs b/changeset/src/lib.rs index 40a0666..4173ad7 100644 --- a/changeset/src/lib.rs +++ b/changeset/src/lib.rs @@ -26,7 +26,7 @@ pub enum Change { NewRecord(Value), } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub struct Changeset { delete: HashSet, update: HashMap, @@ -34,14 +34,6 @@ pub struct Changeset { } impl Changeset { - pub fn new() -> Self { - Self { - delete: HashSet::new(), - update: HashMap::new(), - new: HashMap::new(), - } - } - pub fn add(&mut self, r: Value) -> Key { let k = Key::new(); self.new.insert(k.clone(), r); @@ -90,7 +82,7 @@ impl From> for Vec Self { @@ -110,7 +102,7 @@ mod tests { #[test] fn it_generates_a_new_record() { - let mut set: Changeset = Changeset::new(); + let mut set: Changeset = Changeset::default(); set.add("efgh".to_string()); let changes = Vec::from(set.clone()); assert_eq!(changes.len(), 1); @@ -125,7 +117,7 @@ mod tests { #[test] fn it_generates_a_delete_record() { - let mut set: Changeset = Changeset::new(); + let mut set: Changeset = Changeset::default(); let id1 = Id::new(); set.delete(id1.clone()); let changes = Vec::from(set.clone()); @@ -142,7 +134,7 @@ mod tests { #[test] fn update_unrelated_records() { - let mut set: Changeset = Changeset::new(); + let mut set: Changeset = Changeset::default(); let id1 = Id::new(); let id2 = Id::new(); set.update(id1.clone(), "abcd".to_owned()); @@ -155,7 +147,7 @@ mod tests { #[test] fn delete_cancels_new() { - let mut set: Changeset = Changeset::new(); + let mut set: Changeset = Changeset::default(); let key = set.add("efgh".to_string()); set.delete(key); let changes = Vec::from(set); @@ -164,7 +156,7 @@ mod tests { #[test] fn delete_cancels_update() { - let mut set: Changeset = Changeset::new(); + let mut set: Changeset = Changeset::default(); let id = Id::new(); set.update(id.clone(), "efgh".to_owned()); set.delete(id.clone()); @@ -175,7 +167,7 @@ mod tests { #[test] fn update_atop_new_is_new() { - let mut set: Changeset = Changeset::new(); + let mut set: Changeset = Changeset::default(); let key = set.add("efgh".to_owned()); set.update(key, "wxyz".to_owned()); let changes = Vec::from(set); @@ -185,7 +177,7 @@ mod tests { #[test] fn updates_get_squashed() { - let mut set: Changeset = Changeset::new(); + let mut set: Changeset = Changeset::default(); let id1 = Id::new(); let id2 = Id::new(); set.update(id1.clone(), "efgh".to_owned()); diff --git a/coordinates/src/bin/default_map.rs b/coordinates/src/bin/default_map.rs index b5f6ba4..356720d 100644 --- a/coordinates/src/bin/default_map.rs +++ b/coordinates/src/bin/default_map.rs @@ -33,12 +33,12 @@ fn main() { let filename = args .next() - .map(|p| PathBuf::from(p)) + .map(PathBuf::from) .expect("A filename is required"); let size = args .next() .and_then(|s| s.parse::().ok()) .unwrap_or(3); let map: hex_map::Map = hex_map::Map::new_hexagonal(size); - hex_map::write_file(filename, map); + hex_map::write_file(filename, map).expect("to write file"); } diff --git a/coordinates/src/hex.rs b/coordinates/src/hex.rs index d3b9880..d11b3a7 100644 --- a/coordinates/src/hex.rs +++ b/coordinates/src/hex.rs @@ -10,10 +10,9 @@ Luminescent Dreams Tools is distributed in the hope that it will be useful, but You should have received a copy of the GNU General Public License along with Lumeto. If not, see . */ -/// Ĉi-tiu modulo enhavas la elementojn por kub-koordinato. +/// This module contains the elements of cube coordinates. /// /// This code is based on https://www.redblobgames.com/grids/hexagons/ -use crate::Error; use std::collections::HashSet; /// An address within the hex coordinate system @@ -62,7 +61,7 @@ impl AxialAddr { pub fn is_adjacent(&self, dest: &AxialAddr) -> bool { dest.adjacencies() .collect::>() - .contains(&self) + .contains(self) } /// Measure the distance to a destination @@ -79,7 +78,7 @@ impl AxialAddr { positions.push(item); - while positions.len() > 0 { + while !positions.is_empty() { let elem = positions.remove(0); for adj in elem.adjacencies() { if self.distance(&adj) <= distance && !results.contains(&adj) { diff --git a/coordinates/src/hex_map.rs b/coordinates/src/hex_map.rs index 72ff9cc..76e9eab 100644 --- a/coordinates/src/hex_map.rs +++ b/coordinates/src/hex_map.rs @@ -14,7 +14,6 @@ use crate::{hex::AxialAddr, Error}; use nom::{ bytes::complete::tag, character::complete::alphanumeric1, - error::ParseError, multi::many1, sequence::{delimited, separated_pair}, Finish, IResult, Parser, @@ -81,7 +80,7 @@ pub fn parse_data<'a, A: Default + From>( } let cells = data - .map(|line| parse_line::(&line).unwrap()) + .map(|line| parse_line::(line).unwrap()) .collect::>(); let cells = cells.into_iter().collect::>(); Map { cells } diff --git a/coordinates/src/lib.rs b/coordinates/src/lib.rs index 52c337c..6d591ad 100644 --- a/coordinates/src/lib.rs +++ b/coordinates/src/lib.rs @@ -9,9 +9,9 @@ Lumeto is distributed in the hope that it will be useful, but WITHOUT ANY WARRAN You should have received a copy of the GNU General Public License along with Lumeto. If not, see . */ -use thiserror; +use thiserror::Error; -#[derive(Debug, thiserror::Error)] +#[derive(Debug, Error)] pub enum Error { #[error("IO error on reading or writing: {0}")] IO(std::io::Error), diff --git a/cyberpunk-splash/Cargo.toml b/cyberpunk-splash/Cargo.toml index 04909e5..778a542 100644 --- a/cyberpunk-splash/Cargo.toml +++ b/cyberpunk-splash/Cargo.toml @@ -2,6 +2,7 @@ name = "cyberpunk-splash" version = "0.1.0" edition = "2021" +license = "GPL-3.0-only" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/cyberpunk-splash/src/main.rs b/cyberpunk-splash/src/main.rs index 0e188cb..12bcf3c 100644 --- a/cyberpunk-splash/src/main.rs +++ b/cyberpunk-splash/src/main.rs @@ -2,8 +2,8 @@ use cairo::{ Context, FontSlant, FontWeight, Format, ImageSurface, LineCap, LinearGradient, Pattern, TextExtents, }; -use glib::{GString, Object}; -use gtk::{gdk::Key, prelude::*, subclass::prelude::*, EventControllerKey}; +use glib::Object; +use gtk::{prelude::*, subclass::prelude::*, EventControllerKey}; use std::{ cell::RefCell, rc::Rc, @@ -14,12 +14,6 @@ use std::{ const WIDTH: i32 = 1600; const HEIGHT: i32 = 600; -#[derive(Clone, Copy, Debug)] -enum Event { - Frames(u8), - Time(Duration), -} - #[derive(Clone, Copy, Debug)] pub enum State { Running { @@ -50,7 +44,7 @@ impl State { *self = Self::Running { last_update: Instant::now(), deadline: Instant::now() + *time_remaining, - timeout: timeout.clone(), + timeout: *timeout, }; } } @@ -62,7 +56,7 @@ impl State { { *self = Self::Paused { time_remaining: *deadline - Instant::now(), - timeout: timeout.clone(), + timeout: *timeout, } } } @@ -108,13 +102,13 @@ impl TimeoutAnimation { fn tick(&mut self, frames_elapsed: u8) { let step_size = 1. / (self.duration * 60.); if self.ascending { - self.intensity = self.intensity + step_size * frames_elapsed as f64; + self.intensity += step_size * frames_elapsed as f64; if self.intensity > 1. { self.intensity = 1.0; self.ascending = false; } } else { - self.intensity = self.intensity - step_size * frames_elapsed as f64; + self.intensity -= step_size * frames_elapsed as f64; if self.intensity < 0. { self.intensity = 0.0; self.ascending = true; @@ -148,7 +142,6 @@ impl SplashPrivate { *self.height.borrow(), 2., 8., - 8., (0.7, 0., 1.), ); @@ -333,7 +326,7 @@ impl Splash { let _ = context.set_source(&*background); let _ = context.paint(); - let state = s.imp().state.borrow().clone(); + let state = *s.imp().state.borrow(); let time = match state { State::Running { deadline, .. } => deadline - Instant::now(), @@ -359,7 +352,7 @@ impl Splash { let mut saved_extents = s.imp().time_extents.borrow_mut(); if saved_extents.is_none() { - *saved_extents = Some(time_extents.clone()); + *saved_extents = Some(time_extents); } let time_baseline_x = center_x - time_extents.width() / 2.; @@ -372,8 +365,8 @@ impl Splash { time_baseline_y, ); let (running, timeout_animation) = match state { - State::Running { timeout, .. } => (true, timeout.clone()), - State::Paused { timeout, .. } => (false, timeout.clone()), + State::Running { timeout, .. } => (true, timeout), + State::Paused { timeout, .. } => (false, timeout), }; match timeout_animation { Some(ref animation) => { @@ -395,21 +388,18 @@ impl Splash { let _ = context.show_text(&time); }; - match *s.imp().time_extents.borrow() { - Some(extents) => { - context.set_source_rgb(0.7, 0.0, 1.0); - let time_meter = SlashMeter { - orientation: gtk::Orientation::Horizontal, - start_x: center_x + extents.width() / 2. + 50., - start_y: center_y + 100., - count: 5, - fill_count: minutes as u8, - height: 60., - length: 100., - }; - time_meter.draw(&context); - } - None => {} + if let Some(extents) = *s.imp().time_extents.borrow() { + context.set_source_rgb(0.7, 0.0, 1.0); + let time_meter = SlashMeter { + orientation: gtk::Orientation::Horizontal, + start_x: center_x + extents.width() / 2. + 50., + start_y: center_y + 100., + count: 5, + fill_count: minutes as u8, + height: 60., + length: 100., + }; + time_meter.draw(context); } } }); @@ -544,7 +534,7 @@ impl SlashMeter { gtk::Orientation::Horizontal => { let angle: f64 = 0.8; let run = self.height / angle.tan(); - let width = self.length as f64 / (self.count as f64 * 2.); + let width = self.length / (self.count as f64 * 2.); for c in 0..self.count { context.set_line_width(1.); @@ -579,10 +569,6 @@ trait Pen { struct GlowPen { blur_context: Context, draw_context: Context, - - line_width: f64, - blur_line_width: f64, - blur_size: f64, } impl GlowPen { @@ -591,7 +577,6 @@ impl GlowPen { height: i32, line_width: f64, blur_line_width: f64, - blur_size: f64, color: (f64, f64, f64), ) -> Self { let blur_context = @@ -611,9 +596,6 @@ impl GlowPen { Self { blur_context, draw_context, - line_width, - blur_line_width, - blur_size, } } } @@ -630,8 +612,10 @@ impl Pen for GlowPen { } fn stroke(&self) { - self.blur_context.stroke(); - self.draw_context.stroke(); + self.blur_context.stroke().expect("to draw the blur line"); + self.draw_context + .stroke() + .expect("to draw the regular line"); } fn finish(self) -> Pattern { @@ -681,7 +665,7 @@ fn main() { let countdown = match options.lookup::("countdown") { Ok(Some(countdown_str)) => { let parts = countdown_str.split(':').collect::>(); - let duration = match parts.len() { + match parts.len() { 2 => { let minutes = parts[0].parse::().unwrap(); let seconds = parts[1].parse::().unwrap(); @@ -692,8 +676,7 @@ fn main() { Duration::from_secs(seconds) } _ => Duration::from_secs(300), - }; - duration + } } _ => Duration::from_secs(300), }; @@ -725,7 +708,7 @@ fn main() { let window = gtk::ApplicationWindow::new(app); window.present(); - let splash = Splash::new(title.read().unwrap().clone(), state.read().unwrap().clone()); + let splash = Splash::new(title.read().unwrap().clone(), *state.read().unwrap()); window.set_child(Some(&splash)); @@ -763,7 +746,7 @@ fn main() { loop { std::thread::sleep(Duration::from_millis(1000 / 60)); state.write().unwrap().run(Instant::now()); - let _ = gtk_tx.send(state.read().unwrap().clone()); + let _ = gtk_tx.send(*state.read().unwrap()); } } }); diff --git a/dashboard/dist.sh b/dashboard/dist.sh index d7753aa..6947619 100755 --- a/dashboard/dist.sh +++ b/dashboard/dist.sh @@ -1,11 +1,12 @@ #!/usr/bin/env bash set -euo pipefail -set -x + +VERSION=`cat Cargo.toml | grep "^version =" | sed -r 's/^version = "(.+)"$/\1/'` mkdir -p dist cp dashboard.desktop dist cp ../target/release/dashboard dist strip dist/dashboard -tar -czf dashboard.tgz dist/ +tar -czf dashboard-${VERSION}.tgz dist/ diff --git a/dashboard/src/app_window.rs b/dashboard/src/app_window.rs index 57456b4..482352a 100644 --- a/dashboard/src/app_window.rs +++ b/dashboard/src/app_window.rs @@ -40,16 +40,16 @@ impl ApplicationWindow { .vexpand(true) .build(); - let date_label = Date::new(); + let date_label = Date::default(); layout.append(&date_label); - let events = Events::new(); + let events = Events::default(); layout.append(&events); - let transit_card = TransitCard::new(); + let transit_card = TransitCard::default(); layout.append(&transit_card); - let transit_clock = TransitClock::new(); + let transit_clock = TransitClock::default(); layout.append(&transit_clock); window.set_content(Some(&layout)); diff --git a/dashboard/src/components/date.rs b/dashboard/src/components/date.rs index f8698e4..0dd84e1 100644 --- a/dashboard/src/components/date.rs +++ b/dashboard/src/components/date.rs @@ -35,8 +35,8 @@ glib::wrapper! { pub struct Date(ObjectSubclass) @extends gtk::Box, gtk::Widget; } -impl Date { - pub fn new() -> Self { +impl Default for Date { + fn default() -> Self { let s: Self = Object::builder().build(); s.set_margin_bottom(8); s.set_margin_top(8); @@ -48,7 +48,9 @@ impl Date { s.redraw(); s } +} +impl Date { pub fn update_date(&self, date: IFC) { *self.imp().date.borrow_mut() = date; self.redraw(); diff --git a/dashboard/src/components/events.rs b/dashboard/src/components/events.rs index f1d072c..88a411d 100644 --- a/dashboard/src/components/events.rs +++ b/dashboard/src/components/events.rs @@ -1,13 +1,12 @@ use crate::{ components::Date, solstices::{self, YearlyEvents}, - soluna_client::SunMoon, }; -use chrono::TimeZone; use glib::Object; -use gtk::{prelude::*, subclass::prelude::*, IconLookupFlags}; +use gtk::{prelude::*, subclass::prelude::*}; use ifc::IFC; +/* #[derive(PartialEq)] pub enum UpcomingEvent { SpringEquinox, @@ -15,25 +14,15 @@ pub enum UpcomingEvent { AutumnEquinox, WinterSolstice, } +*/ +#[derive(Default)] pub struct EventsPrivate { spring_equinox: Date, summer_solstice: Date, autumn_equinox: Date, winter_solstice: Date, - next: UpcomingEvent, -} - -impl Default for EventsPrivate { - fn default() -> Self { - Self { - spring_equinox: Date::new(), - summer_solstice: Date::new(), - autumn_equinox: Date::new(), - winter_solstice: Date::new(), - next: UpcomingEvent::SpringEquinox, - } - } + // next: UpcomingEvent, } #[glib::object_subclass] @@ -51,8 +40,8 @@ glib::wrapper! { pub struct Events(ObjectSubclass) @extends gtk::Widget, gtk::Box, @implements gtk::Orientable; } -impl Events { - pub fn new() -> Self { +impl Default for Events { + fn default() -> Self { let s: Self = Object::builder().build(); s.set_orientation(gtk::Orientation::Horizontal); s.set_spacing(8); @@ -64,7 +53,9 @@ impl Events { s } +} +impl Events { pub fn set_events(&self, events: YearlyEvents, next_event: solstices::Event) { self.imp() .spring_equinox diff --git a/dashboard/src/components/label.rs b/dashboard/src/components/label.rs index b793ccc..17686f6 100644 --- a/dashboard/src/components/label.rs +++ b/dashboard/src/components/label.rs @@ -1,6 +1,5 @@ -use crate::soluna_client::SunMoon; use glib::Object; -use gtk::{prelude::*, subclass::prelude::*, IconLookupFlags}; +use gtk::{prelude::*, subclass::prelude::*}; #[derive(Default)] pub struct LabelPrivate { diff --git a/dashboard/src/components/transit_card.rs b/dashboard/src/components/transit_card.rs index 27334e7..3c8eb13 100644 --- a/dashboard/src/components/transit_card.rs +++ b/dashboard/src/components/transit_card.rs @@ -1,6 +1,6 @@ use crate::{components::Label, soluna_client::SunMoon}; use glib::Object; -use gtk::{prelude::*, subclass::prelude::*, IconLookupFlags}; +use gtk::{prelude::*, subclass::prelude::*}; pub struct TransitCardPrivate { sunrise: Label, @@ -35,8 +35,8 @@ glib::wrapper! { pub struct TransitCard(ObjectSubclass) @extends gtk::Grid, gtk::Widget; } -impl TransitCard { - pub fn new() -> Self { +impl Default for TransitCard { + fn default() -> Self { let s: Self = Object::builder().build(); s.add_css_class("card"); s.set_column_homogeneous(true); @@ -48,7 +48,9 @@ impl TransitCard { s } +} +impl TransitCard { pub fn update_transit(&self, transit_info: &SunMoon) { self.imp() .sunrise diff --git a/dashboard/src/components/transit_clock.rs b/dashboard/src/components/transit_clock.rs index be2f0de..44bef09 100644 --- a/dashboard/src/components/transit_clock.rs +++ b/dashboard/src/components/transit_clock.rs @@ -7,18 +7,11 @@ use glib::Object; use gtk::{prelude::*, subclass::prelude::*}; use std::{cell::RefCell, f64::consts::PI, rc::Rc}; +#[derive(Default)] pub struct TransitClockPrivate { info: Rc>>, } -impl Default for TransitClockPrivate { - fn default() -> Self { - Self { - info: Rc::new(RefCell::new(None)), - } - } -} - #[glib::object_subclass] impl ObjectSubclass for TransitClockPrivate { const NAME: &'static str = "TransitClock"; @@ -34,8 +27,8 @@ glib::wrapper! { pub struct TransitClock(ObjectSubclass) @extends gtk::DrawingArea, gtk::Widget; } -impl TransitClock { - pub fn new() -> Self { +impl Default for TransitClock { + fn default() -> Self { let s: Self = Object::builder().build(); s.set_width_request(500); s.set_height_request(500); @@ -100,7 +93,9 @@ impl TransitClock { s } +} +impl TransitClock { pub fn update_transit(&self, transit_info: SunMoon) { *self.imp().info.borrow_mut() = Some(transit_info); self.queue_draw(); diff --git a/dashboard/src/main.rs b/dashboard/src/main.rs index 07f10d8..fc932ae 100644 --- a/dashboard/src/main.rs +++ b/dashboard/src/main.rs @@ -90,7 +90,7 @@ pub fn main() { tx: Arc::new(RwLock::new(None)), }; - let _ = runtime.spawn({ + runtime.spawn({ let core = core.clone(); async move { let soluna_client = SolunaClient::new(); diff --git a/dashboard/src/solstices.rs b/dashboard/src/solstices.rs index 4908292..040d4c6 100644 --- a/dashboard/src/solstices.rs +++ b/dashboard/src/solstices.rs @@ -1,11 +1,10 @@ -use chrono; use chrono::prelude::*; use lazy_static::lazy_static; use serde_derive::{Deserialize, Serialize}; use std::collections::HashMap; // http://astropixels.com/ephemeris/soleq2001.html -const SOLSTICE_TEXT: &'static str = " +const SOLSTICE_TEXT: &str = " 2001 Mar 20 13:31 Jun 21 07:38 Sep 22 23:05 Dec 21 19:22 2002 Mar 20 19:16 Jun 21 13:25 Sep 23 04:56 Dec 22 01:15 2003 Mar 21 01:00 Jun 21 19:11 Sep 23 10:47 Dec 22 07:04 @@ -91,12 +90,14 @@ impl Event { } fn parse_time<'a>( - jaro: &str, + year: &str, iter: impl Iterator, ) -> chrono::DateTime { - let partoj = iter.collect::>(); - let p = format!("{} {} {} {}", jaro, partoj[0], partoj[1], partoj[2]); - chrono::Utc.datetime_from_str(&p, "%Y %b %d %H:%M").unwrap() + let parts = iter.collect::>(); + let p = format!("{} {} {} {}", year, parts[0], parts[1], parts[2]); + NaiveDateTime::parse_from_str(&p, "%Y %b %d %H:%M") + .unwrap() + .and_utc() } fn parse_line(year: &str, rest: &[&str]) -> YearlyEvents { @@ -118,7 +119,7 @@ fn parse_events() -> Vec> { .lines() .map(|line| { match line - .split(" ") + .split(' ') .filter(|elem| !elem.is_empty()) .collect::>() .as_slice() @@ -134,7 +135,7 @@ pub struct Solstices(HashMap); impl Solstices { pub fn yearly_events(&self, year: i32) -> Option { - self.0.get(&year).map(|c| c.clone()) + self.0.get(&year).copied() } pub fn next_event(&self, date: chrono::DateTime) -> Option { @@ -142,17 +143,17 @@ impl Solstices { match year_events { Some(year_events) => { if date <= year_events.spring_equinox { - Some(Event::SpringEquinox(year_events.spring_equinox.clone())) + Some(Event::SpringEquinox(year_events.spring_equinox)) } else if date <= year_events.summer_solstice { - Some(Event::SummerSolstice(year_events.summer_solstice.clone())) + Some(Event::SummerSolstice(year_events.summer_solstice)) } else if date <= year_events.autumn_equinox { - Some(Event::AutumnEquinox(year_events.autumn_equinox.clone())) + Some(Event::AutumnEquinox(year_events.autumn_equinox)) } else if date <= year_events.winter_solstice { - Some(Event::WinterSolstice(year_events.winter_solstice.clone())) + Some(Event::WinterSolstice(year_events.winter_solstice)) } else { self.0 .get(&(date.year() + 1)) - .map(|_| Event::SpringEquinox(year_events.spring_equinox.clone())) + .map(|_| Event::SpringEquinox(year_events.spring_equinox)) } } None => None, @@ -165,7 +166,7 @@ impl From>> for Solstices { Solstices(event_list.iter().fold(HashMap::new(), |mut m, record| { match record { Some(record) => { - m.insert(record.year, record.clone()); + m.insert(record.year, *record); } None => (), } @@ -177,3 +178,24 @@ impl From>> for Solstices { lazy_static! { pub static ref EVENTS: Solstices = Solstices::from(parse_events()); } + +#[cfg(test)] +mod test { + use chrono::{NaiveDate, NaiveDateTime}; + + #[test] + fn it_can_parse_a_solstice_time() { + let p = "2001 Mar 20 13:31".to_owned(); + let parsed_date = NaiveDateTime::parse_from_str(&p, "%Y %b %d %H:%M") + .unwrap() + .and_utc(); + assert_eq!( + parsed_date, + NaiveDate::from_ymd_opt(2001, 03, 20) + .unwrap() + .and_hms_opt(13, 31, 0) + .unwrap() + .and_utc() + ); + } +} diff --git a/dashboard/src/soluna_client.rs b/dashboard/src/soluna_client.rs index c533104..d783311 100644 --- a/dashboard/src/soluna_client.rs +++ b/dashboard/src/soluna_client.rs @@ -4,7 +4,6 @@ use chrono::{DateTime, Duration, Local, NaiveTime, Offset, TimeZone, Timelike, Utc}; use geo_types::{Latitude, Longitude}; use memorycache::MemoryCache; -use reqwest; use serde::Deserialize; const ENDPOINT: &str = "https://api.solunar.org/solunar"; @@ -26,8 +25,8 @@ impl SunMoon { let sunrise = parse_time(val.sunrise).unwrap(); let sunset = parse_time(val.sunset).unwrap(); - let moonrise = val.moonrise.and_then(|v| parse_time(v)); - let moonset = val.moonset.and_then(|v| parse_time(v)); + let moonrise = val.moonrise.and_then(parse_time); + let moonset = val.moonset.and_then(parse_time); Self { sunrise, @@ -82,7 +81,7 @@ impl SolunaClient { pub fn new() -> Self { Self { client: reqwest::Client::new(), - memory_cache: MemoryCache::new(), + memory_cache: MemoryCache::default(), } } @@ -110,7 +109,7 @@ impl SolunaClient { .get(reqwest::header::EXPIRES) .and_then(|header| header.to_str().ok()) .and_then(|expiration| DateTime::parse_from_rfc2822(expiration).ok()) - .map(|dt_local| DateTime::::from(dt_local)) + .map(DateTime::::from) .unwrap_or( Local::now() .with_hour(0) diff --git a/emseries/src/criteria.rs b/emseries/src/criteria.rs index fab7945..9f304e6 100644 --- a/emseries/src/criteria.rs +++ b/emseries/src/criteria.rs @@ -10,7 +10,6 @@ Luminescent Dreams Tools is distributed in the hope that it will be useful, but You should have received a copy of the GNU General Public License along with Lumeto. If not, see . */ -use date_time_tz::DateTimeTz; use types::{Recordable, Timestamp}; /// This trait is used for constructing queries for searching the database. diff --git a/emseries/src/date_time_tz.rs b/emseries/src/date_time_tz.rs index 2ef3607..1022767 100644 --- a/emseries/src/date_time_tz.rs +++ b/emseries/src/date_time_tz.rs @@ -33,19 +33,13 @@ use std::{fmt, str::FromStr}; #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub struct DateTimeTz(pub chrono::DateTime); -impl DateTimeTz { - pub fn map(&self, f: F) -> DateTimeTz - where - F: FnOnce(chrono::DateTime) -> chrono::DateTime, - { - DateTimeTz(f(self.0)) - } - - pub fn to_string(&self) -> String { +impl fmt::Display for DateTimeTz { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { if self.0.timezone() == UTC { - self.0.to_rfc3339_opts(SecondsFormat::Secs, true) + write!(f, "{}", self.0.to_rfc3339_opts(SecondsFormat::Secs, true)) } else { - format!( + write!( + f, "{} {}", self.0 .with_timezone(&chrono_tz::Etc::UTC) @@ -56,11 +50,20 @@ impl DateTimeTz { } } +impl DateTimeTz { + pub fn map(&self, f: F) -> DateTimeTz + where + F: FnOnce(chrono::DateTime) -> chrono::DateTime, + { + DateTimeTz(f(self.0)) + } +} + impl std::str::FromStr for DateTimeTz { type Err = chrono::ParseError; fn from_str(s: &str) -> Result { - let v: Vec<&str> = s.split_terminator(" ").collect(); + let v: Vec<&str> = s.split_terminator(' ').collect(); if v.len() == 2 { let tz = v[1].parse::().unwrap(); chrono::DateTime::parse_from_rfc3339(v[0]).map(|ts| DateTimeTz(ts.with_timezone(&tz))) @@ -86,9 +89,9 @@ impl<'de> Visitor<'de> for DateTimeTzVisitor { } fn visit_str(self, s: &str) -> Result { - DateTimeTz::from_str(s).or(Err(E::custom(format!( - "string is not a parsable datetime representation" - )))) + DateTimeTz::from_str(s).or(Err(E::custom( + "string is not a parsable datetime representation".to_owned(), + ))) } } @@ -117,28 +120,43 @@ mod test { #[test] fn it_creates_timestamp_with_z() { - let t = DateTimeTz(UTC.ymd(2019, 5, 15).and_hms(12, 0, 0)); + let t = DateTimeTz(UTC.with_ymd_and_hms(2019, 5, 15, 12, 0, 0).unwrap()); assert_eq!(t.to_string(), "2019-05-15T12:00:00Z"); } #[test] fn it_parses_utc_rfc3339_z() { let t = DateTimeTz::from_str("2019-05-15T12:00:00Z").unwrap(); - assert_eq!(t, DateTimeTz(UTC.ymd(2019, 5, 15).and_hms(12, 0, 0))); + assert_eq!( + t, + DateTimeTz(UTC.with_ymd_and_hms(2019, 5, 15, 12, 0, 0).unwrap()) + ); } #[test] fn it_parses_rfc3339_with_offset() { let t = DateTimeTz::from_str("2019-05-15T12:00:00-06:00").unwrap(); - assert_eq!(t, DateTimeTz(UTC.ymd(2019, 5, 15).and_hms(18, 0, 0))); + assert_eq!( + t, + DateTimeTz(UTC.with_ymd_and_hms(2019, 5, 15, 18, 0, 0).unwrap()) + ); } #[test] fn it_parses_rfc3339_with_tz() { let t = DateTimeTz::from_str("2019-06-15T19:00:00Z US/Arizona").unwrap(); - assert_eq!(t, DateTimeTz(UTC.ymd(2019, 6, 15).and_hms(19, 0, 0))); - assert_eq!(t, DateTimeTz(Arizona.ymd(2019, 6, 15).and_hms(12, 0, 0))); - assert_eq!(t, DateTimeTz(Central.ymd(2019, 6, 15).and_hms(14, 0, 0))); + assert_eq!( + t, + DateTimeTz(UTC.with_ymd_and_hms(2019, 6, 15, 19, 0, 0).unwrap()) + ); + assert_eq!( + t, + DateTimeTz(Arizona.with_ymd_and_hms(2019, 6, 15, 12, 0, 0).unwrap()) + ); + assert_eq!( + t, + DateTimeTz(Central.with_ymd_and_hms(2019, 6, 15, 14, 0, 0).unwrap()) + ); assert_eq!(t.to_string(), "2019-06-15T19:00:00Z US/Arizona"); } @@ -172,6 +190,9 @@ mod test { fn it_json_parses() { let t = serde_json::from_str::("\"2019-06-15T19:00:00Z America/Phoenix\"").unwrap(); - assert_eq!(t, DateTimeTz(Phoenix.ymd(2019, 6, 15).and_hms(12, 0, 0))); + assert_eq!( + t, + DateTimeTz(Phoenix.with_ymd_and_hms(2019, 6, 15, 12, 0, 0).unwrap()) + ); } } diff --git a/emseries/src/series.rs b/emseries/src/series.rs index 8fad160..71e089f 100644 --- a/emseries/src/series.rs +++ b/emseries/src/series.rs @@ -47,7 +47,7 @@ where .read(true) .append(true) .create(true) - .open(&path) + .open(path) .map_err(EmseriesReadError::IOError)?; let records = Series::load_file(&f)?; @@ -88,8 +88,8 @@ where /// Put a new record into the database. A unique id will be assigned to the record and /// returned. pub fn put(&mut self, entry: T) -> Result { - let uuid = UniqueId::new(); - self.update(uuid.clone(), entry).and_then(|_| Ok(uuid)) + let uuid = UniqueId::default(); + self.update(uuid.clone(), entry).map(|_| uuid) } /// Update an existing record. The `UniqueId` of the record passed into this function must match @@ -138,7 +138,7 @@ where } /// Get all of the records in the database. - pub fn records<'s>(&'s self) -> impl Iterator + 's { + pub fn records(&self) -> impl Iterator { self.records.iter() } @@ -166,7 +166,7 @@ where /// Get an exact record from the database based on unique id. pub fn get(&self, uuid: &UniqueId) -> Option { - self.records.get(uuid).map(|v| v.clone()) + self.records.get(uuid).cloned() } /* diff --git a/emseries/src/types.rs b/emseries/src/types.rs index a2a1606..2b72c73 100644 --- a/emseries/src/types.rs +++ b/emseries/src/types.rs @@ -55,8 +55,8 @@ impl str::FromStr for Timestamp { type Err = chrono::ParseError; fn from_str(line: &str) -> Result { DateTimeTz::from_str(line) - .map(|dtz| Timestamp::DateTime(dtz)) - .or(NaiveDate::from_str(line).map(|d| Timestamp::Date(d))) + .map(Timestamp::DateTime) + .or(NaiveDate::from_str(line).map(Timestamp::Date)) } } @@ -70,8 +70,8 @@ impl Ord for Timestamp { fn cmp(&self, other: &Timestamp) -> Ordering { match (self, other) { (Timestamp::DateTime(dt1), Timestamp::DateTime(dt2)) => dt1.cmp(dt2), - (Timestamp::DateTime(dt1), Timestamp::Date(dt2)) => dt1.0.date().naive_utc().cmp(&dt2), - (Timestamp::Date(dt1), Timestamp::DateTime(dt2)) => dt1.cmp(&dt2.0.date().naive_utc()), + (Timestamp::DateTime(dt1), Timestamp::Date(dt2)) => dt1.0.date_naive().cmp(dt2), + (Timestamp::Date(dt1), Timestamp::DateTime(dt2)) => dt1.cmp(&dt2.0.date_naive()), (Timestamp::Date(dt1), Timestamp::Date(dt2)) => dt1.cmp(dt2), } } @@ -105,11 +105,9 @@ pub trait Recordable { #[derive(Clone, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)] pub struct UniqueId(Uuid); -impl UniqueId { - /// Create a new V4 UUID (this is the most common type in use these days). - pub fn new() -> UniqueId { - let id = Uuid::new_v4(); - UniqueId(id) +impl Default for UniqueId { + fn default() -> Self { + Self(Uuid::new_v4()) } } @@ -120,14 +118,14 @@ impl str::FromStr for UniqueId { fn from_str(val: &str) -> Result { Uuid::parse_str(val) .map(UniqueId) - .map_err(|err| EmseriesReadError::UUIDParseError(err)) + .map_err(EmseriesReadError::UUIDParseError) } } impl fmt::Display for UniqueId { /// Convert to a hyphenated string fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { - write!(f, "{}", self.0.to_hyphenated().to_string()) + write!(f, "{}", self.0.to_hyphenated()) } } @@ -146,7 +144,7 @@ where type Err = EmseriesReadError; fn from_str(line: &str) -> Result { - serde_json::from_str(&line).map_err(|err| EmseriesReadError::JSONParseError(err)) + serde_json::from_str(line).map_err(EmseriesReadError::JSONParseError) } } @@ -184,7 +182,9 @@ mod test { fn timestamp_parses_datetimetz_without_timezone() { assert_eq!( "2003-11-10T06:00:00Z".parse::().unwrap(), - Timestamp::DateTime(DateTimeTz(UTC.ymd(2003, 11, 10).and_hms(6, 0, 0))), + Timestamp::DateTime(DateTimeTz( + UTC.with_ymd_and_hms(2003, 11, 10, 6, 0, 0).unwrap() + )), ); } @@ -210,7 +210,9 @@ mod test { assert_eq!( rec.data, Some(WeightRecord { - date: Timestamp::DateTime(DateTimeTz(UTC.ymd(2003, 11, 10).and_hms(6, 0, 0))), + date: Timestamp::DateTime(DateTimeTz( + UTC.with_ymd_and_hms(2003, 11, 10, 6, 0, 0).unwrap() + )), weight: Weight(77.79109 * KG), }) ); @@ -219,7 +221,9 @@ mod test { #[test] fn serialization_output() { let rec = WeightRecord { - date: Timestamp::DateTime(DateTimeTz(UTC.ymd(2003, 11, 10).and_hms(6, 0, 0))), + date: Timestamp::DateTime(DateTimeTz( + UTC.with_ymd_and_hms(2003, 11, 10, 6, 0, 0).unwrap(), + )), weight: Weight(77.0 * KG), }; assert_eq!( @@ -228,7 +232,12 @@ mod test { ); let rec2 = WeightRecord { - date: Timestamp::DateTime(Central.ymd(2003, 11, 10).and_hms(0, 0, 0).into()), + date: Timestamp::DateTime( + Central + .with_ymd_and_hms(2003, 11, 10, 0, 0, 0) + .unwrap() + .into(), + ), weight: Weight(77.0 * KG), }; assert_eq!( @@ -239,22 +248,28 @@ mod test { #[test] fn two_datetimes_can_be_compared() { - let time1 = Timestamp::DateTime(DateTimeTz(UTC.ymd(2003, 11, 10).and_hms(6, 0, 0))); - let time2 = Timestamp::DateTime(DateTimeTz(UTC.ymd(2003, 11, 11).and_hms(6, 0, 0))); + let time1 = Timestamp::DateTime(DateTimeTz( + UTC.with_ymd_and_hms(2003, 11, 10, 6, 0, 0).unwrap(), + )); + let time2 = Timestamp::DateTime(DateTimeTz( + UTC.with_ymd_and_hms(2003, 11, 11, 6, 0, 0).unwrap(), + )); assert!(time1 < time2); } #[test] fn two_dates_can_be_compared() { - let time1 = Timestamp::Date(NaiveDate::from_ymd(2003, 11, 10)); - let time2 = Timestamp::Date(NaiveDate::from_ymd(2003, 11, 11)); + let time1 = Timestamp::Date(NaiveDate::from_ymd_opt(2003, 11, 10).unwrap()); + let time2 = Timestamp::Date(NaiveDate::from_ymd_opt(2003, 11, 11).unwrap()); assert!(time1 < time2); } #[test] fn datetime_and_date_can_be_compared() { - let time1 = Timestamp::DateTime(DateTimeTz(UTC.ymd(2003, 11, 10).and_hms(6, 0, 0))); - let time2 = Timestamp::Date(NaiveDate::from_ymd(2003, 11, 11)); + let time1 = Timestamp::DateTime(DateTimeTz( + UTC.with_ymd_and_hms(2003, 11, 10, 6, 0, 0).unwrap(), + )); + let time2 = Timestamp::Date(NaiveDate::from_ymd_opt(2003, 11, 11).unwrap()); assert!(time1 < time2) } } diff --git a/emseries/tests/test_io.rs b/emseries/tests/test_io.rs index 92b1a8b..c599369 100644 --- a/emseries/tests/test_io.rs +++ b/emseries/tests/test_io.rs @@ -22,7 +22,7 @@ extern crate emseries; mod test { use chrono::prelude::*; use chrono_tz::Etc::UTC; - use dimensioned::si::{Kilogram, Meter, Second, KG, M, S}; + use dimensioned::si::{Kilogram, Meter, Second, M, S}; use emseries::*; @@ -52,31 +52,31 @@ mod test { fn mk_trips() -> [BikeTrip; 5] { [ BikeTrip { - datetime: DateTimeTz(UTC.ymd(2011, 10, 29).and_hms(0, 0, 0)), + datetime: DateTimeTz(UTC.with_ymd_and_hms(2011, 10, 29, 0, 0, 0).unwrap()), distance: Distance(58741.055 * M), duration: Duration(11040.0 * S), comments: String::from("long time ago"), }, BikeTrip { - datetime: DateTimeTz(UTC.ymd(2011, 10, 31).and_hms(0, 0, 0)), + datetime: DateTimeTz(UTC.with_ymd_and_hms(2011, 10, 31, 0, 0, 0).unwrap()), distance: Distance(17702.0 * M), duration: Duration(2880.0 * S), comments: String::from("day 2"), }, BikeTrip { - datetime: DateTimeTz(UTC.ymd(2011, 11, 02).and_hms(0, 0, 0)), + datetime: DateTimeTz(UTC.with_ymd_and_hms(2011, 11, 02, 0, 0, 0).unwrap()), distance: Distance(41842.945 * M), duration: Duration(7020.0 * S), comments: String::from("Do Some Distance!"), }, BikeTrip { - datetime: DateTimeTz(UTC.ymd(2011, 11, 04).and_hms(0, 0, 0)), + datetime: DateTimeTz(UTC.with_ymd_and_hms(2011, 11, 04, 0, 0, 0).unwrap()), distance: Distance(34600.895 * M), duration: Duration(5580.0 * S), comments: String::from("I did a lot of distance back then"), }, BikeTrip { - datetime: DateTimeTz(UTC.ymd(2011, 11, 05).and_hms(0, 0, 0)), + datetime: DateTimeTz(UTC.with_ymd_and_hms(2011, 11, 05, 0, 0, 0).unwrap()), distance: Distance(6437.376 * M), duration: Duration(960.0 * S), comments: String::from("day 5"), @@ -122,7 +122,7 @@ mod test { Some(tr) => { assert_eq!( tr.timestamp(), - DateTimeTz(UTC.ymd(2011, 10, 29).and_hms(0, 0, 0)).into() + DateTimeTz(UTC.with_ymd_and_hms(2011, 10, 29, 0, 0, 0).unwrap()).into() ); assert_eq!(tr.duration, Duration(11040.0 * S)); assert_eq!(tr.comments, String::from("long time ago")); @@ -145,7 +145,7 @@ mod test { let v: Vec<(&UniqueId, &BikeTrip)> = ts .search(exact_time( - DateTimeTz(UTC.ymd(2011, 10, 31).and_hms(0, 0, 0)).into(), + DateTimeTz(UTC.with_ymd_and_hms(2011, 10, 31, 0, 0, 0).unwrap()).into(), )) .collect(); assert_eq!(v.len(), 1); @@ -166,9 +166,9 @@ mod test { let v: Vec<(&UniqueId, &BikeTrip)> = ts.search_sorted( time_range( - DateTimeTz(UTC.ymd(2011, 10, 31).and_hms(0, 0, 0)).into(), + DateTimeTz(UTC.with_ymd_and_hms(2011, 10, 31, 0, 0, 0).unwrap()).into(), true, - DateTimeTz(UTC.ymd(2011, 11, 04).and_hms(0, 0, 0)).into(), + DateTimeTz(UTC.with_ymd_and_hms(2011, 11, 04, 0, 0, 0).unwrap()).into(), true, ), |l, r| l.1.timestamp().cmp(&r.1.timestamp()), @@ -199,9 +199,9 @@ mod test { .expect("expect the time series to open correctly"); let v: Vec<(&UniqueId, &BikeTrip)> = ts.search_sorted( time_range( - DateTimeTz(UTC.ymd(2011, 10, 31).and_hms(0, 0, 0)).into(), + DateTimeTz(UTC.with_ymd_and_hms(2011, 10, 31, 0, 0, 0).unwrap()).into(), true, - DateTimeTz(UTC.ymd(2011, 11, 04).and_hms(0, 0, 0)).into(), + DateTimeTz(UTC.with_ymd_and_hms(2011, 11, 04, 0, 0, 0).unwrap()).into(), true, ), |l, r| l.1.timestamp().cmp(&r.1.timestamp()), @@ -233,9 +233,9 @@ mod test { .expect("expect the time series to open correctly"); let v: Vec<(&UniqueId, &BikeTrip)> = ts.search_sorted( time_range( - DateTimeTz(UTC.ymd(2011, 10, 31).and_hms(0, 0, 0)).into(), + DateTimeTz(UTC.with_ymd_and_hms(2011, 10, 31, 0, 0, 0).unwrap()).into(), true, - DateTimeTz(UTC.ymd(2011, 11, 04).and_hms(0, 0, 0)).into(), + DateTimeTz(UTC.with_ymd_and_hms(2011, 11, 04, 0, 0, 0).unwrap()).into(), true, ), |l, r| l.1.timestamp().cmp(&r.1.timestamp()), @@ -252,9 +252,9 @@ mod test { .expect("expect the time series to open correctly"); let v: Vec<(&UniqueId, &BikeTrip)> = ts.search_sorted( time_range( - DateTimeTz(UTC.ymd(2011, 10, 31).and_hms(0, 0, 0)).into(), + DateTimeTz(UTC.with_ymd_and_hms(2011, 10, 31, 0, 0, 0).unwrap()).into(), true, - DateTimeTz(UTC.ymd(2011, 11, 05).and_hms(0, 0, 0)).into(), + DateTimeTz(UTC.with_ymd_and_hms(2011, 11, 05, 0, 0, 0).unwrap()).into(), true, ), |l, r| l.1.timestamp().cmp(&r.1.timestamp()), @@ -294,7 +294,7 @@ mod test { Some(trip) => { assert_eq!( trip.datetime, - DateTimeTz(UTC.ymd(2011, 11, 02).and_hms(0, 0, 0)) + DateTimeTz(UTC.with_ymd_and_hms(2011, 11, 02, 0, 0, 0).unwrap()) ); assert_eq!(trip.distance, Distance(50000.0 * M)); assert_eq!(trip.duration, Duration(7020.0 * S)); @@ -335,13 +335,13 @@ mod test { let trips: Vec<(&UniqueId, &BikeTrip)> = ts .search(exact_time( - DateTimeTz(UTC.ymd(2011, 11, 02).and_hms(0, 0, 0)).into(), + DateTimeTz(UTC.with_ymd_and_hms(2011, 11, 02, 0, 0, 0).unwrap()).into(), )) .collect(); assert_eq!(trips.len(), 1); assert_eq!( trips[0].1.datetime, - DateTimeTz(UTC.ymd(2011, 11, 02).and_hms(0, 0, 0)) + DateTimeTz(UTC.with_ymd_and_hms(2011, 11, 02, 0, 0, 0).unwrap()) ); assert_eq!(trips[0].1.distance, Distance(50000.0 * M)); assert_eq!(trips[0].1.duration, Duration(7020.0 * S)); @@ -361,7 +361,6 @@ mod test { let trip_id = ts.put(trips[0].clone()).expect("expect a successful put"); ts.put(trips[1].clone()).expect("expect a successful put"); ts.put(trips[2].clone()).expect("expect a successful put"); - ts.delete(&trip_id).expect("successful delete"); let recs: Vec<(&UniqueId, &BikeTrip)> = ts.records().collect(); diff --git a/file-service/src/bin/cli.rs b/file-service/src/bin/cli.rs index 5c1d3b5..4978dcc 100644 --- a/file-service/src/bin/cli.rs +++ b/file-service/src/bin/cli.rs @@ -26,11 +26,7 @@ pub async fn main() { Commands::AddUser { username } => { match authdb.add_user(Username::from(username.clone())).await { Ok(token) => { - println!( - "User {} created. Auth token: {}", - username, - token.to_string() - ); + println!("User {} created. Auth token: {}", username, *token); } Err(err) => { println!("Could not create user {}", username); @@ -38,7 +34,7 @@ pub async fn main() { } } } - Commands::DeleteUser { username } => {} + Commands::DeleteUser { .. } => {} Commands::ListUsers => {} } } diff --git a/file-service/src/handlers.rs b/file-service/src/handlers.rs index 2e75bf1..699451a 100644 --- a/file-service/src/handlers.rs +++ b/file-service/src/handlers.rs @@ -1,6 +1,5 @@ use build_html::Html; use bytes::Buf; -use cookie::time::error::Format; use file_service::WriteFileError; use futures_util::StreamExt; use http::{Error, StatusCode}; @@ -80,25 +79,22 @@ pub async fn handle_auth( form: HashMap, ) -> Result, Error> { match form.get("token") { - Some(token) => match app - .authenticate(AuthToken::from(AuthToken::from(token.clone()))) - .await - { + Some(token) => match app.authenticate(AuthToken::from(token.clone())).await { Ok(Some(session_token)) => Response::builder() .header("location", "/") .header( "set-cookie", format!( "session={}; Secure; HttpOnly; SameSite=Strict", - session_token.to_string() + *session_token ), ) .status(StatusCode::SEE_OTHER) .body("".to_owned()), - Ok(None) => render_auth_page(Some(format!("no user found"))), - Err(_) => render_auth_page(Some(format!("invalid auth token"))), + Ok(None) => render_auth_page(Some("no user found".to_owned())), + Err(_) => render_auth_page(Some("invalid auth token".to_owned())), }, - None => render_auth_page(Some(format!("no token available"))), + None => render_auth_page(Some("no token available".to_owned())), } } diff --git a/file-service/src/html.rs b/file-service/src/html.rs index 4539696..1d2199a 100644 --- a/file-service/src/html.rs +++ b/file-service/src/html.rs @@ -38,7 +38,7 @@ impl Html for Form { fn to_html_string(&self) -> String { let encoding = match self.encoding { Some(ref encoding) => format!("enctype=\"{encoding}\"", encoding = encoding), - None => format!(""), + None => "".to_owned(), }; format!( "
\n{elements}\n
\n", @@ -108,10 +108,12 @@ impl Input { self } + /* pub fn with_content(mut self, val: &str) -> Self { self.content = Some(val.to_owned()); self } + */ } #[derive(Clone, Debug)] diff --git a/file-service/src/main.rs b/file-service/src/main.rs index ffa4ad7..c70f7ff 100644 --- a/file-service/src/main.rs +++ b/file-service/src/main.rs @@ -1,4 +1,3 @@ -#[macro_use] extern crate log; use cookie::Cookie; @@ -78,10 +77,7 @@ fn parse_cookies(cookie_str: &str) -> Result, cookie::Pa } fn get_session_token(cookies: HashMap) -> Option { - cookies - .get("session") - .cloned() - .and_then(|session| Some(SessionToken::from(session))) + cookies.get("session").cloned().map(SessionToken::from) } fn maybe_with_session() -> impl Filter,), Error = Rejection> + Copy diff --git a/file-service/src/store/filehandle.rs b/file-service/src/store/filehandle.rs index 101254d..e03974f 100644 --- a/file-service/src/store/filehandle.rs +++ b/file-service/src/store/filehandle.rs @@ -97,7 +97,7 @@ impl TryFrom<&Path> for PathResolver { .ok_or(PathError::InvalidPath)?, id: path .file_stem() - .and_then(|s| s.to_str().map(|s| FileId::from(s))) + .and_then(|s| s.to_str().map(FileId::from)) .ok_or(PathError::InvalidPath)?, extension: path .extension() @@ -146,7 +146,7 @@ impl FileHandle { }; let mut md_file = std::fs::File::create(path.metadata_path())?; - md_file.write(&serde_json::to_vec(&info)?)?; + let _ = md_file.write(&serde_json::to_vec(&info)?)?; Ok(Self { id, path, info }) } @@ -168,7 +168,7 @@ impl FileHandle { self.info.hash = self.hash_content(&content).as_string(); let mut md_file = std::fs::File::create(self.path.metadata_path())?; - md_file.write(&serde_json::to_vec(&self.info)?)?; + let _ = md_file.write(&serde_json::to_vec(&self.info)?)?; self.write_thumbnail()?; @@ -188,9 +188,9 @@ impl FileHandle { } fn write_thumbnail(&self) -> Result<(), WriteFileError> { - let img = image::open(&self.path.file_path())?; + let img = image::open(self.path.file_path())?; let tn = img.resize(640, 640, FilterType::Nearest); - tn.save(&self.path.thumbnail_path())?; + tn.save(self.path.thumbnail_path())?; Ok(()) } @@ -203,7 +203,7 @@ impl FileHandle { fn load_content(path: &Path) -> Result, ReadFileError> { let mut buf = Vec::new(); - let mut file = std::fs::File::open(&path)?; + let mut file = std::fs::File::open(path)?; file.read_to_end(&mut buf)?; Ok(buf) } diff --git a/file-service/src/store/fileinfo.rs b/file-service/src/store/fileinfo.rs index 69da79f..0574550 100644 --- a/file-service/src/store/fileinfo.rs +++ b/file-service/src/store/fileinfo.rs @@ -3,7 +3,6 @@ use crate::FileId; use super::{ReadFileError, WriteFileError}; use chrono::prelude::*; use serde::{Deserialize, Serialize}; -use serde_json; use std::{ io::{Read, Write}, path::PathBuf, @@ -33,7 +32,7 @@ impl FileInfo { pub fn save(&self, path: PathBuf) -> Result<(), WriteFileError> { let ser = serde_json::to_string(self).unwrap(); let mut file = std::fs::File::create(path)?; - file.write(ser.as_bytes())?; + let _ = file.write(ser.as_bytes())?; Ok(()) } } diff --git a/file-service/src/store/mod.rs b/file-service/src/store/mod.rs index 119f02a..5f07644 100644 --- a/file-service/src/store/mod.rs +++ b/file-service/src/store/mod.rs @@ -3,12 +3,10 @@ use serde::{Deserialize, Serialize}; use sha2::{Digest, Sha256}; use sqlx::{ sqlite::{SqlitePool, SqliteRow}, - Executor, Row, + Row, }; -use std::collections::HashSet; -use std::{ops::Deref, path::PathBuf, sync::Arc}; +use std::{collections::HashSet, ops::Deref, path::PathBuf}; use thiserror::Error; -use tokio::sync::RwLock; use uuid::Uuid; mod filehandle; @@ -288,7 +286,7 @@ impl AuthDB { return Err(AuthError::DuplicateAuthToken); } - if results.len() == 0 { + if results.is_empty() { return Ok(None); } @@ -322,7 +320,7 @@ impl AuthDB { return Err(AuthError::DuplicateSessionToken); } - if rows.len() == 0 { + if rows.is_empty() { return Ok(None); } @@ -348,7 +346,7 @@ impl Store { let path_ = path.unwrap().path(); if path_.extension().and_then(|s| s.to_str()) == Some("json") { let stem = path_.file_stem().and_then(|s| s.to_str()).unwrap(); - Some(FileId::from(FileId::from(stem))) + Some(FileId::from(stem)) } else { None } diff --git a/flow/Cargo.toml b/flow/Cargo.toml index 27769c2..6f4a4f4 100644 --- a/flow/Cargo.toml +++ b/flow/Cargo.toml @@ -3,7 +3,6 @@ name = "flow" version = "0.1.0" edition = "2021" license = "GPL-3.0-only" -license-file = "../COPYING" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/fluent-ergonomics/Cargo.toml b/fluent-ergonomics/Cargo.toml index edddd75..f23728b 100644 --- a/fluent-ergonomics/Cargo.toml +++ b/fluent-ergonomics/Cargo.toml @@ -5,7 +5,6 @@ edition = "2018" version = "0.2.0" description = "An ergonomics wrapper around Fluent-RS" license = "GPL-3.0-only" -license-file = "../COPYING" homepage = "https://github.com/luminescent-dreams/fluent-ergonomics" repository = "https://github.com/luminescent-dreams/fluent-ergonomics" categories = ["internationalization"] diff --git a/fluent-ergonomics/src/lib.rs b/fluent-ergonomics/src/lib.rs index d6e6bcf..06feb80 100644 --- a/fluent-ergonomics/src/lib.rs +++ b/fluent-ergonomics/src/lib.rs @@ -171,14 +171,14 @@ impl FluentErgo { match entry { Entry::Occupied(mut e) => { let bundle = e.get_mut(); - bundle.add_resource(res).map_err(|err| Error::from(err)) + bundle.add_resource(res).map_err(Error::from) } Entry::Vacant(e) => { let mut bundle: FluentBundle< FluentResource, intl_memoizer::concurrent::IntlLangMemoizer, > = FluentBundle::new_concurrent(vec![lang]); - bundle.add_resource(res).map_err(|err| Error::from(err))?; + bundle.add_resource(res).map_err(Error::from)?; e.insert(bundle); Ok(()) } @@ -248,16 +248,10 @@ impl FluentErgo { /// pub fn tr(&self, msgid: &str, args: Option<&FluentArgs>) -> Result { let bundles = self.bundles.read().unwrap(); - let result: Option = self - .languages - .iter() - .map(|lang| { - let bundle = bundles.get(lang)?; - self.tr_(bundle, msgid, args) - }) - .filter(|v| v.is_some()) - .map(|v| v.unwrap()) - .next(); + let result: Option = self.languages.iter().find_map(|lang| { + let bundle = bundles.get(lang)?; + self.tr_(bundle, msgid, args) + }); match result { Some(r) => Ok(r), @@ -276,8 +270,8 @@ impl FluentErgo { let res = match pattern { None => None, Some(p) => { - let res = bundle.format_pattern(&p, args, &mut errors); - if errors.len() > 0 { + let res = bundle.format_pattern(p, args, &mut errors); + if !errors.is_empty() { println!("Errors in formatting: {:?}", errors) } diff --git a/geo-types/src/lib.rs b/geo-types/src/lib.rs index 6b8aebf..1bf0c05 100644 --- a/geo-types/src/lib.rs +++ b/geo-types/src/lib.rs @@ -5,7 +5,7 @@ pub struct Latitude(f32); impl From for Latitude { fn from(val: f32) -> Self { - if val > 90.0 || val < -90.0 { + if !(-90.0..=90.0).contains(&val) { panic!("Latitude is outside of range"); } Self(val) @@ -23,7 +23,7 @@ pub struct Longitude(f32); impl From for Longitude { fn from(val: f32) -> Self { - if val > 180.0 || val < -180.0 { + if !(-180.0..=180.0).contains(&val) { panic!("Longitude is outside fo range"); } Self(val) diff --git a/gm-control-panel/src/app_window.rs b/gm-control-panel/src/app_window.rs index 26574f2..360c289 100644 --- a/gm-control-panel/src/app_window.rs +++ b/gm-control-panel/src/app_window.rs @@ -45,7 +45,7 @@ impl ApplicationWindow { ] .into_iter() .map(|name| { - let playlist = PlaylistCard::new(); + let playlist = PlaylistCard::default(); playlist.set_name(name); playlist }) diff --git a/gm-control-panel/src/playlist_card.rs b/gm-control-panel/src/playlist_card.rs index d1d0007..d099582 100644 --- a/gm-control-panel/src/playlist_card.rs +++ b/gm-control-panel/src/playlist_card.rs @@ -31,8 +31,8 @@ glib::wrapper! { pub struct PlaylistCard(ObjectSubclass) @extends gtk::Box, gtk::Widget, @implements gtk::Orientable; } -impl PlaylistCard { - pub fn new() -> Self { +impl Default for PlaylistCard { + fn default() -> Self { let s: Self = Object::builder().build(); s.set_orientation(gtk::Orientation::Vertical); s.add_css_class("playlist-card"); @@ -43,7 +43,9 @@ impl PlaylistCard { s } +} +impl PlaylistCard { pub fn set_name(&self, s: &str) { self.imp().name.set_text(s); } diff --git a/hex-grid/src/bin/icon.rs b/hex-grid/src/bin/icon.rs index 4ff3f93..db2c614 100644 --- a/hex-grid/src/bin/icon.rs +++ b/hex-grid/src/bin/icon.rs @@ -1,7 +1,5 @@ -use gtk::prelude::*; - fn main() { - gtk::init(); + let _ = gtk::init(); for name in gtk::IconTheme::new().icon_names() { println!("{}", name); } diff --git a/hex-grid/src/main.rs b/hex-grid/src/main.rs index 8b9eb03..509c23c 100644 --- a/hex-grid/src/main.rs +++ b/hex-grid/src/main.rs @@ -10,10 +10,9 @@ Luminescent Dreams Tools is distributed in the hope that it will be useful, but You should have received a copy of the GNU General Public License along with Lumeto. If not, see . */ -use cairo::Context; use coordinates::{hex_map::parse_data, AxialAddr}; use gio::resources_lookup_data; -use glib::{subclass::InitializingObject, Object}; +use glib::Object; use gtk::{gio, prelude::*, subclass::prelude::*, Application, DrawingArea}; use image::io::Reader as ImageReader; use std::{cell::RefCell, io::Cursor, rc::Rc}; @@ -23,7 +22,7 @@ mod palette_entry; mod tile; mod utilities; -const APP_ID: &'static str = "com.luminescent-dreams.hex-grid"; +const APP_ID: &str = "com.luminescent-dreams.hex-grid"; const HEX_RADIUS: f64 = 50.; const MAP_RADIUS: usize = 3; const DRAWING_ORIGIN: (f64, f64) = (1024. / 2., 768. / 2.); @@ -178,14 +177,14 @@ impl ObjectImpl for HexGridWindowPrivate { let norm_x = x - DRAWING_ORIGIN.0; let norm_y = y - DRAWING_ORIGIN.1; let q = (2. / 3. * norm_x) / HEX_RADIUS; - let r = (-1. / 3. * norm_x + (3. as f64).sqrt() / 3. * norm_y) / HEX_RADIUS; + let r = (-1. / 3. * norm_x + (3_f64).sqrt() / 3. * norm_y) / HEX_RADIUS; let (q, r) = axial_round(q, r); let coordinate = AxialAddr::new(q, r); canvas_address.set_value(&format!("{:.0} {:.0}", x, y)); if coordinate.distance(&AxialAddr::origin()) > MAP_RADIUS { - hex_address.set_value(&format!("-----")); + hex_address.set_value("-----"); *c.borrow_mut() = None; } else { hex_address.set_value(&format!("{:.0} {:.0}", coordinate.q(), coordinate.r())); @@ -209,10 +208,10 @@ impl ObjectImpl for HexGridWindowPrivate { DRAWING_ORIGIN.0 + HEX_RADIUS * (3. / 2. * (coordinate.q() as f64)); let center_y = DRAWING_ORIGIN.1 + HEX_RADIUS - * ((3. as f64).sqrt() / 2. * (coordinate.q() as f64) - + (3. as f64).sqrt() * (coordinate.r() as f64)); + * ((3_f64).sqrt() / 2. * (coordinate.q() as f64) + + (3_f64).sqrt() * (coordinate.r() as f64)); let translate_x = center_x - HEX_RADIUS; - let translate_y = center_y - (3. as f64).sqrt() * HEX_RADIUS / 2.; + let translate_y = center_y - (3_f64).sqrt() * HEX_RADIUS / 2.; let tile = match hex_map.get(&coordinate).unwrap() { tile::Terrain::Mountain => &mountain, @@ -249,10 +248,11 @@ impl HexGridWindow { } } +/* fn draw_hexagon(context: &Context, center_x: f64, center_y: f64, radius: f64) { let ul_x = center_x - radius; - let ul_y = center_y - (3. as f64).sqrt() * radius / 2.; - let points: Vec<(f64, f64)> = utilities::hexagon(radius * 2., (3. as f64).sqrt() * radius); + let ul_y = center_y - (3_f64).sqrt() * radius / 2.; + let points: Vec<(f64, f64)> = utilities::hexagon(radius * 2., (3_f64).sqrt() * radius); context.new_path(); context.move_to(ul_x + points[0].0, ul_y + points[0].1); context.line_to(ul_x + points[1].0, ul_y + points[1].1); @@ -262,6 +262,7 @@ fn draw_hexagon(context: &Context, center_x: f64, center_y: f64, radius: f64) { context.line_to(ul_x + points[5].0, ul_y + points[5].1); context.close_path(); } +*/ fn axial_round(q_f64: f64, r_f64: f64) -> (i32, i32) { let s_f64 = -q_f64 - r_f64; diff --git a/hex-grid/src/utilities.rs b/hex-grid/src/utilities.rs index 613dce6..5c83f24 100644 --- a/hex-grid/src/utilities.rs +++ b/hex-grid/src/utilities.rs @@ -27,20 +27,20 @@ pub fn hexagon(width: f64, height: f64) -> Vec<(f64, f64)> { (center_x + radius, center_y), ( center_x + radius / 2., - center_y + (3. as f64).sqrt() * radius / 2., + center_y + (3_f64).sqrt() * radius / 2., ), ( center_x - radius / 2., - center_y + (3. as f64).sqrt() * radius / 2., + center_y + (3_f64).sqrt() * radius / 2., ), (center_x - radius, center_y), ( center_x - radius / 2., - center_y - (3. as f64).sqrt() * radius / 2., + center_y - (3_f64).sqrt() * radius / 2., ), ( center_x + radius / 2., - center_y - (3. as f64).sqrt() * radius / 2., + center_y - (3_f64).sqrt() * radius / 2., ), ] } diff --git a/ifc/Cargo.toml b/ifc/Cargo.toml index 0da100b..30cd94d 100644 --- a/ifc/Cargo.toml +++ b/ifc/Cargo.toml @@ -7,7 +7,6 @@ edition = "2018" keywords = ["date", "time", "calendar"] categories = ["date-and-time"] license = "GPL-3.0-only" -license-file = "../COPYING" [dependencies] chrono = { version = "0.4" } diff --git a/ifc/src/lib.rs b/ifc/src/lib.rs index 5ede0c0..83b5719 100644 --- a/ifc/src/lib.rs +++ b/ifc/src/lib.rs @@ -141,9 +141,7 @@ impl IFC { } pub fn ymd(year: i32, month: u8, day: u8) -> Result { - if month < 1 || month > 13 { - Err(Error::InvalidDate) - } else if day < 1 || day > 28 { + if !(1..=13).contains(&month) || !(1..=28).contains(&day) { Err(Error::InvalidDate) } else { Ok(Self::Day(Day { year, month, day })) @@ -248,12 +246,12 @@ impl From for IFC { if is_leap_year(date.year()) && date > NaiveDate::from_ymd_opt(date.year(), 6, 17).unwrap() { - days = days - 1; + days -= 1; } let mut month: u8 = (days / 28).try_into().unwrap(); let mut day: u8 = (days % 28).try_into().unwrap(); if day == 0 { - month = month - 1; + month -= 1; day = 28; } Self::Day(Day { diff --git a/kifu/core/src/api.rs b/kifu/core/src/api.rs index 76d5264..8ec9d86 100644 --- a/kifu/core/src/api.rs +++ b/kifu/core/src/api.rs @@ -120,7 +120,7 @@ impl CoreApp { app_state.game = Some(GameState { white_player, black_player, - ..GameState::new() + ..GameState::default() }); let game_state = app_state.game.as_ref().unwrap(); CoreResponse::PlayingFieldView(playing_field(game_state)) diff --git a/kifu/core/src/board.rs b/kifu/core/src/board.rs index 8a7b790..d94d5c9 100644 --- a/kifu/core/src/board.rs +++ b/kifu/core/src/board.rs @@ -1,7 +1,7 @@ use crate::{BoardError, Color, Size}; use std::collections::HashSet; -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub struct Board { pub size: Size, pub groups: Vec, @@ -14,7 +14,7 @@ impl std::fmt::Display for Board { for c in 0..19 { write!(f, "{:2}", c)?; } - writeln!(f, "")?; + writeln!(f)?; for row in 0..self.size.height { write!(f, " {:2}", row)?; @@ -25,7 +25,7 @@ impl std::fmt::Display for Board { Some(Color::White) => write!(f, " O")?, } } - writeln!(f, "")?; + writeln!(f)?; } Ok(()) } @@ -38,16 +38,16 @@ impl PartialEq for Board { } for group in self.groups.iter() { - if !other.groups.contains(&group) { + if !other.groups.contains(group) { return false; } } for group in other.groups.iter() { - if !self.groups.contains(&group) { + if !self.groups.contains(group) { return false; } } - return true; + true } } @@ -79,7 +79,7 @@ pub struct Coordinate { impl Board { pub fn place_stone(mut self, coordinate: Coordinate, color: Color) -> Result { - if let Some(_) = self.stone(&coordinate) { + if self.stone(&coordinate).is_some() { return Err(BoardError::InvalidPosition); } @@ -92,7 +92,7 @@ impl Board { acc.union(&set).cloned().collect() }); - friendly_group.insert(coordinate.clone()); + friendly_group.insert(coordinate); self.groups .retain(|g| g.coordinates.is_disjoint(&friendly_group)); @@ -138,7 +138,7 @@ impl Board { let mut grps: Vec = Vec::new(); adjacent_spaces.for_each(|coord| match self.group(&coord) { - None => return, + None => {} Some(adj) => { if group.color == adj.color { return; @@ -157,15 +157,14 @@ impl Board { group .coordinates .iter() - .map(|c| self.adjacencies(c)) - .flatten() + .flat_map(|c| self.adjacencies(c)) .collect::>() } pub fn liberties(&self, group: &Group) -> usize { self.group_halo(group) .into_iter() - .filter(|c| self.stone(&c) == None) + .filter(|c| self.stone(c).is_none()) .count() } diff --git a/kifu/core/src/database.rs b/kifu/core/src/database.rs index c7e9cc2..b98b885 100644 --- a/kifu/core/src/database.rs +++ b/kifu/core/src/database.rs @@ -1,12 +1,14 @@ -use std::{ffi::OsStr, io::Read, os::unix::ffi::OsStrExt, path::PathBuf}; +use std::{io::Read, path::PathBuf}; use sgf::{go, parse_sgf, Game}; use thiserror::Error; #[derive(Error, Debug)] pub enum Error { + /* #[error("Database permission denied")] PermissionDenied, + */ #[error("An IO error occurred: {0}")] IOError(std::io::Error), } @@ -19,7 +21,6 @@ impl From for Error { #[derive(Debug)] pub struct Database { - path: PathBuf, games: Vec, } @@ -56,11 +57,7 @@ impl Database { } } - Ok(Database { path, games }) - } - - pub fn len(&self) -> usize { - self.games.len() + Ok(Database { games }) } pub fn all_games(&self) -> impl Iterator { @@ -86,14 +83,13 @@ mod test { let db = Database::open_path(PathBuf::from("fixtures/five_games/")).expect("database to open"); assert_eq!(db.all_games().count(), 5); - for game in db.all_games() {} assert_matches!(db.all_games().find(|g| g.info.black_player == Some("Steve".to_owned())), Some(game) => { assert_eq!(game.info.black_player, Some("Steve".to_owned())); assert_eq!(game.info.white_player, Some("Savanni".to_owned())); assert_eq!(game.info.date, vec![Date::Date(chrono::NaiveDate::from_ymd_opt(2023, 4, 19).unwrap())]); - assert_eq!(game.info.komi, Some(6.5)); + // assert_eq!(game.info.komi, Some(6.5)); } ); } diff --git a/kifu/core/src/lib.rs b/kifu/core/src/lib.rs index ceda4df..3ad93c0 100644 --- a/kifu/core/src/lib.rs +++ b/kifu/core/src/lib.rs @@ -1,4 +1,3 @@ -#[macro_use] extern crate config_derive; mod api; @@ -10,11 +9,6 @@ pub use api::{ mod board; pub use board::*; -/* -mod config; -pub use config::*; -*/ - mod database; mod types; diff --git a/kifu/core/src/types.rs b/kifu/core/src/types.rs index 5754c42..86c00d9 100644 --- a/kifu/core/src/types.rs +++ b/kifu/core/src/types.rs @@ -77,20 +77,17 @@ pub struct AppState { impl AppState { pub fn new(database_path: DatabasePath) -> Self { Self { - game: Some(GameState::new()), + game: Some(GameState::default()), database: Database::open_path(database_path.to_path_buf()).unwrap(), } } pub fn place_stone(&mut self, req: PlayStoneRequest) { - match self.game { - Some(ref mut game) => { - let _ = game.place_stone(Coordinate { - column: req.column, - row: req.row, - }); - } - None => {} + if let Some(ref mut game) = self.game { + let _ = game.place_stone(Coordinate { + column: req.column, + row: req.row, + }); } } } @@ -142,9 +139,9 @@ pub struct GameState { pub black_clock: Duration, } -impl GameState { - pub fn new() -> GameState { - GameState { +impl Default for GameState { + fn default() -> Self { + Self { board: Board::new(), past_positions: vec![], conversation: vec![], @@ -161,7 +158,9 @@ impl GameState { black_clock: Duration::from_secs(600), } } +} +impl GameState { fn place_stone(&mut self, coordinate: Coordinate) -> Result<(), BoardError> { let board = self.board.clone(); let new_board = board.place_stone(coordinate, self.current_player)?; @@ -186,7 +185,7 @@ mod test { #[test] fn current_player_changes_after_move() { - let mut state = GameState::new(); + let mut state = GameState::default(); assert_eq!(state.current_player, Color::Black); state.place_stone(Coordinate { column: 9, row: 9 }).unwrap(); assert_eq!(state.current_player, Color::White); @@ -194,7 +193,7 @@ mod test { #[test] fn current_player_remains_the_same_after_self_capture() { - let mut state = GameState::new(); + let mut state = GameState::default(); state.board = Board::from_coordinates( vec![ (Coordinate { column: 17, row: 0 }, Color::White), @@ -215,7 +214,7 @@ mod test { #[test] fn ko_rules_are_enforced() { - let mut state = GameState::new(); + let mut state = GameState::default(); state.board = Board::from_coordinates( vec![ (Coordinate { column: 7, row: 9 }, Color::White), diff --git a/kifu/core/src/ui/types.rs b/kifu/core/src/ui/types.rs index 1454a31..9bfa6cf 100644 --- a/kifu/core/src/ui/types.rs +++ b/kifu/core/src/ui/types.rs @@ -76,7 +76,7 @@ impl BoardElement { } fn addr(&self, column: u8, row: u8) -> usize { - ((row as usize) * (self.size.width as usize) + (column as usize)) as usize + (row as usize) * (self.size.width as usize) + (column as usize) } } diff --git a/kifu/gtk/src/lib.rs b/kifu/gtk/src/lib.rs index 94c88d6..ff7a505 100644 --- a/kifu/gtk/src/lib.rs +++ b/kifu/gtk/src/lib.rs @@ -28,5 +28,5 @@ where let result = f(); let end = std::time::Instant::now(); println!("[Trace: {}] {:?}", trace_name, end - start); - return result; + result } diff --git a/kifu/gtk/src/main.rs b/kifu/gtk/src/main.rs index 614b1dc..a8869f8 100644 --- a/kifu/gtk/src/main.rs +++ b/kifu/gtk/src/main.rs @@ -34,8 +34,8 @@ fn handle_response(api: CoreApi, app_window: &AppWindow, message: CoreResponse) app_window.set_content(&field); *playing_field = Some(field); }) - } else { - playing_field.as_ref().map(|field| field.update_view(view)); + } else if let Some(field) = playing_field.as_ref() { + field.update_view(view) } }), CoreResponse::UpdatedConfigurationView(view) => perftrace("UpdatedConfiguration", || { @@ -56,13 +56,13 @@ fn main() { ); let config_path = std::env::var("CONFIG") - .and_then(|config| Ok(std::path::PathBuf::from(config))) + .map(std::path::PathBuf::from) .or({ - std::env::var("HOME").and_then(|base| { + std::env::var("HOME").map(|base| { let mut config_path = std::path::PathBuf::from(base); config_path.push(".config"); config_path.push("kifu"); - Ok(config_path) + config_path }) }) .expect("no config path could be found"); @@ -87,7 +87,7 @@ fn main() { let (gtk_tx, gtk_rx) = gtk::glib::MainContext::channel::(gtk::glib::PRIORITY_DEFAULT); - let app_window = AppWindow::new(&app); + let app_window = AppWindow::new(app); let api = CoreApi { gtk_tx, @@ -123,5 +123,5 @@ fn main() { println!("running the gtk loop"); app.run(); - let _ = runtime.block_on(async { core_handle.await }); + let _ = runtime.block_on(core_handle); } diff --git a/kifu/gtk/src/ui/board.rs b/kifu/gtk/src/ui/board.rs index fa3e67d..fa30855 100644 --- a/kifu/gtk/src/ui/board.rs +++ b/kifu/gtk/src/ui/board.rs @@ -89,7 +89,7 @@ impl ObjectImpl for BoardPrivate { match background { Ok(Some(ref background)) => { - context.set_source_pixbuf(&background, 0., 0.); + context.set_source_pixbuf(background, 0., 0.); context.paint().expect("paint should succeed"); } Ok(None) | Err(_) => context.set_source_rgb(0.7, 0.7, 0.7), @@ -140,11 +140,8 @@ impl ObjectImpl for BoardPrivate { (0..19).for_each(|col| { (0..19).for_each(|row| { - match board.stone(row, col) { - IntersectionElement::Filled(stone) => { - pen.stone(&context, row, col, stone.color, stone.liberties); - } - _ => {} + if let IntersectionElement::Filled(stone) = board.stone(row, col) { + pen.stone(context, row, col, stone.color, stone.liberties); }; }) }); @@ -152,15 +149,18 @@ impl ObjectImpl for BoardPrivate { let cursor = cursor_location.borrow(); match *cursor { None => {} - Some(ref cursor) => match board.stone(cursor.row, cursor.column) { - IntersectionElement::Empty(_) => pen.ghost_stone( - context, - cursor.row, - cursor.column, - *current_player.borrow(), - ), - _ => {} - }, + Some(ref cursor) => { + if let IntersectionElement::Empty(_) = + board.stone(cursor.row, cursor.column) + { + pen.ghost_stone( + context, + cursor.row, + cursor.column, + *current_player.borrow(), + ) + } + } } let render_end = std::time::Instant::now(); println!("board rendering time: {:?}", render_end - render_start); @@ -208,16 +208,17 @@ impl ObjectImpl for BoardPrivate { let cursor = cursor.borrow(); match *cursor { None => {} - Some(ref cursor) => match board.stone(cursor.row, cursor.column) { - IntersectionElement::Empty(request) => { + Some(ref cursor) => { + if let IntersectionElement::Empty(request) = + board.stone(cursor.row, cursor.column) + { println!("need to send request: {:?}", request); api.borrow() .as_ref() .expect("API must exist") .dispatch(request); } - _ => {} - }, + } } }); } diff --git a/kifu/gtk/src/ui/chat.rs b/kifu/gtk/src/ui/chat.rs index 4e31094..104a800 100644 --- a/kifu/gtk/src/ui/chat.rs +++ b/kifu/gtk/src/ui/chat.rs @@ -39,7 +39,7 @@ impl Chat { element.messages.into_iter().for_each(|msg| { s.imp().chat_history.append( >k::Label::builder() - .label(&msg) + .label(msg) .halign(gtk::Align::Start) .build(), ) diff --git a/kifu/gtk/src/ui/game_preview.rs b/kifu/gtk/src/ui/game_preview.rs index ff87214..5ba112e 100644 --- a/kifu/gtk/src/ui/game_preview.rs +++ b/kifu/gtk/src/ui/game_preview.rs @@ -26,8 +26,8 @@ glib::wrapper! { pub struct GamePreview(ObjectSubclass) @extends gtk::Box, gtk::Widget, @implements gtk::Orientable; } -impl GamePreview { - pub fn new() -> GamePreview { +impl Default for GamePreview { + fn default() -> Self { let s: Self = Object::builder().build(); s.set_orientation(gtk::Orientation::Horizontal); s.set_homogeneous(true); @@ -41,7 +41,9 @@ impl GamePreview { s } +} +impl GamePreview { pub fn set_game(&self, element: GamePreviewElement) { self.imp().black_player.set_text(&element.black_player); self.imp().white_player.set_text(&element.white_player); diff --git a/kifu/gtk/src/ui/home.rs b/kifu/gtk/src/ui/home.rs index daf0691..1ace82e 100644 --- a/kifu/gtk/src/ui/home.rs +++ b/kifu/gtk/src/ui/home.rs @@ -137,7 +137,7 @@ impl Home { .build(); s.append(&new_game_button); - let library = Library::new(); + let library = Library::default(); let library_view = gtk::ScrolledWindow::builder() .hscrollbar_policy(gtk::PolicyType::Never) .min_content_width(360) diff --git a/kifu/gtk/src/ui/library.rs b/kifu/gtk/src/ui/library.rs index a2b42c6..034d3dc 100644 --- a/kifu/gtk/src/ui/library.rs +++ b/kifu/gtk/src/ui/library.rs @@ -1,7 +1,6 @@ -use crate::ui::GamePreview; use adw::{prelude::*, subclass::prelude::*}; use glib::Object; -use gtk::{glib, prelude::*, subclass::prelude::*}; +use gtk::glib; use kifu_core::ui::GamePreviewElement; use std::{cell::RefCell, rc::Rc}; @@ -92,7 +91,7 @@ impl Default for LibraryPrivate { .set_child(Some( >k::Label::builder() .halign(gtk::Align::Start) - .ellipsize(pango::EllipsizeMode::End) + .ellipsize(gtk::pango::EllipsizeMode::End) .build(), )) }); @@ -100,10 +99,9 @@ impl Default for LibraryPrivate { let list_item = list_item.downcast_ref::().unwrap(); let game = list_item.item().and_downcast::().unwrap(); let preview = list_item.child().and_downcast::().unwrap(); - match game.game() { - Some(game) => preview.set_text(&bind(game)), - None => (), - }; + if let Some(game) = game.game() { + preview.set_text(&bind(game)) + } }); factory } @@ -148,18 +146,20 @@ glib::wrapper! { pub struct Library(ObjectSubclass) @extends adw::Bin, gtk::Widget; } -impl Library { - pub fn new() -> Self { +impl Default for Library { + fn default() -> Self { let s: Self = Object::builder().build(); s.set_child(Some(&s.imp().list_view)); s } +} +impl Library { pub fn set_games(&self, games: Vec) { let games = games .into_iter() - .map(|g| GameObject::new(g)) + .map(GameObject::new) .collect::>(); self.imp().model.extend_from_slice(&games); } diff --git a/kifu/gtk/src/ui/mod.rs b/kifu/gtk/src/ui/mod.rs index 5b5bfcd..00b5cbd 100644 --- a/kifu/gtk/src/ui/mod.rs +++ b/kifu/gtk/src/ui/mod.rs @@ -1,7 +1,7 @@ use adw::prelude::*; use gio::resources_lookup_data; use glib::IsA; -use gtk::{prelude::*, STYLE_PROVIDER_PRIORITY_USER}; +use gtk::STYLE_PROVIDER_PRIORITY_USER; mod chat; pub use chat::Chat; diff --git a/kifu/gtk/src/ui/playing_field.rs b/kifu/gtk/src/ui/playing_field.rs index dce713e..4317707 100644 --- a/kifu/gtk/src/ui/playing_field.rs +++ b/kifu/gtk/src/ui/playing_field.rs @@ -50,11 +50,9 @@ impl PlayingField { let chat = Chat::new(view.chat); *s.imp().board.borrow_mut() = Some(Board::new(api)); - s.imp() - .board - .borrow() - .as_ref() - .map(|board| s.attach(board, 1, 1, 1, 2)); + if let Some(board) = s.imp().board.borrow().as_ref() { + s.attach(board, 1, 1, 1, 2) + } s.attach(&player_card_black, 2, 1, 1, 1); s.attach(&player_card_white, 3, 1, 1, 1); s.attach(&chat, 2, 2, 2, 1); @@ -63,20 +61,20 @@ impl PlayingField { *s.imp().player_card_black.borrow_mut() = Some(player_card_black); *s.imp().chat.borrow_mut() = Some(chat); - s.imp().board.borrow().as_ref().map(|board| { + if let Some(board) = s.imp().board.borrow().as_ref() { board.set_board(view.board); board.set_current_player(view.current_player); - }); + }; s } pub fn update_view(&self, view: PlayingFieldView) { perftrace("update_view", || { - self.imp().board.borrow().as_ref().map(|board| { + if let Some(board) = self.imp().board.borrow().as_ref() { board.set_board(view.board); board.set_current_player(view.current_player); - }); + } }) } } diff --git a/memorycache/src/lib.rs b/memorycache/src/lib.rs index 2245688..7ac9fb0 100644 --- a/memorycache/src/lib.rs +++ b/memorycache/src/lib.rs @@ -13,11 +13,13 @@ pub struct MemoryCacheRecord { pub struct MemoryCache(Arc>>>); -impl MemoryCache { - pub fn new() -> MemoryCache { - MemoryCache(Arc::new(RwLock::new(HashMap::new()))) +impl Default for MemoryCache { + fn default() -> Self { + Self(Arc::new(RwLock::new(HashMap::new()))) } +} +impl MemoryCache { pub async fn find(&self, key: &str, f: impl Future, T)>) -> T { let val = { let cache = self.0.read().unwrap(); @@ -53,7 +55,7 @@ mod tests { #[tokio::test] async fn it_runs_the_requestor_when_the_value_does_not_exist() { - let cache = MemoryCache::new(); + let cache = MemoryCache::default(); let value = cache .find("my_key", async { (Utc::now(), Value(15)) }) .await; @@ -63,7 +65,7 @@ mod tests { #[tokio::test] async fn it_runs_the_requestor_when_the_value_is_old() { let run = Arc::new(RwLock::new(false)); - let cache = MemoryCache::new(); + let cache = MemoryCache::default(); let _ = cache .find("my_key", async { (Utc::now() - Duration::seconds(10), Value(15)) @@ -82,7 +84,7 @@ mod tests { #[tokio::test] async fn it_returns_the_cached_value_when_the_value_is_new() { let run = Arc::new(RwLock::new(false)); - let cache = MemoryCache::new(); + let cache = MemoryCache::default(); let _ = cache .find("my_key", async { (Utc::now() + Duration::seconds(10), Value(15)) diff --git a/sgf/src/date.rs b/sgf/src/date.rs index 3058174..8de0e1b 100644 --- a/sgf/src/date.rs +++ b/sgf/src/date.rs @@ -1,6 +1,6 @@ use chrono::{Datelike, NaiveDate}; use serde::{Deserialize, Serialize}; -use std::num::ParseIntError; +use std::{fmt, num::ParseIntError}; use thiserror::Error; use typeshare::typeshare; @@ -11,9 +11,6 @@ pub enum Error { #[error("Invalid date")] InvalidDate, - - #[error("unsupported date format")] - Unsupported, } #[derive(Clone, Debug, PartialEq, PartialOrd, Deserialize, Serialize)] @@ -24,12 +21,12 @@ pub enum Date { Date(chrono::NaiveDate), } -impl Date { - pub fn to_string(&self) -> String { +impl fmt::Display for Date { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - Date::Year(y) => format!("{}", y), - Date::YearMonth(y, m) => format!("{}-{}", y, m), - Date::Date(date) => format!("{}-{}-{}", date.year(), date.month(), date.day()), + Date::Year(y) => write!(f, "{}", y), + Date::YearMonth(y, m) => write!(f, "{}-{}", y, m), + Date::Date(date) => write!(f, "{}-{}-{}", date.year(), date.month(), date.day()), } } } @@ -71,13 +68,13 @@ impl TryFrom<&str> for Date { */ fn parse_numbers(s: &str) -> Result, Error> { - s.split("-") - .map(|s| s.parse::().map_err(|err| Error::ParseNumberError(err))) + s.split('-') + .map(|s| s.parse::().map_err(Error::ParseNumberError)) .collect::, Error>>() } pub fn parse_date_field(s: &str) -> Result, Error> { - let date_elements = s.split(","); + let date_elements = s.split(','); let mut dates = Vec::new(); let mut most_recent: Option = None; @@ -96,9 +93,9 @@ pub fn parse_date_field(s: &str) -> Result, Error> { None => Date::Year(*v1), }, [v1, v2] => Date::YearMonth(*v1, *v2 as u32), - [v1, v2, v3, ..] => Date::Date( - NaiveDate::from_ymd_opt(v1.clone(), v2.clone() as u32, v3.clone() as u32).unwrap(), - ), + [v1, v2, v3, ..] => { + Date::Date(NaiveDate::from_ymd_opt(*v1, *v2 as u32, *v3 as u32).unwrap()) + } }; dates.push(new_date.clone()); most_recent = Some(new_date); diff --git a/sgf/src/go.rs b/sgf/src/go.rs index d0fa213..2c226f4 100644 --- a/sgf/src/go.rs +++ b/sgf/src/go.rs @@ -95,6 +95,7 @@ impl Deref for Game { impl TryFrom for Game { type Error = Error; + #[allow(clippy::field_reassign_with_default)] fn try_from(tree: Tree) -> Result { let board_size = match tree.root.find_prop("SZ") { Some(prop) => Size::try_from(prop.values[0].as_str())?, @@ -131,7 +132,7 @@ impl TryFrom for Game { .root .find_prop("TM") .and_then(|prop| prop.values[0].parse::().ok()) - .and_then(|seconds| Some(std::time::Duration::from_secs(seconds))); + .map(std::time::Duration::from_secs); info.date = tree .root @@ -182,7 +183,7 @@ pub enum Rank { impl TryFrom<&str> for Rank { type Error = String; fn try_from(r: &str) -> Result { - let parts = r.split(" ").map(|s| s.to_owned()).collect::>(); + let parts = r.split(' ').map(|s| s.to_owned()).collect::>(); let cnt = parts[0].parse::().map_err(|err| format!("{:?}", err))?; match parts[1].to_ascii_lowercase().as_str() { "kyu" => Ok(Rank::Kyu(cnt)), @@ -250,7 +251,7 @@ impl TryFrom<&str> for GameResult { } else if s == "Void" { Ok(GameResult::Annulled) } else { - let parts = s.split("+").collect::>(); + let parts = s.split('+').collect::>(); let res = match parts[0].to_ascii_lowercase().as_str() { "b" => GameResult::Black, "w" => GameResult::White, diff --git a/sgf/src/lib.rs b/sgf/src/lib.rs index bd2937c..3c42229 100644 --- a/sgf/src/lib.rs +++ b/sgf/src/lib.rs @@ -51,7 +51,7 @@ impl From> for ParseError { fn from(err: nom::error::Error<&str>) -> Self { Self::NomError(nom::error::Error { input: err.input.to_owned(), - code: err.code.clone(), + code: err.code, }) } } diff --git a/sgf/src/tree.rs b/sgf/src/tree.rs index e1340a2..167353d 100644 --- a/sgf/src/tree.rs +++ b/sgf/src/tree.rs @@ -2,7 +2,7 @@ use crate::Error; use nom::{ branch::alt, bytes::complete::{escaped_transform, tag}, - character::complete::{alpha1, digit1, multispace0, multispace1, none_of}, + character::complete::{alpha1, multispace0, multispace1, none_of}, combinator::{opt, value}, multi::{many0, many1, separated_list1}, IResult, @@ -101,7 +101,7 @@ impl Node { .cloned() } - pub fn next<'a>(&'a self) -> Option<&'a Node> { + pub fn next(&self) -> Option<&Node> { self.next.get(0) } } @@ -209,21 +209,6 @@ fn parse_propval_text<'a, E: nom::error::ParseError<&'a str>>( Ok((input, value.map(|v| v.to_owned()))) } -pub fn parse_size<'a, E: nom::error::ParseError<&'a str>>( - input: &'a str, -) -> IResult<&'a str, Size, E> { - let (input, dimensions) = separated_list1(tag(":"), digit1)(input)?; - let (width, height) = match dimensions.as_slice() { - [width] => (width.parse::().unwrap(), width.parse::().unwrap()), - [width, height] => ( - width.parse::().unwrap(), - height.parse::().unwrap(), - ), - _ => (19, 19), - }; - Ok((input, Size { width, height })) -} - #[cfg(test)] mod test { use super::*;