Please clippy

master
Tait Hoyem 12 months ago
parent b821be5913
commit f5e04fce16

33
Cargo.lock generated

@ -383,15 +383,6 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
[[package]]
name = "convert_case"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.4"
@ -534,7 +525,7 @@ version = "0.99.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
dependencies = [
"convert_case 0.4.0",
"convert_case",
"proc-macro2",
"quote",
"rustc_version",
@ -1132,8 +1123,6 @@ dependencies = [
"lazy_static",
"once_cell",
"ormx",
"rename",
"rename-item",
"rust-embed",
"rust-i18n",
"serde",
@ -1735,26 +1724,6 @@ version = "0.6.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
[[package]]
name = "rename"
version = "0.1.1"
dependencies = [
"quote",
"syn 1.0.109",
]
[[package]]
name = "rename-item"
version = "0.1.0"
dependencies = [
"convert_case 0.6.0",
"darling",
"heck",
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "ring"
version = "0.16.20"

@ -33,8 +33,6 @@ i18n-embed-fl = "0.6.6"
rust-embed = { version = "6.6.1", features = ["axum"] }
lazy_static = "1.4.0"
ibihf-macros = { version = "0.1.0", path = "ibihf-macros" }
rename = { version = "0.1.1", path = "../rename-rs" }
rename-item = { version = "0.1.0", path = "../rename-item" }
[dev-dependencies]
tokio-test = "0.4.2"

@ -1,3 +1,9 @@
// We must always wrap a return type of a filter in a Result.
// This sometimes triggers a clippy warning.
#![allow(clippy::unnecessary_wraps)]
// We must always take references, even when it's not technically the fastest thing to do.
// This sometimes also causes a clippy warning.
#![allow(clippy::trivially_copy_pass_by_ref)]
use crate::{
Player,
ShotDetails,
@ -8,7 +14,7 @@ use crate::{
pub fn seconds_as_time(secs: &i32) -> ::askama::Result<String> {
let minutes = secs / 60;
let seconds = secs % 60;
Ok(format!("{}:{}", minutes, seconds))
Ok(format!("{minutes}:{seconds}"))
}
pub fn player_name(player: &Player) -> ::askama::Result<String> {
Ok(format!("{} {}", initials(&player.first_names)?, &player.last_name))
@ -17,48 +23,40 @@ pub fn goal_player_name(goal: &GoalDetails) -> ::askama::Result<String> {
Ok(format!("{} {}", initials(&goal.player_first_names)?, &goal.player_last_name))
}
pub fn goal_assist_name(goal: &GoalDetails, lang: &SupportedLanguage) -> ::askama::Result<String> {
let initials = match goal.first_assist_first_names {
Some(ref f_names) => initials(f_names)?,
None => return Ok(lang.lookup("not-applicable")),
};
let last_name = match goal.first_assist_last_name {
Some(ref l_name) => l_name,
None => return Ok(lang.lookup("not-applicable")),
};
Ok(format!("{} {}", initials, last_name))
let Some(ref f_names) = goal.second_assist_first_names else {
return Ok(lang.lookup("not-applicable"));
};
let Some(ref l_name) = goal.second_assist_last_name else {
return Ok(lang.lookup("not-applicable"));
};
Ok(format!("{f_names} {l_name}"))
}
pub fn shot_assist_name(goal: &ShotDetails, lang: &SupportedLanguage) -> ::askama::Result<String> {
let initials = match goal.first_assist_first_names {
Some(ref f_names) => initials(&f_names)?,
None => return Ok(lang.lookup("not-applicable")),
};
let last_name = match goal.first_assist_last_name {
Some(ref l_name) => l_name,
None => return Ok(lang.lookup("not-applicable")),
};
Ok(format!("{} {}", initials, last_name))
let Some(ref f_names) = goal.second_assist_first_names else {
return Ok(lang.lookup("not-applicable"));
};
let Some(ref l_name) = goal.second_assist_last_name else {
return Ok(lang.lookup("not-applicable"));
};
Ok(format!("{f_names} {l_name}"))
}
pub fn goal_second_assist_name(goal: &GoalDetails, lang: &SupportedLanguage) -> ::askama::Result<String> {
let initials = match goal.second_assist_first_names {
Some(ref f_names) => initials(f_names)?,
None => return Ok(lang.lookup("not-applicable")),
};
let last_name = match goal.second_assist_last_name {
Some(ref l_name) => l_name,
None => return Ok(lang.lookup("not-applicable")),
};
Ok(format!("{} {}", initials, last_name))
let Some(ref f_names) = goal.second_assist_first_names else {
return Ok(lang.lookup("not-applicable"));
};
let Some(ref l_name) = goal.second_assist_last_name else {
return Ok(lang.lookup("not-applicable"));
};
Ok(format!("{f_names} {l_name}"))
}
pub fn shot_second_assist_name(goal: &ShotDetails, lang: &SupportedLanguage) -> ::askama::Result<String> {
let initials = match goal.second_assist_first_names {
Some(ref f_names) => initials(f_names)?,
None => return Ok(lang.lookup("not-applicable")),
};
let last_name = match goal.second_assist_last_name {
Some(ref l_name) => l_name,
None => return Ok(lang.lookup("not-applicable")),
};
Ok(format!("{} {}", initials, last_name))
let Some(ref f_names) = goal.second_assist_first_names else {
return Ok(lang.lookup("not-applicable"));
};
let Some(ref l_name) = goal.second_assist_last_name else {
return Ok(lang.lookup("not-applicable"));
};
Ok(format!("{f_names} {l_name}"))
}
pub fn shot_player_name(shot: &ShotDetails) -> ::askama::Result<String> {
Ok(format!("{} {}", initials(&shot.player_first_names)?, &shot.player_last_name))
@ -72,7 +70,7 @@ pub fn initials(first_names: &str) -> ::askama::Result<String> {
}
pub fn nullable<T: std::fmt::Display>(ot: &Option<T>) -> ::askama::Result<String> {
match ot {
Some(t) => Ok(format!("{}", t)),
Some(t) => Ok(format!("{t}")),
None => Ok("NULL".to_string())
}
}

@ -33,49 +33,49 @@ pub enum SupportedLanguage {
#[display(fmt = "fr-ca")]
French = 2,
}
impl Into<i32> for SupportedLanguage {
fn into(self) -> i32 {
match self {
Self::English => 1,
Self::French => 2,
}
}
impl From<SupportedLanguage> for i32 {
fn from(lang: SupportedLanguage) -> Self {
match lang {
SupportedLanguage::English => 1,
SupportedLanguage::French => 2,
}
}
}
impl From<SupportedLanguage> for FluentValue<'_> {
fn from(n: SupportedLanguage) -> Self {
n.to_string().into()
}
}
impl Into<LanguageIdentifier> for SupportedLanguage {
fn into(self) -> LanguageIdentifier {
match self {
Self::English => langid!("en-ca"),
Self::French => langid!("fr-ca"),
impl From<SupportedLanguage> for LanguageIdentifier {
fn from(lang: SupportedLanguage) -> LanguageIdentifier {
match lang {
SupportedLanguage::English => langid!("en-ca"),
SupportedLanguage::French => langid!("fr-ca"),
}
}
}
impl<'a> Into<Locale<'a>> for SupportedLanguage {
fn into(self) -> Locale<'a> {
Locale::new(self.into(), &LOCALES)
}
impl<'a> From<SupportedLanguage> for Locale<'a> {
fn from(lang: SupportedLanguage) -> Self {
Locale::new(lang.into(), &LOCALES)
}
}
impl SupportedLanguage {
pub fn lookup(&self, key: &str) -> String {
pub fn lookup(self, key: &str) -> String {
LOCALES
.lookup(&(*self).into(), key)
.lookup(&self.into(), key)
.expect("Unable to find key {key} in locale {self}.")
}
pub fn other_langs(&self) -> impl Iterator<Item = Self> + '_ {
Self::iter().filter(move |lang| lang != self)
pub fn other_langs(self) -> impl Iterator<Item = Self> + 'static {
Self::iter().filter(move |lang| lang != &self)
}
pub fn native_name(&self) -> String {
pub fn native_name(self) -> String {
match self {
Self::English => "English",
Self::French => "Français",
}
.to_string()
}
pub fn id(&self) -> i32 {
pub fn id(self) -> i32 {
match self {
Self::English => 1,
Self::French => 2,
@ -105,8 +105,8 @@ impl LocalizedName {
})
// if not found, replace it with ANY localization of the word; this will help when, for example, there is no matching name for a French game, but the game has already been created with the English name.
// if NO localization is found, then we can still return a None value; but hopefully through database, form, and web server restrictions, we can mostly stop that from happening
.or_else(|| if self.localizations.len() >= 1 {
Some(self.localizations.values().nth(0).unwrap().to_string())
.or_else(|| if self.localizations.is_empty() {
Some(self.localizations.values().next().unwrap().to_string())
} else {
None
})

@ -1,3 +1,9 @@
#![warn(
clippy::all,
clippy::pedantic,
unsafe_code,
)]
mod db;
mod filters;
mod languages;
@ -254,10 +260,9 @@ async fn main() {
&SupportedLanguage::French.lookup(GameScorePageTemplate::URL_KEY),
get(score_for_game_html),
)
//.route("/:lang/player/:name/", get(player_from_name))
.with_state(state);
let addr = SocketAddr::from(([127, 0, 0, 1], 8000));
println!("Listening on {}", addr);
println!("Listening on {addr}");
axum::Server::bind(&addr)
.serve(router.into_make_service())
.await
@ -275,42 +280,12 @@ async fn language_list(State(server_config): State<ServerState>) -> impl IntoRes
(StatusCode::OK, lang_list_tmpl)
}
async fn player_from_name(
State(server_config): State<ServerState>,
Path((lang, name)): Path<(SupportedLanguage, String)>,
) -> impl IntoResponse {
let player = Player::from_name_case_insensitive(&server_config.db_pool, name.clone())
.await
.unwrap();
let latest_league = Player::latest_league(&server_config.db_pool, player.id, lang.into())
.await
.unwrap()
.unwrap();
let latest_league_stats =
League::player_stats(&server_config.db_pool, player.id, latest_league.id)
.await
.unwrap();
let lifetime_stats = Player::lifetime_stats(&server_config.db_pool, player.id)
.await
.unwrap();
let html = PlayerPageTemplate {
player,
lang_links: other_lang_urls!(lang, PlayerPageTemplate),
locale: lang.into(),
league: latest_league,
league_stats: latest_league_stats,
lifetime_stats,
lang,
};
(StatusCode::OK, html)
}
/*
macro_rules! get_all {
($crud_struct:ident, $func_name:ident) => {
#[debug_handler]
async fn $func_name(State(server_config): State<ServerState>) -> impl IntoResponse {
let cruder = $crud_struct::all(&*server_config.db_pool).await.unwrap();
let cruder = $crud_struct::all(&server_config.db_pool).await.unwrap();
(StatusCode::OK, Json(cruder))
}
};
@ -322,7 +297,7 @@ macro_rules! get_by_id {
State(server_config): State<ServerState>,
Path(id): Path<i32>,
) -> impl IntoResponse {
let cruder = $crud_struct::get(&*server_config.db_pool, id)
let cruder = $crud_struct::get(&server_config.db_pool, id)
.await
.unwrap();
(StatusCode::OK, Json(cruder))
@ -335,7 +310,7 @@ async fn league_html(
State(server_config): State<ServerState>,
Path(lang): Path<SupportedLanguage>,
) -> impl IntoResponse {
let leagues = League::all(&*server_config.db_pool, lang.into()).await.unwrap();
let leagues = League::all(&server_config.db_pool, lang.into()).await.unwrap();
let leagues_template = LeagueListTemplate {
lang_links: other_lang_urls!(lang, LeagueListTemplate),
locale: lang.into(),
@ -349,11 +324,11 @@ async fn divisions_for_league_html(
State(server_config): State<ServerState>,
Path((lang, league_id)): Path<(SupportedLanguage, i32)>,
) -> impl IntoResponse {
let league = League::get(&*server_config.db_pool, league_id, lang.into())
let league = League::get(&server_config.db_pool, league_id, lang.into())
.await
.unwrap()
.unwrap();
let divisions = Division::by_league(&*server_config.db_pool, league_id, lang.into())
let divisions = Division::by_league(&server_config.db_pool, league_id, lang.into())
.await
.unwrap();
let html = DivisionListTemplate {
@ -371,14 +346,14 @@ async fn games_for_division_html(
State(server_config): State<ServerState>,
Path((lang, division_id)): Path<(SupportedLanguage, i32)>,
) -> impl IntoResponse {
let division = Division::get(&*server_config.db_pool, division_id, lang.into())
let division = Division::get(&server_config.db_pool, division_id, lang.into())
.await
.unwrap()
.unwrap();
let games = Game::by_division(&*server_config.db_pool, division.id, lang.into())
let games = Game::by_division(&server_config.db_pool, division.id, lang.into())
.await
.unwrap();
let iihf_stats = division.iihf_stats(&*server_config.db_pool, lang.into()).await.unwrap();
let iihf_stats = division.iihf_stats(&server_config.db_pool, lang.into()).await.unwrap();
let games_template = GameListTemplate {
locale: lang.into(),
lang_links: other_lang_urls!(lang, GameListTemplate, "id" => division_id),
@ -396,10 +371,10 @@ async fn score_for_game_html(
State(server_config): State<ServerState>,
Path((lang, game_id)): Path<(SupportedLanguage, i32)>,
) -> impl IntoResponse {
let game = Game::get(&*server_config.db_pool, game_id, lang.into())
let game = Game::get(&server_config.db_pool, game_id, lang.into())
.await
.unwrap().unwrap();
let division = Division::get(&*server_config.db_pool, game.division, lang.into())
let division = Division::get(&server_config.db_pool, game.division, lang.into())
.await
.unwrap()
.unwrap();

@ -10,21 +10,6 @@ pub trait NameTableName {
const NAME_TABLE_NAME: &'static str;
const NAME_TABLE_FK_NAME: &'static str;
}
macro_rules! impl_table_name {
($ty:ident, $tname:literal) => {
impl TableName for $ty {
const TABLE_NAME: &'static str = $tname;
}
};
}
macro_rules! impl_name_table_name {
($ty:ident, $tname:literal, $fk_name:literal) => {
impl NameTableName for $ty {
const NAME_TABLE_NAME: &'static str = $tname;
const NAME_TABLE_FK_NAME: &'static str = $fk_name;
}
};
}
#[derive(FromRow, Serialize, Deserialize, Debug, ormx::Table)]
#[ormx(table = "supported_languages", id = id, insertable, deletable)]
@ -35,111 +20,6 @@ pub struct Language {
pub short_name: String,
}
macro_rules! impl_localized_get {
($struct:ident, $func:ident) => {
impl $struct {
pub async fn get(pool: &sqlx::PgPool, id: i32, lang: crate::SupportedLanguage) -> Result<Option<Self>, sqlx::Error> {
let query = const_format::formatcp!(r#"
SELECT
{0}.*,
{1}({0}.id, $2) AS name
FROM {0}
WHERE {0}.id = $1;"#,
stringify!(<$struct as TableName>::TABLE_NAME),
stringify!($func),
);
sqlx::query_as::<_, $struct>(&query)
.bind(id)
.bind(lang)
.fetch_optional(pool)
.await
}
}
};
}
macro_rules! impl_localized_get_by_many {
($struct:ident, $by:ident) => {
impl $struct {
#[rename::rename_fn(prepend="by_")]
pub async fn $by(pool: &sqlx::PgPool, by: i32, lang: crate::SupportedLanguage) -> Result<Vec<Self>, sqlx::Error> {
let query = format!(r#"
SELECT
{0}.*,
-- if available, use the localized name,
-- if not, choose the default name (in English, CA)
-- if not, see if there is any name attached (there should be at least some language selected)
COALESCE(
localized_name.name,
default_name.name,
any_name.name
) AS name
FROM {0}
-- search for the proper, localized name
LEFT JOIN {1} localized_name
ON localized_name.{2} = {0}.id
AND localized_name.language = $2
-- also look for the name in the default language (English, CA)
LEFT JOIN {1} default_name
ON default_name.{2} = {0}.id
AND default_name.language=1
-- also look for ANY matching name in ANY locale
LEFT JOIN {1} any_name
ON any_name.{2} = {0}.id
WHERE {0}.{3} = $1;"#,
<$struct as TableName>::TABLE_NAME,
<$struct as NameTableName>::NAME_TABLE_NAME,
<$struct as NameTableName>::NAME_TABLE_FK_NAME,
stringify!($by),
);
sqlx::query_as::<_, $struct>(&query)
.bind(by)
.bind(lang)
.fetch_all(pool)
.await
}
}
};
}
macro_rules! impl_localized_all {
($struct:ident) => {
impl $struct {
pub async fn all(pool: &sqlx::PgPool, lang: crate::SupportedLanguage) -> Result<Vec<Self>, sqlx::Error> {
let query = format!(r#"
SELECT
{0}.*,
-- if available, use the localized name,
-- if not, choose the default name (in English, CA)
-- if not, see if there is any name attached (there should be at least some language selected)
COALESCE(
localized_name.name,
default_name.name,
any_name.name
) AS name
FROM {0}
-- search for the proper, localized name
LEFT JOIN {1} localized_name
ON localized_name.{2} = {0}.id
AND localized_name.language = $1
-- also look for the name in the default language (English, CA)
LEFT JOIN {1} default_name
ON default_name.{2} = {0}.id
AND default_name.language=1
-- also look for ANY matching name in ANY locale
LEFT JOIN {1} any_name
ON any_name.{2} = {0}.id;"#,
<$struct as TableName>::TABLE_NAME,
<$struct as NameTableName>::NAME_TABLE_NAME,
<$struct as NameTableName>::NAME_TABLE_FK_NAME,
);
sqlx::query_as::<_, $struct>(&query)
.bind(lang)
.fetch_all(pool)
.await
}
}
};
}
#[derive(FromRow, Serialize, Deserialize, Debug, NameTableName)]
#[table_names(table_name = "leagues", name_func = "league_name", name_table_name = "league_names", name_table_name_fk = "league")]
pub struct League {

@ -1,7 +1,6 @@
#![allow(dead_code)]
use crate::model::{Division, Game, League, Player};
use crate::languages::SupportedLanguage;
use serde::{Deserialize, Serialize};
use sqlx::FromRow;
use sqlx::PgPool;
@ -35,19 +34,19 @@ pub struct IihfStatsI64 {
pub ties: i64,
pub points: i64,
}
impl Into<IihfStatsI64> for IihfStats {
fn into(self) -> IihfStatsI64 {
impl From<IihfStats> for IihfStatsI64 {
fn from(val: IihfStats) -> Self {
IihfStatsI64 {
team_name: self.team_name.clone(),
team_id: self.team_id,
reg_wins: self.reg_wins.into(),
reg_losses: self.reg_losses.into(),
ot_wins: self.ot_wins.into(),
ot_losses: self.ot_losses.into(),
ties: self.ties.into(),
points: self.points.into(),
}
}
team_name: val.team_name.clone(),
team_id: val.team_id,
reg_wins: val.reg_wins.into(),
reg_losses: val.reg_losses.into(),
ot_wins: val.ot_wins.into(),
ot_losses: val.ot_losses.into(),
ties: val.ties.into(),
points: val.points.into(),
}
}
}
#[derive(FromRow, Deserialize, Serialize, Debug)]
@ -459,7 +458,7 @@ impl Player {
shots.period_time ASC
LIMIT 5;
"#;
sqlx::query_as::<_, GoalDetails>(&query)
sqlx::query_as::<_, GoalDetails>(query)
.bind(id)
.bind(lang)
.fetch_all(pool)

@ -12,7 +12,7 @@
<tbody>
{% for shot in shots %}
<tr>
<td>{{ shot.player_first_names|initials }} {{ shot.player_last_name }}</td>
<td>{{ shot|shot_player_name }}</td>
<td>{{ shot.team_name }}</td>
<td>{{ shot.player_number }}</td>
<td>

Loading…
Cancel
Save