Skip to content
This repository has been archived by the owner on Dec 22, 2023. It is now read-only.

Commit

Permalink
♻️ Get rid of phf and just use matches
Browse files Browse the repository at this point in the history
  • Loading branch information
eigenein committed Jul 24, 2023
1 parent e6b07c4 commit d134fd2
Show file tree
Hide file tree
Showing 10 changed files with 6,227 additions and 4,987 deletions.
49 changes: 0 additions & 49 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ maud = { version = "0.25.0", features = ["axum"] }
moka = { version = "0.11.2", default-features = false, features = ["future", "atomic64"] }
mongodb = { version = "2.6.0", features = ["tracing", "bson-uuid-1", "bson-chrono-0_4"] }
monostate = "0.1.9"
phf = { version = "0.11.2", features = ["macros"] }
quick-xml = { version = "0.29.0", features = ["serialize"] }
rayon = "1.7.0"
reqwest = { version = "0.11.18", default-features = false, features = ["gzip", "json", "rustls-tls"] }
Expand Down
5 changes: 2 additions & 3 deletions src/db/votes.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use futures::TryStreamExt;
use itertools::Itertools;
use mongodb::{
bson::{doc, to_document},
options::UpdateOptions,
Expand All @@ -9,7 +8,7 @@ use mongodb::{
use crate::{
models::{AccountId, TankId, Vote, VoteId},
prelude::*,
tankopedia::vendored::TANKOPEDIA,
tankopedia::vendored::ALL_TANK_IDS,
};

#[derive(Clone)]
Expand Down Expand Up @@ -59,7 +58,7 @@ impl Votes {

/// Iterate over **all** the votes. Only the **tankopedia vehicles** are taken into account.
pub async fn iter_all(&self) -> Result<Cursor<Vote>> {
let filter = doc! { "_id.tid": { "$in": TANKOPEDIA.keys().map(|tank_id| *tank_id as u32).collect_vec() } };
let filter = doc! { "_id.tid": { "$in": ALL_TANK_IDS.as_slice() } };
self.0.find(filter, None).await.context("failed to query all votes")
}

Expand Down
129 changes: 95 additions & 34 deletions src/tankopedia/bundler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ use image::{DynamicImage, ImageFormat};
use img_parts::webp::WebP;
use reqwest::{Client, StatusCode};
use serde::Deserialize;
use tokio::task::spawn_blocking;

use crate::{models::VehicleAvailability, prelude::*, tankopedia::dvpl::Dvpl};

Expand Down Expand Up @@ -48,17 +47,12 @@ impl BundleTankopedia {
pub async fn run(self) -> Result {
let client = Client::new();

let translations: HashMap<String, String> = {
let path = self.data_path.join("Strings").join("en.yaml.dvpl");
serde_yaml::from_reader(Dvpl::read(path).await?.into_reader().await?)?
};
let vehicles_path = self.data_path.join("XML").join("item_defs").join("vehicles");
let parameters_path = self.data_path.join("3d").join("Tanks").join("Parameters");

static NATIONS: [&str; 9] = [
"germany", "usa", "china", "france", "uk", "japan", "other", "european", "ussr",
];

let vehicles_path = self.data_path.join("XML").join("item_defs").join("vehicles");
let parameters_path = self.data_path.join("3d").join("Tanks").join("Parameters");
let mut vehicles: Vec<_> = stream::iter(NATIONS)
.then(|nation| {
self.load_nation(vehicles_path.join(nation), parameters_path.join(nation), &client)
Expand All @@ -70,6 +64,11 @@ impl BundleTankopedia {
// Sort the vehicles for pretty Git diffs when new vehicles are added.
vehicles.sort_unstable_by_key(|(_, vehicle, _)| vehicle.tank_id);

let translations: HashMap<String, String> = {
let path = self.data_path.join("Strings").join("en.yaml.dvpl");
serde_yaml::from_reader(Dvpl::read(path).await?.into_reader().await?)?
};

let mut module = File::options()
.write(true)
.create(true)
Expand All @@ -78,21 +77,88 @@ impl BundleTankopedia {
let vendored_path = Path::new("src").join("tankopedia").join("vendored");
create_dir_all(&vendored_path)?;

if !self.skip_images {
Self::save_images(&vendored_path, &vehicles)?;
}

writeln!(
&mut module,
"//! Auto-generated tankopedia, to update run `blitz-tanks bundle-tankopedia`.",
)?;
writeln!(&mut module)?;
writeln!(&mut module, "use phf::{{phf_map, Map}};")?;
writeln!(&mut module)?;
writeln!(
&mut module,
"use crate::models::{{TankId, Vehicle, VehicleAvailability::*, VehicleType::*}};"
)?;
writeln!(&mut module)?;
writeln!(&mut module, "pub static TANKOPEDIA: Map<u16, Vehicle> = phf_map! {{")?;
Self::write_all_tank_ids(&mut module, &vehicles)?;
writeln!(&mut module)?;
Self::write_is_known_tank_id_function(&mut module, &vehicles)?;
writeln!(&mut module)?;
Self::write_get_vehicle_function(&mut module, &vehicles, &translations)?;

Ok(())
}

#[instrument(skip_all)]
fn save_images(
vendored_path: &Path,
vehicles: &[(VehicleXmlDetails, VehicleJsonDetails, DynamicImage)],
) -> Result {
info!("📦 Saving images…");
for (xml_details, json_details, image) in vehicles {
info!(json_details.tank_id, json_details.user_string, "📦 Saving…");
info!(json_details.tank_id, xml_details.user_string_key);
let path = vendored_path.join(json_details.tank_id.to_string()).with_extension("webp");
image.save(path)?;
}
Ok(())
}

#[instrument(skip_all)]
fn write_all_tank_ids(
mut writer: impl Write,
vehicles: &[(VehicleXmlDetails, VehicleJsonDetails, DynamicImage)],
) -> Result {
info!("📦 Writing tank IDs…");
writeln!(writer, "pub static ALL_TANK_IDS: [TankId; {}] = [", vehicles.len())?;
for (_, json_details, _) in vehicles {
writeln!(writer, " TankId({}),", json_details.tank_id)?;
}
writeln!(writer, "];")?;
Ok(())
}

#[instrument(skip_all)]
fn write_is_known_tank_id_function(
mut writer: impl Write,
vehicles: &[(VehicleXmlDetails, VehicleJsonDetails, DynamicImage)],
) -> Result {
info!("📦 Writing `is_known_tank_id()`…");
writeln!(writer, "pub const fn is_known_tank_id(tank_id: TankId) -> bool {{")?;
writeln!(writer, " matches!(")?;
writeln!(writer, " tank_id,")?;
for (i, (_, json_details, _)) in vehicles.iter().enumerate() {
if i != 0 {
writeln!(writer, " | TankId({})", json_details.tank_id)?;
} else {
writeln!(writer, " TankId({})", json_details.tank_id)?;
}
}
writeln!(writer, " )")?;
writeln!(writer, "}}")?;
Ok(())
}

#[instrument(skip_all)]
fn write_get_vehicle_function(
mut writer: impl Write,
vehicles: &[(VehicleXmlDetails, VehicleJsonDetails, DynamicImage)],
translations: &HashMap<String, String>,
) -> Result {
info!("📦 Writing `get_vehicle()`…");
writeln!(writer, "pub const fn get_vehicle(tank_id: TankId) -> Option<Vehicle> {{")?;
writeln!(writer, " match tank_id {{")?;
for (xml_details, json_details, _) in vehicles {
let short_user_string_key = xml_details.short_user_string_key();
let name = translations
// Take the short name from the client.
Expand All @@ -102,31 +168,26 @@ impl BundleTankopedia {
// Fall back to the long name from the API.
.unwrap_or(&json_details.user_string);

writeln!(&mut module, " {}_u16 => Vehicle {{", json_details.tank_id)?;
writeln!(&mut module, " tank_id: TankId({:?}),", json_details.tank_id)?;
writeln!(&mut module, " name: {:?},", name)?;
writeln!(&mut module, " tier: {:?},", json_details.tier)?;
writeln!(&mut module, " type_: {:?},", json_details.type_)?;
writeln!(writer, " TankId({}) => Some(Vehicle {{", json_details.tank_id)?;
writeln!(writer, " tank_id: TankId({:?}),", json_details.tank_id)?;
writeln!(writer, " name: {:?},", name)?;
writeln!(writer, " tier: {:?},", json_details.tier)?;
writeln!(writer, " type_: {:?},", json_details.type_)?;
writeln!(
&mut module,
" availability: {:?},",
VehicleAvailability::from(&json_details),
writer,
" availability: {:?},",
VehicleAvailability::from(json_details),
)?;
writeln!(
&mut module,
r#" image_content: include_bytes!("vendored/{}.webp"),"#,
writer,
r#" image_content: include_bytes!("vendored/{}.webp"),"#,
json_details.tank_id
)?;
writeln!(&mut module, r#" }},"#)?;

if !self.skip_images {
let path =
vendored_path.join(json_details.tank_id.to_string()).with_extension("webp");
spawn_blocking(move || image.save(path)).await??;
}
writeln!(writer, r#" }}),"#)?;
}
writeln!(&mut module, "}};")?;

writeln!(writer, " _ => None,")?;
writeln!(writer, " }}")?;
writeln!(writer, "}}")?;
Ok(())
}

Expand Down Expand Up @@ -207,7 +268,7 @@ impl BundleTankopedia {
.await?;
let parameters: VehicleParameters =
serde_yaml::from_reader(dvpl.into_reader().await?)?;
self.extract_vehicle_icon(&parameters.resources_path.big_icon_path).await?
self.extract_vehicle_icon(&parameters.resource_paths.big_icon_path).await?
}
};
let Some(image) = image else {
Expand Down Expand Up @@ -364,11 +425,11 @@ enum VehicleType {
#[derive(Deserialize)]
struct VehicleParameters {
#[serde(rename = "resourcesPath")]
resources_path: ResourcesPath,
resource_paths: ResourcePaths,
}

#[derive(Deserialize)]
struct ResourcesPath {
struct ResourcePaths {
/// Path to the icon resource, for example: `~res:/Gfx/UI/BigTankIcons/ussr-KV_1s_BP`.
#[serde(rename = "bigIconPath")]
big_icon_path: String,
Expand Down
Loading

0 comments on commit d134fd2

Please sign in to comment.