0.1.0-0-pre.9

This commit is contained in:
2026-09-16 10:01:13 +02:00
parent 00808ea5a6
commit 4fcbdf316d
22 changed files with 507 additions and 18 deletions

View File

@@ -0,0 +1,45 @@
// file: crates/common/game-assets-lib/src/resolver.rs
// version: 1
/// Resolves logical asset URIs against separate common and game roots.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct AssetResolver {
common_root: std::path::PathBuf,
game_root: std::path::PathBuf,
}
impl AssetResolver {
/// Creates a resolver from physical common and game asset roots.
#[must_use]
pub fn new(common_root: impl Into<std::path::PathBuf>, game_root: impl Into<std::path::PathBuf>) -> Self {
return Self { common_root: common_root.into(), game_root: game_root.into() };
}
/// Resolves `common://` or `game://` URI into a physical path without touching the filesystem.
pub fn resolve(&self, uri: &str) -> Result<std::path::PathBuf, crate::AssetError> {
let (root, relative) = if let Some(relative) = uri.strip_prefix("common://") {
(&self.common_root, relative)
} else if let Some(relative) = uri.strip_prefix("game://") {
(&self.game_root, relative)
} else {
return Err(crate::AssetError::UnsupportedScheme);
};
if relative.is_empty() {
return Err(crate::AssetError::EmptyPath);
}
let relative_path = std::path::Path::new(relative);
if relative_path.is_absolute() || relative.contains('\\') {
return Err(crate::AssetError::InvalidPath);
}
for component in relative_path.components() {
if !matches!(component, std::path::Component::Normal(_)) {
return Err(crate::AssetError::InvalidPath);
}
}
return Ok(root.join(relative_path));
}
}
#[cfg(test)]
#[path = "../unit_tests/resolver.rs"]
mod tests;