convert codegen to rust

This commit is contained in:
41666 2022-11-27 14:54:52 -05:00
parent 0568024b9e
commit 2bbb36e942
12 changed files with 547 additions and 257 deletions

View file

@ -1 +0,0 @@
node_modules

14
hack/codegen/Cargo.toml Normal file
View file

@ -0,0 +1,14 @@
[package]
name = "codegen"
version = "0.1.0"
edition = "2021"
[dependencies]
reqwest = { version="0.11.13", features = ["json"] }
tera = { version = "1.17.1", default-features = false }
lazy_static = "1.4.0"
regex = "1.7.0"
futures = "0.3.25"
tokio = { version = "1.22.0", features = ["full"] }
serde = { version = "1.0.147", features = ["derive"] }
serde_json = "1.0.89"

View file

@ -1,88 +0,0 @@
import fetch from "node-fetch";
const vehicles_hashmap = async () => {
const req = await fetch("https://census.lithafalcon.cc/get/ps2/vehicle");
const resp = await req.json();
const relevantVehicles = [
"flash",
"sunderer",
"lightning",
"scythe",
"vanguard",
"prowler",
"reaver",
"mosquito",
"galaxy",
"valkyrie",
"liberator",
"ant",
"harasser",
"dervish",
"chimera",
"javelin",
"corsair",
"magrider",
];
const matcher = new RegExp(`\\b${relevantVehicles.join("|")}\\b`, "i");
return resp.vehicle_list
.reduce((acc, vehicle) => {
if (vehicle.name?.en) {
let result = vehicle.name.en.match(matcher);
if (result) {
acc.push(`("${vehicle.vehicle_id}", "${result[0].toLowerCase()}")`);
}
}
return acc;
}, [])
.filter((v) => !!v);
};
const class_hashmap = async () => {
const req = await fetch("https://census.lithafalcon.cc/get/ps2/loadout");
const resp = await req.json();
return resp.loadout_list.map(
(loadout) =>
`("${loadout.loadout_id}", "${loadout.code_name
.toLowerCase()
.replace(/\btr|nc|vs|nso\b/, "")
.trim()
.replace("defector", "max")
.replace(/ /g, "_")}")`
);
};
console.log(`// GENERATED CODE -- Do not edit. Run \`node hack/codegen/codegen.js > services/websocket/src/translators.rs\` to regenerate.
use once_cell::sync::Lazy;
use std::collections::HashMap;
static VEHICLE_TO_NAME: Lazy<HashMap<&str, &str>> = Lazy::new(|| {
HashMap::from([
${(await vehicles_hashmap()).join(",\n ")},
])
});
pub fn vehicle_to_name(vehicle_id: &str) -> String {
match VEHICLE_TO_NAME.get(&vehicle_id) {
Some(name) => name.to_string(),
None => "unknown".to_string(),
}
}
static LOADOUT_TO_CLASS: Lazy<HashMap<&str, &str>> = Lazy::new(|| {
HashMap::from([
${(await class_hashmap()).join(",\n ")},
])
});
pub fn loadout_to_class(loadout_id: &str) -> String {
match LOADOUT_TO_CLASS.get(&loadout_id) {
Some(name) => name.to_string(),
None => "unknown".to_string(),
}
}`);

View file

@ -1,144 +0,0 @@
{
"name": "saerro-codegen",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "saerro-codegen",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"node-fetch": "^3.3.0"
}
},
"node_modules/data-uri-to-buffer": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz",
"integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==",
"engines": {
"node": ">= 12"
}
},
"node_modules/fetch-blob": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
"integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/jimmywarting"
},
{
"type": "paypal",
"url": "https://paypal.me/jimmywarting"
}
],
"dependencies": {
"node-domexception": "^1.0.0",
"web-streams-polyfill": "^3.0.3"
},
"engines": {
"node": "^12.20 || >= 14.13"
}
},
"node_modules/formdata-polyfill": {
"version": "4.0.10",
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
"integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
"dependencies": {
"fetch-blob": "^3.1.2"
},
"engines": {
"node": ">=12.20.0"
}
},
"node_modules/node-domexception": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/jimmywarting"
},
{
"type": "github",
"url": "https://paypal.me/jimmywarting"
}
],
"engines": {
"node": ">=10.5.0"
}
},
"node_modules/node-fetch": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.0.tgz",
"integrity": "sha512-BKwRP/O0UvoMKp7GNdwPlObhYGB5DQqwhEDQlNKuoqwVYSxkSZCSbHjnFFmUEtwSKRPU4kNK8PbDYYitwaE3QA==",
"dependencies": {
"data-uri-to-buffer": "^4.0.0",
"fetch-blob": "^3.1.4",
"formdata-polyfill": "^4.0.10"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/node-fetch"
}
},
"node_modules/web-streams-polyfill": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz",
"integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==",
"engines": {
"node": ">= 8"
}
}
},
"dependencies": {
"data-uri-to-buffer": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz",
"integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA=="
},
"fetch-blob": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
"integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
"requires": {
"node-domexception": "^1.0.0",
"web-streams-polyfill": "^3.0.3"
}
},
"formdata-polyfill": {
"version": "4.0.10",
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
"integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
"requires": {
"fetch-blob": "^3.1.2"
}
},
"node-domexception": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ=="
},
"node-fetch": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.0.tgz",
"integrity": "sha512-BKwRP/O0UvoMKp7GNdwPlObhYGB5DQqwhEDQlNKuoqwVYSxkSZCSbHjnFFmUEtwSKRPU4kNK8PbDYYitwaE3QA==",
"requires": {
"data-uri-to-buffer": "^4.0.0",
"fetch-blob": "^3.1.4",
"formdata-polyfill": "^4.0.10"
}
},
"web-streams-polyfill": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz",
"integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q=="
}
}
}

