diff --git a/Cargo.toml b/Cargo.toml index b6dce372..923830b0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,6 +26,7 @@ anyhow = "1.0" thiserror = "1.0" paste = "1.0" derive_more = "0.99.17" +path-clean = "1.0.1" [dev-dependencies] bevy = "0.11" diff --git a/src/assets/ldtk_project.rs b/src/assets/ldtk_project.rs index dd842d0e..63a5439c 100644 --- a/src/assets/ldtk_project.rs +++ b/src/assets/ldtk_project.rs @@ -14,6 +14,7 @@ use bevy::{ }; use derive_getters::Getters; use derive_more::From; +use path_clean::PathClean; use std::collections::HashMap; use thiserror::Error; @@ -24,7 +25,12 @@ use crate::assets::InternalLevels; use crate::assets::{ExternalLevelMetadata, ExternalLevels}; fn ldtk_path_to_asset_path<'b>(ldtk_path: &Path, rel_path: &str) -> AssetPath<'b> { - ldtk_path.parent().unwrap().join(Path::new(rel_path)).into() + ldtk_path + .parent() + .unwrap() + .join(Path::new(rel_path)) + .clean() + .into() } /// Main asset for loading LDtk project data. @@ -365,6 +371,49 @@ mod tests { } } + #[test] + fn normalizes_asset_paths() { + let resolve_path = |project_path, rel_path| { + let asset_path = ldtk_path_to_asset_path(Path::new(project_path), rel_path); + asset_path.path().to_owned() + }; + + assert_eq!( + resolve_path("project.ldtk", "images/tiles.png"), + Path::new("images/tiles.png") + ); + assert_eq!( + resolve_path("projects/sub/project.ldtk", "../images/tiles.png"), + Path::new("projects/images/tiles.png") + ); + assert_eq!( + resolve_path("projects/sub/project.ldtk", "../../tiles.png"), + Path::new("tiles.png") + ); + } + + #[cfg(target_os = "windows")] + #[test] + fn normalizes_windows_asset_paths() { + let resolve_path = |project_path, rel_path| { + let asset_path = ldtk_path_to_asset_path(Path::new(project_path), rel_path); + asset_path.path().to_owned() + }; + + assert_eq!( + resolve_path("projects\\sub/project.ldtk", "../images/tiles.png"), + Path::new("projects/images/tiles.png") + ); + assert_eq!( + resolve_path("projects\\sub/project.ldtk", "../../images/tiles.png"), + Path::new("images/tiles.png") + ); + assert_eq!( + resolve_path("projects/sub\\project.ldtk", "../../tiles.png"), + Path::new("tiles.png") + ); + } + #[cfg(feature = "internal_levels")] mod internal_levels { use crate::{