diff --git a/src/directb2s/mod.rs b/src/directb2s/mod.rs index 56e9d7d..a7e6e68 100644 --- a/src/directb2s/mod.rs +++ b/src/directb2s/mod.rs @@ -549,7 +549,7 @@ pub struct DirectB2SData { impl DirectB2SData { /// Replaces image data with "\[stripped\]" for the whole structure - pub fn strip_images(self: &mut Self) { + pub fn strip_images(&mut self) { self.images.backglass_image.iter_mut().for_each(|i| { i.value = "[stripped]".to_string(); }); @@ -583,7 +583,7 @@ impl DirectB2SData { }); } - fn strip_reels_images(images: &mut Vec) { + fn strip_reels_images(images: &mut [ReelsImage]) { images.iter_mut().for_each(|i| { i.image = "[stripped]".to_string(); i.intermediate_image1 = Some("[stripped]".to_string()); diff --git a/src/vpx/expanded.rs b/src/vpx/expanded.rs index 757adcf..f3f2a09 100644 --- a/src/vpx/expanded.rs +++ b/src/vpx/expanded.rs @@ -78,14 +78,14 @@ impl From for WriteError { pub fn write>(vpx: &VPX, expanded_dir: &P) -> Result<(), WriteError> { // write the version as utf8 to version.txt let version_path = expanded_dir.as_ref().join("version.txt"); - let mut version_file = File::create(&version_path)?; - let version_string = vpx.version.to_string(); + let mut version_file = File::create(version_path)?; + let version_string = vpx.version.to_u32_string(); version_file.write_all(version_string.as_bytes())?; // write the screenshot as a png if let Some(screenshot) = &vpx.info.screenshot { let screenshot_path = expanded_dir.as_ref().join("screenshot.png"); - let mut screenshot_file = std::fs::File::create(&screenshot_path)?; + let mut screenshot_file = File::create(screenshot_path)?; screenshot_file.write_all(screenshot)?; } @@ -94,21 +94,21 @@ pub fn write>(vpx: &VPX, expanded_dir: &P) -> Result<(), WriteErr // collections let collections_json_path = expanded_dir.as_ref().join("collections.json"); - let mut collections_json_file = File::create(&collections_json_path)?; + let mut collections_json_file = File::create(collections_json_path)?; let json_collections = collections_json(&vpx.collections); serde_json::to_writer_pretty(&mut collections_json_file, &json_collections)?; - write_gameitems(&vpx, expanded_dir)?; - write_images(&vpx, expanded_dir)?; - write_sounds(&vpx, expanded_dir)?; - write_fonts(&vpx, expanded_dir)?; - write_game_data(&vpx, expanded_dir)?; + write_gameitems(vpx, expanded_dir)?; + write_images(vpx, expanded_dir)?; + write_sounds(vpx, expanded_dir)?; + write_fonts(vpx, expanded_dir)?; + write_game_data(vpx, expanded_dir)?; if vpx.gamedata.materials.is_some() { - write_materials(&vpx, expanded_dir)?; + write_materials(vpx, expanded_dir)?; } else { - write_old_materials(&vpx, expanded_dir)?; - write_old_materials_physics(&vpx, expanded_dir)?; + write_old_materials(vpx, expanded_dir)?; + write_old_materials_physics(vpx, expanded_dir)?; } - write_renderprobes(&vpx, expanded_dir)?; + write_renderprobes(vpx, expanded_dir)?; Ok(()) } @@ -187,12 +187,12 @@ pub fn read>(expanded_dir: &P) -> io::Result { fn write_game_data>(vpx: &VPX, expanded_dir: &P) -> Result<(), WriteError> { let game_data_path = expanded_dir.as_ref().join("gamedata.json"); - let mut game_data_file = File::create(&game_data_path)?; + let mut game_data_file = File::create(game_data_path)?; let json = GameDataJson::from_game_data(&vpx.gamedata); serde_json::to_writer_pretty(&mut game_data_file, &json)?; // write the code to script.vbs let script_path = expanded_dir.as_ref().join("script.vbs"); - let mut script_file = File::create(&script_path)?; + let mut script_file = File::create(script_path)?; let script_bytes: Vec = vpx.gamedata.code.clone().into(); script_file.write_all(script_bytes.as_ref())?; Ok(()) @@ -200,7 +200,7 @@ fn write_game_data>(vpx: &VPX, expanded_dir: &P) -> Result<(), Wr fn read_game_data>(expanded_dir: &P) -> io::Result { let game_data_path = expanded_dir.as_ref().join("gamedata.json"); - let game_data_json: GameDataJson = read_json(&game_data_path)?; + let game_data_json: GameDataJson = read_json(game_data_path)?; let mut game_data = game_data_json.to_game_data(); // read the code from script.vbs, and find out the correct encoding let script_path = expanded_dir.as_ref().join("script.vbs"); @@ -240,7 +240,7 @@ where fn write_images>(vpx: &VPX, expanded_dir: &P) -> Result<(), WriteError> { // create an image index let images_index_path = expanded_dir.as_ref().join("images.json"); - let mut images_index_file = std::fs::File::create(&images_index_path)?; + let mut images_index_file = File::create(images_index_path)?; // on macOS/windows the file system is case-insensitive let mut image_names_lower: HashSet = HashSet::new(); let mut image_names_dupe_counter = 0; @@ -304,7 +304,7 @@ fn write_images>(vpx: &VPX, expanded_dir: &P) -> Result<(), Write fn read_images>(expanded_dir: &P) -> io::Result> { // TODO do we actually need an index? let images_index_path = expanded_dir.as_ref().join("images.json"); - let images_index_json: Vec = read_json(&images_index_path)?; + let images_index_json: Vec = read_json(images_index_path)?; let images_dir = expanded_dir.as_ref().join("images"); let images: io::Result> = images_index_json .into_iter() @@ -312,7 +312,7 @@ fn read_images>(expanded_dir: &P) -> io::Result> { let mut image = image_data_json.to_image_data(); if image.is_link() { // linked images have no data - return Ok(image); + Ok(image) } else { let file_name = image_data_json.name_dedup.as_ref().unwrap_or(&image.name); let full_file_name = format!("{}.{}", file_name, image.ext()); @@ -343,7 +343,7 @@ fn read_images>(expanded_dir: &P) -> io::Result> { fn write_sounds>(vpx: &VPX, expanded_dir: &P) -> Result<(), WriteError> { let sounds_index_path = expanded_dir.as_ref().join("sounds.json"); - let mut sounds_index_file = std::fs::File::create(&sounds_index_path)?; + let mut sounds_index_file = File::create(sounds_index_path)?; // on macOS/windows the file system is case-insensitive let mut sound_names_lower: HashSet = HashSet::new(); let mut sound_names_dupe_counter = 0; @@ -379,7 +379,7 @@ fn write_sounds>(vpx: &VPX, expanded_dir: &P) -> Result<(), Write let sound_path = sounds_dir.join(sound_file_name); if !sound_path.exists() { let mut file = File::create(sound_path)?; - file.write_all(&write_sound(&sound)) + file.write_all(&write_sound(sound)) } else { Err(io::Error::new( io::ErrorKind::AlreadyExists, @@ -408,7 +408,7 @@ fn read_sounds>(expanded_dir: &P) -> io::Result> { let mut sound = sound_data_json.to_sound_data(); let file_name = sound_data_json.name_dedup.as_ref().unwrap_or(&sound.name); let full_file_name = format!("{}.{}", file_name, sound.ext()); - let file_path = sounds_dir.join(&full_file_name); + let file_path = sounds_dir.join(full_file_name); if file_path.exists() { let mut sound_file = File::open(&file_path)?; let mut sound_data = Vec::new(); @@ -428,12 +428,9 @@ fn read_sounds>(expanded_dir: &P) -> io::Result> { fn write_fonts>(vpx: &VPX, expanded_dir: &P) -> Result<(), WriteError> { let fonts_json_path = expanded_dir.as_ref().join("fonts.json"); - let mut fonts_index_file = File::create(&fonts_json_path)?; - let fonts_index: Vec = vpx - .fonts - .iter() - .map(|font| FontDataJson::from_font_data(font)) - .collect(); + let mut fonts_index_file = File::create(fonts_json_path)?; + let fonts_index: Vec = + vpx.fonts.iter().map(FontDataJson::from_font_data).collect(); serde_json::to_writer_pretty(&mut fonts_index_file, &fonts_index)?; let fonts_dir = expanded_dir.as_ref().join("fonts"); @@ -447,7 +444,7 @@ fn write_fonts>(vpx: &VPX, expanded_dir: &P) -> Result<(), WriteE Ok(()) } -fn read_fonts>(expanded_dir: &P) -> io::Result> { +fn read_fonts>(expanded_dir: &P) -> io::Result> { let fonts_index_path = expanded_dir.as_ref().join("fonts.json"); if !fonts_index_path.exists() { println!("No fonts.json found"); @@ -485,7 +482,7 @@ fn read_fonts>(expanded_dir: &P) -> io::Result>(vpx: &VPX, expanded_dir: &P) -> Result<(), WriteError> { if let Some(materials) = &vpx.gamedata.materials { let materials_path = expanded_dir.as_ref().join("materials.json"); - let mut materials_file = File::create(&materials_path)?; + let mut materials_file = File::create(materials_path)?; let materials_index: Vec = materials.iter().map(MaterialJson::from_material).collect(); serde_json::to_writer_pretty(&mut materials_file, &materials_index)?; @@ -509,7 +506,7 @@ fn read_materials>(expanded_dir: &P) -> io::Result>(vpx: &VPX, expanded_dir: &P) -> Result<(), WriteError> { let materials_path = expanded_dir.as_ref().join("materials-old.json"); - let mut materials_file = File::create(&materials_path)?; + let mut materials_file = File::create(materials_path)?; let materials_index: Vec = vpx .gamedata .materials_old @@ -540,7 +537,7 @@ fn write_old_materials_physics>( ) -> Result<(), WriteError> { if let Some(materials) = &vpx.gamedata.materials_physics_old { let materials_path = expanded_dir.as_ref().join("materials-physics-old.json"); - let mut materials_file = File::create(&materials_path)?; + let mut materials_file = File::create(materials_path)?; let materials_index: Vec = materials .iter() .map(SavePhysicsMaterialJson::from_save_physics_material) @@ -628,7 +625,7 @@ fn write_gameitems>(vpx: &VPX, expanded_dir: &P) -> Result<(), Wr } // write the gameitems index as array with names being the type and the name let gameitems_index_path = expanded_dir.as_ref().join("gameitems.json"); - let mut gameitems_index_file = File::create(&gameitems_index_path)?; + let mut gameitems_index_file = File::create(gameitems_index_path)?; serde_json::to_writer_pretty(&mut gameitems_index_file, &files)?; Ok(()) } @@ -663,7 +660,7 @@ const MAX_VERTICES_FOR_2_BYTE_INDEX: usize = 65535; /// for primitives we write fields m3cx, m3ci and m3ay's to separate files with bin extension fn write_gameitem_binaries( - gameitems_dir: &PathBuf, + gameitems_dir: &Path, gameitem: &GameItemEnum, json_file_name: String, ) -> Result<(), WriteError> { @@ -716,17 +713,17 @@ fn write_gameitem_binaries( } fn write_animation_frames_to_objs( - gameitems_dir: &PathBuf, + gameitems_dir: &Path, gameitem: &GameItemEnum, - json_file_name: &String, - vertices: &Vec<([u8; 32], Vertex3dNoTex2)>, - indices: &Vec, + json_file_name: &str, + vertices: &[([u8; 32], Vertex3dNoTex2)], + indices: &[i64], zipped: Zip>, Iter>, ) -> Result<(), WriteError> { for (i, (compressed_frame, compressed_length)) in zipped.enumerate() { let animation_frame_vertices = read_vpx_animation_frame(compressed_frame, compressed_length); - let full_vertices = replace_vertices(&vertices, animation_frame_vertices)?; + let full_vertices = replace_vertices(vertices, animation_frame_vertices)?; // The file name of the sequence must be _x.obj where x is the frame number. let file_name_without_ext = json_file_name.trim_end_matches(".json"); let file_name = animation_frame_file_name(file_name_without_ext, i); @@ -734,7 +731,7 @@ fn write_animation_frames_to_objs( write_obj( gameitem.name().to_string(), &full_vertices, - &indices, + indices, &obj_path, ) .map_err(|e| WriteError::Io(io::Error::new(io::ErrorKind::Other, format!("{}", e))))?; @@ -743,7 +740,7 @@ fn write_animation_frames_to_objs( } fn replace_vertices( - vertices: &Vec<([u8; 32], Vertex3dNoTex2)>, + vertices: &[([u8; 32], Vertex3dNoTex2)], animation_frame_vertices: Result, WriteError>, ) -> Result, WriteError> { // combine animation_vertices with the vertices and indices from the mesh @@ -766,7 +763,7 @@ fn replace_vertices( } fn read_vpx_animation_frame( - compressed_frame: &Vec, + compressed_frame: &[u8], compressed_length: &u32, ) -> Result, WriteError> { if compressed_frame.len() != *compressed_length as usize { @@ -790,11 +787,13 @@ fn read_vpx_animation_frame( Ok(vertices) } +type ReadMesh = (Vec<([u8; 32], Vertex3dNoTex2)>, Vec); + fn read_mesh( primitive: &Primitive, - vertices_data: &Vec, - indices_data: &Vec, -) -> Result<(Vec<([u8; 32], Vertex3dNoTex2)>, Vec), WriteError> { + vertices_data: &[u8], + indices_data: &[u8], +) -> Result { let raw_vertices = decompress_data(vertices_data)?; let indices = decompress_data(indices_data)?; let calculated_num_vertices = raw_vertices.len() / BYTES_PER_VERTEX; @@ -815,13 +814,12 @@ fn read_mesh( "Indices count mismatch" ); let num_vertices = raw_vertices.len() / 32; - let bytes_per_index: u8 = if num_vertices > crate::vpx::expanded::MAX_VERTICES_FOR_2_BYTE_INDEX - { + let bytes_per_index: u8 = if num_vertices > MAX_VERTICES_FOR_2_BYTE_INDEX { 4 } else { 2 }; - let mut vertices: Vec<([u8; 32], Vertex3dNoTex2)> = Vec::with_capacity(num_vertices as usize); + let mut vertices: Vec<([u8; 32], Vertex3dNoTex2)> = Vec::with_capacity(num_vertices); let mut buff = BytesMut::from(raw_vertices.as_slice()); for _ in 0..num_vertices { @@ -965,12 +963,11 @@ fn write_vertex_index_for_vpx(bytes_per_index: u8, vpx_indices: &mut BytesMut, v } fn read_vertex_index_from_vpx(bytes_per_index: u8, buff: &mut BytesMut) -> i64 { - let index = if bytes_per_index == 2 { + if bytes_per_index == 2 { buff.get_u16_le() as i64 } else { buff.get_u32_le() as i64 - }; - index + } } fn read_gameitems>(expanded_dir: &P) -> io::Result> { @@ -1006,7 +1003,7 @@ fn read_gameitems>(expanded_dir: &P) -> io::Result io::Result { @@ -1023,7 +1020,7 @@ fn read_gameitem_binaries( primitive.compressed_indices_len = Some(compressed_indices.len() as u32); primitive.compressed_indices_data = Some(compressed_indices); } - let frame0_file_name = animation_frame_file_name(&gameitem_file_name, 0); + let frame0_file_name = animation_frame_file_name(gameitem_file_name, 0); let frame0_path = gameitems_dir.join(frame0_file_name); if frame0_path.exists() { // we have animation frames @@ -1074,7 +1071,7 @@ fn read_obj(obj_path: &PathBuf) -> io::Result<(usize, usize, Vec, Vec)> texture_coordinates, normals, indices, - } = read_obj_file(&obj_path).map_err(|e| { + } = read_obj_file(obj_path).map_err(|e| { io::Error::new( io::ErrorKind::Other, format!("Error reading obj {}: {}", obj_path.display(), e), @@ -1094,7 +1091,7 @@ fn read_obj(obj_path: &PathBuf) -> io::Result<(usize, usize, Vec, Vec)> // invert the z axis let nz = -(normal.2 as f32); - let vertext = crate::vpx::expanded::Vertex3dNoTex2 { + let vertext = Vertex3dNoTex2 { x: v.0 as f32, y: v.1 as f32, // invert the z axis @@ -1145,7 +1142,7 @@ fn read_obj_as_frame(obj_path: &PathBuf) -> io::Result> { texture_coordinates: _, normals, indices: _, - } = read_obj_file(&obj_path).map_err(|e| { + } = read_obj_file(obj_path).map_err(|e| { io::Error::new( io::ErrorKind::Other, format!("Error reading obj {}: {}", obj_path.display(), e), @@ -1174,7 +1171,7 @@ fn read_obj_as_frame(obj_path: &PathBuf) -> io::Result> { fn write_info>(vpx: &&VPX, expanded_dir: &P) -> Result<(), WriteError> { let json_path = expanded_dir.as_ref().join("info.json"); - let mut json_file = File::create(&json_path)?; + let mut json_file = File::create(json_path)?; let info = info_to_json(&vpx.info, &vpx.custominfotags); serde_json::to_writer_pretty(&mut json_file, &info)?; Ok(()) @@ -1219,7 +1216,7 @@ fn read_renderprobes>( fn write_renderprobes>(vpx: &VPX, expanded_dir: &P) -> Result<(), WriteError> { if let Some(renderprobes) = &vpx.gamedata.render_probes { let renderprobes_path = expanded_dir.as_ref().join("renderprobes.json"); - let mut renderprobes_file = File::create(&renderprobes_path)?; + let mut renderprobes_file = File::create(renderprobes_path)?; let renderprobes_index: Vec = renderprobes .iter() .map(RenderProbeJson::from_renderprobe) @@ -1313,13 +1310,13 @@ pub fn extract_directory_list(vpx_file_path: &Path) -> Vec { let mut font_path = fonts_path.clone(); font_path.push(format!("Font{}.{}.{}", index, font.name, ext)); - files.push(font_path.join("/").to_string_lossy().to_string()); + files.push(font_path.to_string_lossy().to_string()); } if fonts_size == 0 { files.push(fonts_path.to_string_lossy().to_string()); } - let entries = retrieve_entries_from_compound_file(&mut comp); + let entries = retrieve_entries_from_compound_file(&comp); entries.iter().for_each(|path| { // write the steam directly to a file let file_path = root_dir_path.join(&path[1..]); @@ -1368,7 +1365,7 @@ pub fn extract_directory_list(vpx_file_path: &Path) -> Vec { files } -fn retrieve_entries_from_compound_file(comp: &CompoundFile) -> Vec { +fn retrieve_entries_from_compound_file(comp: &CompoundFile) -> Vec { let entries: Vec = comp .walk() .filter(|entry| { @@ -1450,7 +1447,7 @@ mod test { light_sequencer.name = "test light sequencer".to_string(); let mut plunger: gameitem::plunger::Plunger = Faker.fake(); plunger.name = "test plunger".to_string(); - let mut primitive: gameitem::primitive::Primitive = Faker.fake(); + let mut primitive: Primitive = Faker.fake(); primitive.name = "test primitive".to_string(); // keep the vertices and indices empty to work around compression errors on fake data primitive.num_vertices = None; @@ -1608,12 +1605,12 @@ mod test { }, ], fonts: vec![ - font::FontData { + FontData { name: "test font".to_string(), path: "test.ttf".to_string(), data: vec![0, 1, 2, 3], }, - font::FontData { + FontData { name: "test font2".to_string(), path: "test2.ttf".to_string(), data: vec![5, 6, 7], diff --git a/src/vpx/gamedata.rs b/src/vpx/gamedata.rs index 9f1ceb9..e2ffddd 100644 --- a/src/vpx/gamedata.rs +++ b/src/vpx/gamedata.rs @@ -59,9 +59,11 @@ impl ViewSetup { mode: VIEW_LAYOUT_MODE_LEGACY, } } +} +impl Default for ViewSetup { fn default() -> Self { - ViewSetup::new() + Self::new() } } @@ -566,11 +568,8 @@ impl GameDataJson { } pub fn from_game_data(game_data: &GameData) -> GameDataJson { - let custom_colors: [ColorJson; 16] = game_data - .custom_colors - .map(|c| ColorJson::from_color(&c)) - .try_into() - .unwrap(); + let custom_colors: [ColorJson; 16] = + game_data.custom_colors.map(|c| ColorJson::from_color(&c)); GameDataJson { left: game_data.left, top: game_data.top, diff --git a/src/vpx/gameitem/bumper.rs b/src/vpx/gameitem/bumper.rs index 34ac6ce..a00dd8a 100644 --- a/src/vpx/gameitem/bumper.rs +++ b/src/vpx/gameitem/bumper.rs @@ -156,31 +156,33 @@ impl<'de> Deserialize<'de> for Bumper { D: serde::Deserializer<'de>, { let bumper_json = BumperJson::deserialize(deserializer)?; - let mut bumper = Bumper::default(); - bumper.center = bumper_json.center; - bumper.radius = bumper_json.radius; - bumper.is_timer_enabled = bumper_json.is_timer_enabled; - bumper.timer_interval = bumper_json.timer_interval; - bumper.threshold = bumper_json.threshold; - bumper.force = bumper_json.force; - bumper.scatter = bumper_json.scatter; - bumper.height_scale = bumper_json.height_scale; - bumper.ring_speed = bumper_json.ring_speed; - bumper.orientation = bumper_json.orientation; - bumper.ring_drop_offset = bumper_json.ring_drop_offset.map(f32::from); - bumper.cap_material = bumper_json.cap_material; - bumper.base_material = bumper_json.base_material; - bumper.socket_material = bumper_json.socket_material; - bumper.ring_material = bumper_json.ring_material; - bumper.surface = bumper_json.surface; - bumper.name = bumper_json.name; - bumper.is_cap_visible = bumper_json.is_cap_visible; - bumper.is_base_visible = bumper_json.is_base_visible; - bumper.is_ring_visible = bumper_json.is_ring_visible; - bumper.is_socket_visible = bumper_json.is_socket_visible; - bumper.hit_event = bumper_json.hit_event; - bumper.is_collidable = bumper_json.is_collidable; - bumper.is_reflection_enabled = bumper_json.is_reflection_enabled; + let bumper = Bumper { + center: bumper_json.center, + radius: bumper_json.radius, + is_timer_enabled: bumper_json.is_timer_enabled, + timer_interval: bumper_json.timer_interval, + threshold: bumper_json.threshold, + force: bumper_json.force, + scatter: bumper_json.scatter, + height_scale: bumper_json.height_scale, + ring_speed: bumper_json.ring_speed, + orientation: bumper_json.orientation, + ring_drop_offset: bumper_json.ring_drop_offset.map(f32::from), + cap_material: bumper_json.cap_material, + base_material: bumper_json.base_material, + socket_material: bumper_json.socket_material, + ring_material: bumper_json.ring_material, + surface: bumper_json.surface, + name: bumper_json.name, + is_cap_visible: bumper_json.is_cap_visible, + is_base_visible: bumper_json.is_base_visible, + is_ring_visible: bumper_json.is_ring_visible, + is_socket_visible: bumper_json.is_socket_visible, + hit_event: bumper_json.hit_event, + is_collidable: bumper_json.is_collidable, + is_reflection_enabled: bumper_json.is_reflection_enabled, + ..Default::default() + }; Ok(bumper) } } diff --git a/src/vpx/gameitem/flipper.rs b/src/vpx/gameitem/flipper.rs index 605895c..b6f325f 100644 --- a/src/vpx/gameitem/flipper.rs +++ b/src/vpx/gameitem/flipper.rs @@ -95,7 +95,7 @@ pub(crate) struct FlipperJson { impl FlipperJson { pub fn from_flipper(flipper: &Flipper) -> Self { Self { - center: flipper.center.clone(), + center: flipper.center, base_radius: flipper.base_radius, end_radius: flipper.end_radius, flipper_radius_max: flipper.flipper_radius_max, @@ -135,7 +135,7 @@ impl FlipperJson { pub fn to_flipper(&self) -> Flipper { Flipper { - center: self.center.clone(), + center: self.center, base_radius: self.base_radius, end_radius: self.end_radius, flipper_radius_max: self.flipper_radius_max, diff --git a/src/vpx/gameitem/font.rs b/src/vpx/gameitem/font.rs index becf047..30c5541 100644 --- a/src/vpx/gameitem/font.rs +++ b/src/vpx/gameitem/font.rs @@ -47,11 +47,11 @@ pub enum FontStyle { impl FontStyle { fn to_u8(flag: &FontStyle) -> u8 { match flag { - &FontStyle::Normal => 1 << 0, - &FontStyle::Bold => 1 << 1, - &FontStyle::Italic => 1 << 2, - &FontStyle::Underline => 1 << 3, - &FontStyle::Strikethrough => 1 << 4, + FontStyle::Normal => 1 << 0, + FontStyle::Bold => 1 << 1, + FontStyle::Italic => 1 << 2, + FontStyle::Underline => 1 << 3, + FontStyle::Strikethrough => 1 << 4, } } pub fn flags_to_styles(style: u8) -> HashSet { @@ -79,7 +79,7 @@ impl FontStyle { for flag in flags { bitflags |= Self::to_u8(flag); } - return bitflags; + bitflags } } diff --git a/src/vpx/gameitem/primitive.rs b/src/vpx/gameitem/primitive.rs index 866104b..b76146e 100644 --- a/src/vpx/gameitem/primitive.rs +++ b/src/vpx/gameitem/primitive.rs @@ -230,7 +230,7 @@ impl PrimitiveJson { add_blend: self.add_blend, use_depth_mask: self.use_depth_mask, alpha: self.alpha, - color: self.color.as_ref().map(|c| ColorJson::to_color(c)), + color: self.color.as_ref().map(ColorJson::to_color), light_map: self.light_map.clone(), reflection_probe: self.reflection_probe.clone(), reflection_strength: self.reflection_strength, diff --git a/src/vpx/image.rs b/src/vpx/image.rs index 478b990..56a69d0 100644 --- a/src/vpx/image.rs +++ b/src/vpx/image.rs @@ -137,7 +137,7 @@ impl ImageDataJson { jpeg: image_data .jpeg .as_ref() - .map(|jpeg| ImageDataJpegJson::from_image_data_jpeg(jpeg)), + .map(ImageDataJpegJson::from_image_data_jpeg), bits: image_data.bits.is_some(), name_dedup: None, } diff --git a/src/vpx/json.rs b/src/vpx/json.rs index 071eac5..bda7363 100644 --- a/src/vpx/json.rs +++ b/src/vpx/json.rs @@ -69,8 +69,7 @@ where "inf" => Ok(f32::INFINITY), "-inf" => Ok(f32::NEG_INFINITY), other => { - if other.starts_with("nan|") { - let hex_string = &other[4..]; + if let Some(hex_string) = other.strip_prefix("nan|") { let bytes = hex::decode(hex_string) .map_err(|e| serde::de::Error::custom(e.to_string()))?; let mut array = [0; 4]; @@ -116,14 +115,11 @@ mod tests { let json_nan = json!("NaN|0000c07f"); let json_other_nan = json!("NaN|ffffffff"); - assert_eq!(serde_json::to_value(&f32_num).unwrap(), json_num); - assert_eq!(serde_json::to_value(&f32_inf).unwrap(), json_inf); - assert_eq!(serde_json::to_value(&f32_n_inf).unwrap(), json_n_inf); - assert_eq!(serde_json::to_value(&f32_nan).unwrap(), json_nan); - assert_eq!( - serde_json::to_value(&f32_other_nan).unwrap(), - json_other_nan - ); + assert_eq!(serde_json::to_value(f32_num).unwrap(), json_num); + assert_eq!(serde_json::to_value(f32_inf).unwrap(), json_inf); + assert_eq!(serde_json::to_value(f32_n_inf).unwrap(), json_n_inf); + assert_eq!(serde_json::to_value(f32_nan).unwrap(), json_nan); + assert_eq!(serde_json::to_value(f32_other_nan).unwrap(), json_other_nan); assert_eq!( serde_json::from_value::(json_num).unwrap(), diff --git a/src/vpx/jsonmodel.rs b/src/vpx/jsonmodel.rs index b7bbbfc..73a0b1a 100644 --- a/src/vpx/jsonmodel.rs +++ b/src/vpx/jsonmodel.rs @@ -56,8 +56,7 @@ pub fn info_to_json( properties: table_info.properties.clone(), properties_order: custom_info_tags.clone(), }; - let json = to_value(info_json).unwrap(); - json + to_value(info_json).unwrap() } pub fn json_to_info( @@ -96,8 +95,7 @@ pub fn collections_json(collections: &[Collection]) -> serde_json::Value { }; collections_json.push(collection_json); } - let json = to_value(collections_json).unwrap(); - json + to_value(collections_json).unwrap() } pub fn json_to_collections(json: serde_json::Value) -> Result, serde_json::Error> { diff --git a/src/vpx/mod.rs b/src/vpx/mod.rs index 6640c3b..d665c74 100644 --- a/src/vpx/mod.rs +++ b/src/vpx/mod.rs @@ -17,7 +17,6 @@ use std::io::{self, Read, Seek, Write}; use std::path::MAIN_SEPARATOR_STR; use std::{ - fs, fs::File, path::{Path, PathBuf}, }; @@ -86,15 +85,15 @@ pub(crate) mod wav; #[derive(Debug, PartialEq)] pub struct VPX { /// This is mainly here to have an ordering for custom info tags - pub custominfotags: custominfotags::CustomInfoTags, // this is a bit redundant + pub custominfotags: CustomInfoTags, // this is a bit redundant pub info: TableInfo, pub version: Version, pub gamedata: GameData, - pub gameitems: Vec, - pub images: Vec, - pub sounds: Vec, - pub fonts: Vec, - pub collections: Vec, + pub gameitems: Vec, + pub images: Vec, + pub sounds: Vec, + pub fonts: Vec, + pub collections: Vec, } pub enum ExtractResult { @@ -145,7 +144,7 @@ impl VpxFile { } pub fn read_tableinfo(&mut self) -> io::Result { - tableinfo::read_tableinfo(&mut self.compound_file) + read_tableinfo(&mut self.compound_file) } pub fn read_gamedata(&mut self) -> io::Result { @@ -185,8 +184,8 @@ impl VpxFile { } /// Opens a handle to an existing VPX file -pub fn open>(path: P) -> io::Result> { - VpxFile::open(fs::File::open(path)?) +pub fn open>(path: P) -> io::Result> { + VpxFile::open(File::open(path)?) } /// Reads a VPX file from disk to memory @@ -214,6 +213,7 @@ pub fn write(path: &PathBuf, vpx: &VPX) -> io::Result<()> { .read(true) .write(true) .create(true) + .truncate(true) .open(path)?; let mut comp = CompoundFile::create(file)?; write_vpx(&mut comp, vpx) @@ -263,12 +263,13 @@ pub fn new_minimal_vpx>(vpx_file_path: P) -> io::Result<()> { .read(true) .write(true) .create(true) + .truncate(true) .open(&vpx_file_path)?; let mut comp = CompoundFile::create(file)?; write_minimal_vpx(&mut comp) } -fn write_minimal_vpx(comp: &mut CompoundFile) -> std::io::Result<()> { +fn write_minimal_vpx(comp: &mut CompoundFile) -> io::Result<()> { let table_info = TableInfo::new(); write_tableinfo(comp, &table_info)?; create_game_storage(comp)?; @@ -316,7 +317,7 @@ pub fn extractvbs( /// Imports the sidecar script into the provided `vpx` file. /// /// see also [extractvbs] -pub fn importvbs(vpx_file_path: &PathBuf, extension: Option<&str>) -> std::io::Result { +pub fn importvbs(vpx_file_path: &PathBuf, extension: Option<&str>) -> io::Result { let script_path = match extension { Some(ext) => path_for(vpx_file_path, ext), None => vbs_path_for(vpx_file_path), @@ -371,7 +372,7 @@ fn path_for(vpx_file_path: &PathBuf, extension: &str) -> PathBuf { PathBuf::from(vpx_file_path).with_extension(extension) } -fn read_mac(comp: &mut cfb::CompoundFile) -> std::io::Result> { +fn read_mac(comp: &mut CompoundFile) -> io::Result> { let mac_path = Path::new(MAIN_SEPARATOR_STR).join("GameStg").join("MAC"); if !comp.exists(&mac_path) { // fail @@ -386,10 +387,7 @@ fn read_mac(comp: &mut cfb::CompoundFile) -> std::io: Ok(mac) } -fn write_mac( - comp: &mut CompoundFile, - mac: &[u8], -) -> std::io::Result<()> { +fn write_mac(comp: &mut CompoundFile, mac: &[u8]) -> io::Result<()> { let mac_path = Path::new(MAIN_SEPARATOR_STR).join("GameStg").join("MAC"); let mut mac_stream = comp.create_stream(mac_path)?; mac_stream.write_all(mac) @@ -491,11 +489,11 @@ fn generate_mac(comp: &mut CompoundFile) -> Result, i continue; } match item.file_type { - FileType::UnstructuredBytes => { + UnstructuredBytes => { let bytes = read_bytes_at(&item.path, comp)?; hasher.update(&bytes); } - FileType::Biff => { + Biff => { // println!("reading biff: {:?}", item.path); let bytes = read_bytes_at(&item.path, comp)?; let mut biff = BiffReader::new(&bytes); @@ -580,7 +578,7 @@ pub fn extract_script>(gamedata: &GameData, vbs_path: &P) -> Resu fn read_gamedata( comp: &mut CompoundFile, version: &Version, -) -> std::io::Result { +) -> io::Result { let mut game_data_vec = Vec::new(); let game_data_path = Path::new(MAIN_SEPARATOR_STR) .join("GameStg") @@ -642,7 +640,7 @@ fn read_sounds( comp: &mut CompoundFile, gamedata: &GameData, file_version: &Version, -) -> std::io::Result> { +) -> io::Result> { (0..gamedata.sounds_size) .map(|index| { let path = Path::new(MAIN_SEPARATOR_STR) @@ -813,7 +811,7 @@ mod tests { write_minimal_vpx(&mut comp)?; let version = read_version(&mut comp)?; - let tableinfo = tableinfo::read_tableinfo(&mut comp)?; + let tableinfo = read_tableinfo(&mut comp)?; let game_data = read_gamedata(&mut comp, &version)?; assert_eq!(tableinfo, TableInfo::new()); @@ -903,6 +901,7 @@ mod tests { expected_info.table_name = Some(String::from("Visual Pinball Demo Table")); expected_info.table_save_rev = Some(String::from("10")); expected_info.table_version = Some(String::from("1.2")); + expected_info.author_website = Some(String::from("http://www.vpforums.org/")); expected_info.table_save_date = Some(String::from("Tue Jul 11 15:48:49 2023")); expected_info.table_description = Some(String::from( @@ -928,7 +927,7 @@ mod tests { fn create_minimal_vpx_and_read() -> io::Result<()> { let dir: PathBuf = testdir!(); let test_vpx_path = dir.join("test.vpx"); - let mut comp = cfb::create(&test_vpx_path)?; + let mut comp = cfb::create(test_vpx_path)?; write_minimal_vpx(&mut comp)?; comp.flush()?; let vpx = read_vpx(&mut comp)?; diff --git a/src/vpx/obj.rs b/src/vpx/obj.rs index 45b1dfd..4eaf801 100644 --- a/src/vpx/obj.rs +++ b/src/vpx/obj.rs @@ -26,8 +26,7 @@ fn obj_vpx_comment(bytes: &VpxNormalBytes) -> String { } fn obj_parse_vpx_comment(comment: &str) -> Option { - if comment.starts_with("vpx ") { - let hex = &comment[4..]; + if let Some(hex) = comment.strip_prefix("vpx ") { let bytes = hex .split_whitespace() .map(|s| u8::from_str_radix(s, 16).unwrap()) @@ -52,10 +51,10 @@ fn obj_parse_vpx_comment(comment: &str) -> Option { pub(crate) fn write_obj( name: String, vertices: &Vec<([u8; 32], Vertex3dNoTex2)>, - indices: &Vec, + indices: &[i64], obj_file_path: &PathBuf, -) -> Result<(), Box> { - let mut obj_file = File::create(&obj_file_path)?; +) -> Result<(), Box> { + let mut obj_file = File::create(obj_file_path)?; let mut writer = std::io::BufWriter::new(&mut obj_file); let obj_writer = Writer { auto_newline: true }; @@ -145,9 +144,9 @@ pub(crate) fn write_obj( for chunk in indices.chunks(3) { // obj indices are 1 based // since the z axis is inverted we have to reverse the order of the vertices - let v1 = (chunk[0] as i64) + 1; - let v2 = (chunk[1] as i64) + 1; - let v3 = (chunk[2] as i64) + 1; + let v1 = chunk[0] + 1; + let v2 = chunk[1] + 1; + let v3 = chunk[2] + 1; let face = Entity::Face { vertices: vec![ FaceVertex::new_vtn(v1, Some(v1), Some(v1)), @@ -160,10 +159,8 @@ pub(crate) fn write_obj( Ok(()) } -pub(crate) fn read_obj_file( - obj_file_path: &PathBuf, -) -> Result> { - let obj_file = File::open(&obj_file_path)?; +pub(crate) fn read_obj_file(obj_file_path: &PathBuf) -> Result> { + let obj_file = File::open(obj_file_path)?; let mut reader = std::io::BufReader::new(obj_file); read_obj(&mut reader) } @@ -172,7 +169,7 @@ pub(crate) fn read_obj(mut reader: &mut R) -> Result = Vec::new(); let mut vertices: Vec<(f64, f64, f64, Option)> = Vec::new(); let mut texture_coordinates: Vec<(f64, Option, Option)> = Vec::new(); - let mut normals: Vec<((f64, f64, f64), Option<[u8; 12]>)> = Vec::new(); + let mut normals: Vec = Vec::new(); let mut object_count = 0; let mut previous_comment: Option = None; let mut name = String::new(); @@ -235,13 +232,15 @@ pub(crate) fn read_obj(mut reader: &mut R) -> Result); + #[derive(Debug, PartialEq)] pub(crate) struct ObjData { pub name: String, pub vertices: Vec<(f64, f64, f64, Option)>, pub texture_coordinates: Vec<(f64, Option, Option)>, - pub normals: Vec<((f64, f64, f64), Option)>, - /// indices can also be relative so they can be negative + pub normals: Vec, + /// Indices can also be relative, so they can be negative /// stored by three as vertex, texture, normal are all the same /// /// Here they are 0-based, in obj files they are 1-based @@ -304,8 +303,8 @@ f 1/1/1 1/1/1 1/1/1 assert_eq!(read_data.vertices, expected.vertices); assert_eq!(read_data.texture_coordinates, expected.texture_coordinates); assert_eq!( - read_data.normals.get(0).unwrap().1, - expected.normals.get(0).unwrap().1 + read_data.normals.first().unwrap().1, + expected.normals.first().unwrap().1 ); assert_eq!(read_data.indices, expected.indices); Ok(()) diff --git a/src/vpx/version.rs b/src/vpx/version.rs index fc94548..4e7d9f4 100644 --- a/src/vpx/version.rs +++ b/src/vpx/version.rs @@ -20,7 +20,7 @@ impl Version { Ok(Version(version)) } - pub fn to_string(&self) -> String { + pub fn to_u32_string(&self) -> String { self.0.to_string() } } @@ -49,7 +49,7 @@ impl From for u32 { val.0 } } -impl cmp::PartialOrd for Version { +impl PartialOrd for Version { fn partial_cmp(&self, other: &Self) -> Option { self.0.partial_cmp(&other.0) } @@ -108,7 +108,7 @@ mod test { #[test] pub fn test_to_string_parse() -> TestResult { let version = Version::new(1080); - let version_string = version.to_string(); + let version_string = version.to_u32_string(); let parsed_version = Version::parse(&version_string)?; assert_eq!(version, parsed_version); Ok(()) @@ -118,7 +118,7 @@ mod test { pub fn test_parse_to_string() -> TestResult { let version_string = "1080"; let parsed_version = Version::parse(version_string)?; - let version_string2 = parsed_version.to_string(); + let version_string2 = parsed_version.to_u32_string(); assert_eq!(version_string, version_string2); Ok(()) }