fmt and clippy

This commit is contained in:
widberg 2026-03-03 01:01:23 -05:00
parent 829ee8fbad
commit ea2c3a42a4
12 changed files with 119 additions and 106 deletions

View file

@ -81,7 +81,10 @@ fn describe_data_change(old_resource: &Resource, new_resource: &Resource) -> Str
}
}
fn describe_changes(old_resource: &ResolvedResource<'_>, new_resource: &ResolvedResource<'_>) -> Vec<String> {
fn describe_changes(
old_resource: &ResolvedResource<'_>,
new_resource: &ResolvedResource<'_>,
) -> Vec<String> {
let mut changes = Vec::new();
if old_resource.link_name != new_resource.link_name {
@ -115,19 +118,21 @@ pub fn diff(
let new_resources = resolve_resources(&new_bigfile, &new_name_context, "new BigFile")?;
let added = new_resources
.iter()
.filter(|(name, _)| !old_resources.contains_key(*name))
.keys()
.filter(|name| !old_resources.contains_key(*name))
.cloned()
.collect::<Vec<_>>();
let removed = old_resources
.iter()
.filter(|(name, _)| !new_resources.contains_key(*name))
.keys()
.filter(|name| !new_resources.contains_key(*name))
.cloned()
.collect::<Vec<_>>();
let changed = old_resources
.iter()
.filter_map(|(name, old_resource)| {
let new_resource = new_resources.get(name)?;
let changes = describe_changes(old_resource, new_resource);
(!changes.is_empty()).then_some((name, old_resource, new_resource, changes))
(!changes.is_empty()).then(|| format!("{name} ({})", changes.join(", ")))
})
.collect::<Vec<_>>();
@ -138,35 +143,19 @@ pub fn diff(
return Ok(());
}
let mut wrote_section = false;
let mut sections = [("Added", added), ("Removed", removed), ("Changed", changed)]
.into_iter()
.filter(|(_, lines)| !lines.is_empty())
.peekable();
if !added.is_empty() {
writeln!(stdout, "Added:")?;
for (name, _) in &added {
writeln!(stdout, " {name}")?;
while let Some((title, lines)) = sections.next() {
writeln!(stdout, "{title}:")?;
for line in lines {
writeln!(stdout, " {line}")?;
}
wrote_section = true;
}
if !removed.is_empty() {
if wrote_section {
if sections.peek().is_some() {
writeln!(stdout)?;
}
writeln!(stdout, "Removed:")?;
for (name, _) in &removed {
writeln!(stdout, " {name}")?;
}
wrote_section = true;
}
if !changed.is_empty() {
if wrote_section {
writeln!(stdout)?;
}
writeln!(stdout, "Changed:")?;
for (name, _, _, changes) in &changed {
writeln!(stdout, " {name} ({})", changes.join(", "))?;
}
}
Ok(())

View file

@ -7,6 +7,9 @@ repository.workspace = true
edition.workspace = true
rust-version.workspace = true
[package.metadata.cargo-machete]
ignored = ["image"] # Need to depend on image to set the features for egui_extras
[dependencies]
bff = { path = "../bff" }
clap = { version = "4.5.60", features = ["derive"] }
@ -31,6 +34,20 @@ three-d = { version = "0.18.2", default-features = false, features = [
] }
three-d-asset = "0.9.2"
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
mimalloc = { version = "0.1.48", features = ["v3"] }
tokio = { version = "1.44.2", features = ["rt-multi-thread", "time"] }
# https://github.com/rust-lang/cargo/issues/1197
[target.'cfg(target_arch = "wasm32")'.dependencies]
async-std = "1.12.0"
eframe = { version = "0.29.1", features = ["persistence"] }
three-d = { version = "0.18.2", default-features = false, features = [
"egui_glow",
] }
wasm-bindgen-futures = "0.4"
web-sys = "0.3.77"
[target.'cfg(target_os = "windows")'.dependencies]
windows = { version = "0.62.2", features = [
"Win32_Foundation",
@ -41,22 +58,5 @@ windows = { version = "0.62.2", features = [
[target.'cfg(target_os = "windows")'.build-dependencies]
winres = "0.1.12"
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
mimalloc = { version = "0.1.48", features = ["v3"] }
tokio = { version = "1.44.2", features = ["rt-multi-thread", "time"] }
# https://github.com/rust-lang/cargo/issues/1197
[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen-futures = "0.4"
three-d = { version = "0.18.2", default-features = false, features = [
"egui_glow",
] }
eframe = { version = "0.29.1", features = ["persistence"] }
async-std = "1.12.0"
web-sys = "0.3.77"
[lints]
workspace = true
[package.metadata.cargo-machete]
ignored = ["image"] # Need to depend on image to set the features for egui_extras

View file

@ -5,10 +5,9 @@ use std::sync::Arc;
use bff::bigfile::BigFile;
use bff::bigfile::platforms::Platform;
use bff::bigfile::versions::Version;
use bff::class::Class;
use bff::class::{ClassNameStyle, ClassType};
use bff::class::bitmap::generic::BitmapGeneric;
use bff::class::sound::generic::SoundGeneric;
use bff::class::{Class, ClassNameStyle, ClassType};
use bff::names::{Name, NameType};
use bff::traits::{Artifact as BffArtifact, Export as BffExport, TryIntoVersionPlatform};
@ -16,8 +15,7 @@ use crate::artifact::{Artifact, BitmapFormat};
use crate::traits::export::{Export, RecursiveExport};
pub fn class_supports_preview(class_name: Name, version: &Version, platform: Platform) -> bool {
let Ok((class_type, _, _)) =
<(ClassType, ClassNameStyle, NameType)>::try_from(class_name)
let Ok((class_type, _, _)) = <(ClassType, ClassNameStyle, NameType)>::try_from(class_name)
else {
return false;
};
@ -30,8 +28,7 @@ pub fn class_supports_preview(class_name: Name, version: &Version, platform: Pla
),
ClassType::Sound => matches!(
(version, platform),
(&Version::Asobo(1, 381, 67, 9), Platform::PC)
| (&Version::Asobo(1, 6..=291, _, _), _)
(&Version::Asobo(1, 381, 67, 9), Platform::PC) | (&Version::Asobo(1, 6..=291, _, _), _)
),
ClassType::Mesh => matches!(
(version, platform),

View file

@ -8,7 +8,10 @@ pub fn play_sound(data: Arc<Vec<i16>>, sample_rate: u32, channels: u16, volume:
let Some(sample_rate) = std::num::NonZeroU32::new(sample_rate) else {
return;
};
let samples: Vec<f32> = data.iter().map(|sample| f32::from(*sample) / 32768.0).collect();
let samples: Vec<f32> = data
.iter()
.map(|sample| f32::from(*sample) / 32768.0)
.collect();
let stream = rodio::DeviceSinkBuilder::open_default_sink().unwrap();
let sink = rodio::Player::connect_new(stream.mixer());
let source = rodio::buffer::SamplesBuffer::new(channel_count, sample_rate, samples);

View file

@ -108,15 +108,30 @@ const PROG_ID: &str = "Widberg.BFF.1";
mod registry {
use std::io::{Error, ErrorKind, Result};
use windows::core::PCWSTR;
use windows::Win32::Foundation::{
ERROR_FILE_NOT_FOUND, ERROR_PATH_NOT_FOUND, ERROR_SUCCESS, WIN32_ERROR,
ERROR_FILE_NOT_FOUND,
ERROR_PATH_NOT_FOUND,
ERROR_SUCCESS,
WIN32_ERROR,
};
use windows::Win32::System::Registry::{
HKEY, KEY_READ, KEY_WRITE, REG_OPTION_NON_VOLATILE, REG_ROUTINE_FLAGS, REG_SAM_FLAGS,
REG_SZ, RRF_RT_REG_SZ, RegCloseKey, RegCreateKeyExW, RegDeleteTreeW, RegDeleteValueW,
RegGetValueW, RegOpenKeyExW, RegSetValueExW,
HKEY,
KEY_READ,
KEY_WRITE,
REG_OPTION_NON_VOLATILE,
REG_ROUTINE_FLAGS,
REG_SAM_FLAGS,
REG_SZ,
RRF_RT_REG_SZ,
RegCloseKey,
RegCreateKeyExW,
RegDeleteTreeW,
RegDeleteValueW,
RegGetValueW,
RegOpenKeyExW,
RegSetValueExW,
};
use windows::core::PCWSTR;
pub struct Key(HKEY);
@ -195,7 +210,10 @@ mod registry {
pub fn set_value_sz(key: HKEY, name: Option<&str>, value: &str) -> Result<()> {
let value = widestr(value);
let value_bytes = unsafe {
std::slice::from_raw_parts(value.as_ptr() as *const u8, std::mem::size_of_val(value.as_slice()))
std::slice::from_raw_parts(
value.as_ptr() as *const u8,
std::mem::size_of_val(value.as_slice()),
)
};
unsafe {
match name {
@ -308,6 +326,7 @@ fn change_notify() {
#[cfg(target_os = "windows")]
fn install() -> BffGuiResult<()> {
use std::env::current_exe;
use windows::Win32::System::Registry::HKEY_CURRENT_USER;
let exe_path = current_exe()?.to_str().unwrap_or_default().to_owned();
@ -335,7 +354,8 @@ fn install() -> BffGuiResult<()> {
fn uninstall() -> BffGuiResult<()> {
use windows::Win32::System::Registry::{HKEY_CURRENT_USER, KEY_READ, KEY_WRITE};
let classes = registry::open_subkey(HKEY_CURRENT_USER, "Software\\Classes", KEY_READ | KEY_WRITE)?;
let classes =
registry::open_subkey(HKEY_CURRENT_USER, "Software\\Classes", KEY_READ | KEY_WRITE)?;
registry::delete_tree_if_exists(classes.raw(), PROG_ID)?;
for extension in bff::bigfile::platforms::extensions() {

View file

@ -241,7 +241,8 @@ impl Gui {
if name_filter.is_empty() {
return true;
}
let displayed_resource = resource_display_label(res, nicknames, name_context);
let displayed_resource =
resource_display_label(res, nicknames, name_context);
if let Some(regex) = &name_filter_regex {
regex.is_match(displayed_resource.as_str())
} else {
@ -364,17 +365,17 @@ impl Gui {
ui.style_mut().spacing.item_spacing.y = 4.0;
for row in row_range {
let resource = resources.get(row).unwrap();
let resource_entry = bigfile.resources.get(resource).unwrap();
let resource_entry =
bigfile.resources.get(resource).unwrap();
let nickname = self.nicknames.get(resource);
let mut tooltip_text = format!(
"Size: {} bytes",
resource_entry.size()
);
let mut tooltip_text =
format!("Size: {} bytes", resource_entry.size());
if nickname.is_some() {
tooltip_text.push_str(
format!(
"\nOriginal name: {}",
resource.with_context(self.name_context.as_ref())
resource
.with_context(self.name_context.as_ref())
)
.as_str(),
);
@ -397,12 +398,14 @@ impl Gui {
let btn = ui
.add(
egui::Button::new(button_text)
.rounding(0.0)
.truncate()
.selected(
self.resource_name
.map_or_else(|| false, |n| resource == &n),
),
.rounding(0.0)
.truncate()
.selected(
self.resource_name.map_or_else(
|| false,
|n| resource == &n,
),
),
)
.on_hover_text_at_pointer(tooltip_text);
btn.context_menu(|ui| {

View file

@ -208,12 +208,10 @@ impl Gui {
if let Some(path) = rfd::FileDialog::new()
.add_filter(
"raw",
&[
resource
.class_name
.with_context(self.name_context.as_ref())
.to_string(),
],
&[resource
.class_name
.with_context(self.name_context.as_ref())
.to_string()],
)
.save_file()
{
@ -238,12 +236,10 @@ impl Gui {
rfd::AsyncFileDialog::new()
.add_filter(
"raw",
&[
resource
.class_name
.with_context(self.name_context.as_ref())
.to_string(),
],
&[resource
.class_name
.with_context(self.name_context.as_ref())
.to_string()],
)
.save_file()
.await
@ -271,8 +267,8 @@ impl Gui {
name.with_context(self.name_context.as_ref()),
class_name.with_context(self.name_context.as_ref())
)
.replace(':', "_")
.replace('>', "-"),
.replace(':', "_")
.replace('>', "-"),
// works fine but i don't really like this solution
);
std::fs::create_dir_all(path.parent().unwrap()).unwrap();

View file

@ -143,9 +143,8 @@ impl TryFrom<D3DFormat> for BmFormat {
impl Export for BitmapV1_381_67_09PC {
fn export(&self) -> BffResult<HashMap<OsString, Artifact>> {
let caps2 = matches!(self.link_header.bitmap_class, BitmapClass::Cubemap).then_some(
Caps2::CUBEMAP | Caps2::CUBEMAP_ALLFACES,
);
let caps2 = matches!(self.link_header.bitmap_class, BitmapClass::Cubemap)
.then_some(Caps2::CUBEMAP | Caps2::CUBEMAP_ALLFACES);
let mut dds = Dds::new_d3d(NewD3dParams {
height: self.link_header.height,
width: self.link_header.width,

View file

@ -1,9 +1,10 @@
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use crate::class::trivial_class::TrivialClass;
use crate::helpers::{BffMap, DynArray, ResourceObjectLinkHeaderV1_381_67_09PC};
use crate::names::Name;
use crate::traits::{Export, Import};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, JsonSchema)]
struct MaterialObjEntryV1_381_67_09PC {
@ -31,11 +32,10 @@ mod material_obj_entries {
use serde::ser::SerializeSeq;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use super::MaterialObjEntryV1_381_67_09PC;
use crate::helpers::{BffMap, DynArray};
use crate::names::Name;
use super::MaterialObjEntryV1_381_67_09PC;
#[derive(Serialize)]
struct MaterialObjEntryRefV1_381_67_09PC<'a> {
key: &'a Name,

View file

@ -199,7 +199,10 @@ pub fn get_forced_hash_string<S: AsRef<str>>(name: &Name, string: S) -> String {
impl Name {
pub fn with_context<'a>(&'a self, name_context: &'a NameContext) -> NameWithContext<'a> {
NameWithContext { name: self, name_context }
NameWithContext {
name: self,
name_context,
}
}
fn fmt_without_context(&self, f: &mut Formatter<'_>) -> fmt::Result {
@ -836,7 +839,9 @@ pub(crate) struct DeserializeNamesContext {
impl DeserializeNamesContext {
fn new(names: Names) -> Self {
Self { names: RefCell::new(names) }
Self {
names: RefCell::new(names),
}
}
fn into_names(self) -> Names {

View file

@ -60,14 +60,13 @@ mod tests {
},
class,
};
let resource_serialized = bff::names::json::to_string_pretty(&bff_class, &name_context)
.unwrap();
let mut roundtripped_bff_class: BffClass =
bff::names::json::from_reader(
Cursor::new(resource_serialized.into_bytes()),
&name_context,
)
.unwrap();
let resource_serialized =
bff::names::json::to_string_pretty(&bff_class, &name_context).unwrap();
let mut roundtripped_bff_class: BffClass = bff::names::json::from_reader(
Cursor::new(resource_serialized.into_bytes()),
&name_context,
)
.unwrap();
let artifacts = bff_class.class.export().unwrap_or_else(|_| HashMap::new());
let _ = roundtripped_bff_class.class.import(&artifacts);

View file

@ -102,6 +102,7 @@ flamegraph CMD *OPTIONS:
cargo flamegraph --release --bin {{ CMD }} -- {{ OPTIONS }}
# cargo-build timings (https://doc.rust-lang.org/cargo/reference/timings.html),
# rustc -Ztime-passes, and measureme summarize (https://github.com/rust-lang/measureme)
[unix]
profile-compile *TARGET:
@ -129,6 +130,7 @@ profile-compile *TARGET:
echo "Wrote compile profile artifacts to $out"
# cargo-build timings (https://doc.rust-lang.org/cargo/reference/timings.html),
# rustc -Ztime-passes, and measureme summarize (https://github.com/rust-lang/measureme)
[windows]
profile-compile *TARGET: