Fix clippy warnings and make macro for error types

This commit is contained in:
Yash Karandikar 2022-06-21 15:29:27 +05:30
parent 0f7311cc2b
commit fbf2532189
4 changed files with 69 additions and 28 deletions

View file

@ -83,6 +83,14 @@
//! } //! }
//! ``` //! ```
#![warn(clippy::pedantic)]
#![allow(
clippy::similar_names,
clippy::needless_doctest_main,
clippy::module_name_repetitions,
clippy::missing_errors_doc
)]
pub mod physics; pub mod physics;
pub mod vec2; pub mod vec2;
@ -100,7 +108,7 @@ use sdl2::{
render::{Canvas, TextureCreator, TextureValueError}, render::{Canvas, TextureCreator, TextureValueError},
rwops::RWops, rwops::RWops,
surface::Surface, surface::Surface,
ttf::{FontError, Sdl2TtfContext}, ttf::{FontError, InitError, Sdl2TtfContext},
video::{Window, WindowBuildError, WindowContext}, video::{Window, WindowBuildError, WindowContext},
EventPump, IntegerOrSdlError, EventPump, IntegerOrSdlError,
}; };
@ -125,37 +133,33 @@ macro_rules! cloned {
} }
} }
macro_rules! error_from_format {
($($t:ty),+) => {
$(
impl From<$t> for CatboxError {
fn from(e: $t) -> Self {
CatboxError(format!("{}", e))
}
}
)+
};
}
#[derive(Debug)] #[derive(Debug)]
pub struct CatboxError(String); pub struct CatboxError(String);
impl From<WindowBuildError> for CatboxError {
fn from(e: WindowBuildError) -> Self {
CatboxError(format!("{}", e))
}
}
impl From<String> for CatboxError { impl From<String> for CatboxError {
fn from(e: String) -> Self { fn from(e: String) -> Self {
CatboxError(e) CatboxError(e)
} }
} }
impl From<IntegerOrSdlError> for CatboxError { error_from_format! {
fn from(e: IntegerOrSdlError) -> Self { WindowBuildError,
CatboxError(format!("{}", e)) IntegerOrSdlError,
} TextureValueError,
} FontError,
InitError
impl From<TextureValueError> for CatboxError {
fn from(e: TextureValueError) -> Self {
CatboxError(format!("{}", e))
}
}
impl From<FontError> for CatboxError {
fn from(e: FontError) -> Self {
CatboxError(format!("{}", e))
}
} }
pub type Result<T> = std::result::Result<T, CatboxError>; pub type Result<T> = std::result::Result<T, CatboxError>;
@ -301,6 +305,7 @@ impl Sprite {
/// # let s = Sprite::new("duck.png", 500, 400).unwrap(); /// # let s = Sprite::new("duck.png", 500, 400).unwrap();
/// let angle = s.angle(); /// let angle = s.angle();
/// ``` /// ```
#[must_use]
pub fn angle(&self) -> f64 { pub fn angle(&self) -> f64 {
self.angle self.angle
} }
@ -312,6 +317,7 @@ impl Sprite {
/// # let s = Sprite::new("duck.png", 500, 400).unwrap(); /// # let s = Sprite::new("duck.png", 500, 400).unwrap();
/// let (x, y) = s.position().into(); /// let (x, y) = s.position().into();
/// ``` /// ```
#[must_use]
pub fn position(&self) -> Vec2Int { pub fn position(&self) -> Vec2Int {
self.rect.center().into() self.rect.center().into()
} }
@ -321,6 +327,7 @@ impl Sprite {
/// ///
/// Technically, this is a thin wrapper around a simple [`Vec`] of sprites, /// Technically, this is a thin wrapper around a simple [`Vec`] of sprites,
/// although with some convenience methods. /// although with some convenience methods.
#[derive(Default)]
pub struct SpriteCollection { pub struct SpriteCollection {
v: Vec<Sprite>, v: Vec<Sprite>,
} }
@ -333,6 +340,7 @@ impl SpriteCollection {
/// # use cat_box::*; /// # use cat_box::*;
/// let sprites = SpriteCollection::new(); /// let sprites = SpriteCollection::new();
/// ``` /// ```
#[must_use]
pub fn new() -> Self { pub fn new() -> Self {
Self { v: Vec::new() } Self { v: Vec::new() }
} }
@ -344,6 +352,7 @@ impl SpriteCollection {
/// # use cat_box::*; /// # use cat_box::*;
/// let sprites = SpriteCollection::with_capacity(10); /// let sprites = SpriteCollection::with_capacity(10);
/// ``` /// ```
#[must_use]
pub fn with_capacity(cap: usize) -> Self { pub fn with_capacity(cap: usize) -> Self {
Self { Self {
v: Vec::with_capacity(cap), v: Vec::with_capacity(cap),
@ -361,7 +370,7 @@ impl SpriteCollection {
/// # }); /// # });
/// ``` /// ```
pub fn draw(&mut self, ctx: &mut Context) -> Result<()> { pub fn draw(&mut self, ctx: &mut Context) -> Result<()> {
for s in self.v.iter_mut() { for s in &mut self.v {
s.draw(ctx)?; s.draw(ctx)?;
} }
@ -449,6 +458,7 @@ impl SpriteCollection {
} }
/// Returns the length of this vector. /// Returns the length of this vector.
#[must_use]
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
self.v.len() self.v.len()
} }
@ -461,14 +471,21 @@ impl SpriteCollection {
/// # sprites.push(s); /// # sprites.push(s);
/// let s = sprites.get(0); /// let s = sprites.get(0);
/// ``` /// ```
#[must_use]
pub fn get(&self, index: usize) -> Option<&Sprite> { pub fn get(&self, index: usize) -> Option<&Sprite> {
self.v.get(index) self.v.get(index)
} }
/// Return the inner Vec. Only use this method if you know what you're doing. /// Return the inner Vec. Only use this method if you know what you're doing.
#[must_use]
pub fn inner(&self) -> &Vec<Sprite> { pub fn inner(&self) -> &Vec<Sprite> {
&self.v &self.v
} }
#[must_use]
pub fn is_empty(&self) -> bool {
self.v.is_empty()
}
} }
impl Deref for SpriteCollection { impl Deref for SpriteCollection {
@ -550,6 +567,7 @@ impl Context {
} }
/// Set the mode for drawing text. /// Set the mode for drawing text.
#[derive(Clone, Copy, Debug)]
pub enum TextMode { pub enum TextMode {
/// Render the text transparently. /// Render the text transparently.
Transparent { colour: (u8, u8, u8) }, Transparent { colour: (u8, u8, u8) },
@ -686,6 +704,7 @@ impl Game {
/// Game::new("cool game", 1000, 1000); /// Game::new("cool game", 1000, 1000);
/// ``` /// ```
/// ///
#[must_use]
pub fn new(title: &str, width: u32, height: u32) -> Self { pub fn new(title: &str, width: u32, height: u32) -> Self {
Self { Self {
title: title.to_string(), title: title.to_string(),
@ -716,7 +735,7 @@ impl Game {
.build()?; .build()?;
let canvas = window.into_canvas().build()?; let canvas = window.into_canvas().build()?;
let s = sdl2::ttf::init().unwrap(); let s = sdl2::ttf::init()?;
let event_pump = sdl_context.event_pump()?; let event_pump = sdl_context.event_pump()?;

View file

@ -1,3 +1,5 @@
#![warn(clippy::pedantic)]
use cat_box::{draw_text, get_keyboard_state, get_mouse_state, Game, Sprite, SpriteCollection}; use cat_box::{draw_text, get_keyboard_state, get_mouse_state, Game, Sprite, SpriteCollection};
use sdl2::keyboard::Scancode; use sdl2::keyboard::Scancode;
@ -39,7 +41,7 @@ fn main() {
let x_diff = m.x - start_x; let x_diff = m.x - start_x;
let y_diff = m.y - start_y; let y_diff = m.y - start_y;
let angle = (y_diff as f64).atan2(x_diff as f64); let angle = f64::from(y_diff).atan2(f64::from(x_diff));
s.set_angle(angle.to_degrees()); s.set_angle(angle.to_degrees());
for spr in coll.iter() { for spr in coll.iter() {
@ -48,7 +50,7 @@ fn main() {
let x_diff = m.x - start_x; let x_diff = m.x - start_x;
let y_diff = m.y - start_y; let y_diff = m.y - start_y;
let angle = (y_diff as f64).atan2(x_diff as f64); let angle = f64::from(y_diff).atan2(f64::from(x_diff));
spr.set_angle(angle.to_degrees()); spr.set_angle(angle.to_degrees());
} }

View file

@ -2,6 +2,8 @@
//! //!
//! Still ***very much work-in-progress*** //! Still ***very much work-in-progress***
#![allow(clippy::cast_possible_wrap)]
use crate::{Sprite, SpriteCollection}; use crate::{Sprite, SpriteCollection};
use std::cmp::max; use std::cmp::max;
@ -28,16 +30,18 @@ fn collided(sprite1: &Sprite, sprite2: &Sprite) -> bool {
return false; return false;
} }
return sprite1.rect.has_intersection(sprite2.rect); sprite1.rect.has_intersection(sprite2.rect)
} }
/// Check if two sprites are touching or overlapping. /// Check if two sprites are touching or overlapping.
#[must_use]
pub fn check_for_collision(sprite1: &Sprite, sprite2: &Sprite) -> bool { pub fn check_for_collision(sprite1: &Sprite, sprite2: &Sprite) -> bool {
collided(sprite1, sprite2) collided(sprite1, sprite2)
} }
/// Check if the sprite is colliding with any sprite in the collection, and return a list of /// Check if the sprite is colliding with any sprite in the collection, and return a list of
/// references to the sprites which are colliding /// references to the sprites which are colliding
#[must_use]
pub fn check_for_collision_with_collection<'a>( pub fn check_for_collision_with_collection<'a>(
sprite: &Sprite, sprite: &Sprite,
list: &'a SpriteCollection, list: &'a SpriteCollection,

View file

@ -34,11 +34,13 @@ pub enum Direction {
#[allow(clippy::enum_glob_use)] #[allow(clippy::enum_glob_use)]
impl Direction { impl Direction {
/// Flips this `Direction` around both the x- and y-axes. /// Flips this `Direction` around both the x- and y-axes.
#[must_use]
pub fn flipped(self) -> Self { pub fn flipped(self) -> Self {
self.flip_x().flip_y() self.flip_x().flip_y()
} }
/// Flips this `Direction` around the x-axis. /// Flips this `Direction` around the x-axis.
#[must_use]
pub fn flip_x(self) -> Self { pub fn flip_x(self) -> Self {
use Direction::*; use Direction::*;
match self { match self {
@ -49,6 +51,7 @@ impl Direction {
} }
/// Flips this `Direction` around the y-axis. /// Flips this `Direction` around the y-axis.
#[must_use]
pub fn flip_y(self) -> Self { pub fn flip_y(self) -> Self {
use Direction::*; use Direction::*;
match self { match self {
@ -144,6 +147,7 @@ impl Vec2 {
/// Creates a new `Vec2` with the given x- and y-values. /// Creates a new `Vec2` with the given x- and y-values.
/// ///
/// It is often simpler, and preferred, to just write `(x, y).into()`. /// It is often simpler, and preferred, to just write `(x, y).into()`.
#[must_use]
pub const fn new(x: f32, y: f32) -> Vec2 { pub const fn new(x: f32, y: f32) -> Vec2 {
Self { x, y } Self { x, y }
} }
@ -151,11 +155,13 @@ impl Vec2 {
/// Gets the squared magnitude of the vector. /// Gets the squared magnitude of the vector.
/// ///
/// Useful for comparisons as it is faster to calculate than `magnitude`. /// Useful for comparisons as it is faster to calculate than `magnitude`.
#[must_use]
pub fn sq_magnitude(self) -> f32 { pub fn sq_magnitude(self) -> f32 {
self.x * self.x + self.y * self.y self.x * self.x + self.y * self.y
} }
/// Gets the magnitude of the vector. /// Gets the magnitude of the vector.
#[must_use]
pub fn magnitude(self) -> f32 { pub fn magnitude(self) -> f32 {
self.sq_magnitude().sqrt() self.sq_magnitude().sqrt()
} }
@ -163,16 +169,19 @@ impl Vec2 {
/// Gets the squared distance from this vector to `rhs`. /// Gets the squared distance from this vector to `rhs`.
/// ///
/// Useful for comparisons as it is faster to calculate than `dist`. /// Useful for comparisons as it is faster to calculate than `dist`.
#[must_use]
pub fn sq_dist(self, rhs: Self) -> f32 { pub fn sq_dist(self, rhs: Self) -> f32 {
(self - rhs).sq_magnitude() (self - rhs).sq_magnitude()
} }
/// Gets the distance from this vector to `rhs`. /// Gets the distance from this vector to `rhs`.
#[must_use]
pub fn dist(self, rhs: Self) -> f32 { pub fn dist(self, rhs: Self) -> f32 {
(self - rhs).magnitude() (self - rhs).magnitude()
} }
/// Normalizes the vector, making its magnitude `1`. /// Normalizes the vector, making its magnitude `1`.
#[must_use]
pub fn normalized(self) -> Self { pub fn normalized(self) -> Self {
self / self.magnitude() self / self.magnitude()
} }
@ -180,6 +189,7 @@ impl Vec2 {
/// Rounds the vector to a [`Vec2Int`]. /// Rounds the vector to a [`Vec2Int`].
/// ///
/// This uses `as i32` under the hood, and as such comes with all the same unfortunate edge cases. Beware. /// This uses `as i32` under the hood, and as such comes with all the same unfortunate edge cases. Beware.
#[must_use]
pub fn rounded(self) -> Vec2Int { pub fn rounded(self) -> Vec2Int {
#[allow(clippy::cast_possible_truncation)] #[allow(clippy::cast_possible_truncation)]
Vec2Int { Vec2Int {
@ -333,6 +343,7 @@ impl Vec2Int {
/// Creates a new `Vec2` with the given x- and y-values. /// Creates a new `Vec2` with the given x- and y-values.
/// ///
/// It is often simpler, and preferred, to just write `(x, y).into()`. /// It is often simpler, and preferred, to just write `(x, y).into()`.
#[must_use]
pub const fn new(x: i32, y: i32) -> Vec2Int { pub const fn new(x: i32, y: i32) -> Vec2Int {
Self { x, y } Self { x, y }
} }
@ -340,11 +351,13 @@ impl Vec2Int {
/// Gets the squared magnitude of the vector. /// Gets the squared magnitude of the vector.
/// ///
/// Useful for comparisons as it is faster to calculate than `magnitude`. /// Useful for comparisons as it is faster to calculate than `magnitude`.
#[must_use]
pub fn sq_magnitude(self) -> i32 { pub fn sq_magnitude(self) -> i32 {
self.x * self.x + self.y * self.y self.x * self.x + self.y * self.y
} }
/// Gets the magnitude of the vector. /// Gets the magnitude of the vector.
#[must_use]
pub fn magnitude(self) -> f32 { pub fn magnitude(self) -> f32 {
#[allow(clippy::cast_precision_loss)] #[allow(clippy::cast_precision_loss)]
(self.sq_magnitude() as f32).sqrt() (self.sq_magnitude() as f32).sqrt()
@ -353,11 +366,13 @@ impl Vec2Int {
/// Gets the squared distance from this vector to `rhs`. /// Gets the squared distance from this vector to `rhs`.
/// ///
/// Useful for comparisons as it is faster to calculate than `dist`. /// Useful for comparisons as it is faster to calculate than `dist`.
#[must_use]
pub fn sq_dist(self, rhs: Self) -> i32 { pub fn sq_dist(self, rhs: Self) -> i32 {
(self - rhs).sq_magnitude() (self - rhs).sq_magnitude()
} }
/// Gets the distance from this vector to `rhs`. /// Gets the distance from this vector to `rhs`.
#[must_use]
pub fn dist(self, rhs: Self) -> f32 { pub fn dist(self, rhs: Self) -> f32 {
(self - rhs).magnitude() (self - rhs).magnitude()
} }
@ -365,6 +380,7 @@ impl Vec2Int {
/// Casts this vector to a [`Vec2`]. /// Casts this vector to a [`Vec2`].
/// ///
/// This uses `as f32` under the hood, and as such comes with all the same unfortunate edge cases. Beware. /// This uses `as f32` under the hood, and as such comes with all the same unfortunate edge cases. Beware.
#[must_use]
pub fn to_f32(self) -> Vec2 { pub fn to_f32(self) -> Vec2 {
#[allow(clippy::cast_precision_loss)] #[allow(clippy::cast_precision_loss)]
Vec2 { Vec2 {