View file

@ -1,15 +0,0 @@
{
"name": "saerro-codegen",
"version": "1.0.0",
"description": "",
"main": "codegen.js",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"node-fetch": "^3.3.0"
}
}

168
hack/codegen/src/main.rs Normal file
View file

@ -0,0 +1,168 @@
use std::process;
use lazy_static::lazy_static;
use regex::{Regex, RegexBuilder};
use serde::{Deserialize, Serialize};
use tera::Tera;
#[derive(Deserialize, Serialize, Debug)]
struct LangEn {
en: Option<String>,
}
#[derive(Deserialize, Serialize, Debug)]
struct Vehicle {
vehicle_id: String,
name: Option<LangEn>,
propulsion_type: String,
}
#[derive(Deserialize, Serialize, Debug)]
struct VehicleResponse {
vehicle_list: Vec<Vehicle>,
}
#[derive(Deserialize, Serialize, Debug)]
struct Loadout {
loadout_id: String,
code_name: String,
}
#[derive(Deserialize, Serialize, Debug)]
struct ClassesResponse {
loadout_list: Vec<Loadout>,
}
async fn translators_rs() {
lazy_static! {
static ref ALL_VEHICLES: Vec<&'static str> = vec![
"flash",
"sunderer",
"lightning",
"scythe",
"vanguard",
"prowler",
"reaver",
"mosquito",
"galaxy",
"valkyrie",
"liberator",
"ant",
"harasser",
"dervish",
"chimera",
"javelin",
"corsair",
"magrider",
];
static ref VEHICLES_RE: Regex =
RegexBuilder::new(format!("{}", ALL_VEHICLES.join("|")).as_str())
.case_insensitive(true)
.build()
.unwrap();
}
let mut tera = Tera::default();
tera.add_raw_template(
"translators.rs",
include_str!("templates/translators.rs.tera"),
)
.unwrap();
let res: VehicleResponse = reqwest::get("https://census.lithafalcon.cc/get/ps2/vehicle")
.await
.unwrap()
.json()
.await
.unwrap();
let vehicles: Vec<Vehicle> = res
.vehicle_list
.into_iter()
.filter(|item| {
// filter if no name
if item.name.is_none() || item.name.as_ref().unwrap().en.is_none() {
// println!("Skipping vehicle (no name): {:#?}", item);
return false;
}
let name = item.name.as_ref().unwrap().en.as_ref().unwrap();
if name.contains("Turret") {
// println!("Skipping vehicle (turret): {:#?}", item);
return false;
}
// filter if not in list
if !VEHICLES_RE.is_match(name.as_str()) {
// println!("Skipping vehicle (not tracked): {:#?}", item);
return false;
}
return true;
})
.map(|item| {
// match to regex
let matched = VEHICLES_RE
.find(&item.name.as_ref().unwrap().en.as_ref().unwrap())
.unwrap();
Vehicle {
vehicle_id: item.vehicle_id,
name: Some(LangEn {
en: Some(matched.as_str().to_string().to_lowercase()),
}),
propulsion_type: item.propulsion_type,
}
})
.collect();
let res: ClassesResponse = reqwest::get("https://census.lithafalcon.cc/get/ps2/loadout")
.await
.unwrap()
.json()
.await
.unwrap();
let classes: Vec<Loadout> = res
.loadout_list
.into_iter()
.map(|item| {
let new_name = item
.code_name
.replace(" ", "_")
.to_lowercase()
.replace("vs_", "")
.replace("tr_", "")
.replace("nso_", "")
.replace("nc_", "")
.replace("defector", "max");
Loadout {
loadout_id: item.loadout_id.clone(),
code_name: new_name,
}
})
.collect();
let mut context = tera::Context::new();
context.insert("vehicles", &vehicles);
context.insert("classes", &classes);
let rendered = tera.render("translators.rs", &context).unwrap();
let path_raw = format!(
"{}/../../services/websocket/src/translators.rs",
env!("CARGO_MANIFEST_DIR")
);
let path = std::path::Path::new(path_raw.as_str());
std::fs::write(path, rendered).unwrap();
process::Command::new("rustfmt")
.arg(path)
.output()
.expect("failed to execute process");
}
#[tokio::main]
async fn main() {
translators_rs().await;
}

View file

@ -0,0 +1,30 @@
// GENERATED CODE -- Do not edit. Run `cargo run --bin codegen` to regenerate.
use once_cell::sync::Lazy;
use std::collections::HashMap;
static VEHICLE_TO_NAME: Lazy<HashMap<&str, &str>> = Lazy::new(|| {
HashMap::from([
{% for vehicle in vehicles %}("{{ vehicle.vehicle_id }}", "{{ vehicle.name.en }}"),{% endfor %}
])
});
pub fn vehicle_to_name(vehicle_id: &str) -> String {
match VEHICLE_TO_NAME.get(&vehicle_id) {
Some(name) => name.to_string(),
None => "unknown".to_string(),
}
}
static LOADOUT_TO_CLASS: Lazy<HashMap<&str, &str>> = Lazy::new(|| {
HashMap::from([
{% for class in classes %}("{{ class.loadout_id }}", "{{ class.code_name }}"),{% endfor %}
])
});
pub fn loadout_to_class(loadout_id: &str) -> String {
match LOADOUT_TO_CLASS.get(&loadout_id) {
Some(name) => name.to_string(),
None => "unknown".to_string(),
}
}