bevy/crates/bevy_asset/src/path.rs

190 lines
4.8 KiB
Rust
Raw Normal View History

use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
use bevy_utils::AHasher;
use serde::{Deserialize, Serialize};
use std::{
borrow::Cow,
hash::{Hash, Hasher},
path::{Path, PathBuf},
};
/// Represents a path to an asset in the file system.
#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize)]
pub struct AssetPath<'a> {
path: Cow<'a, Path>,
label: Option<Cow<'a, str>>,
}
impl<'a> AssetPath<'a> {
/// Creates a new asset path using borrowed information.
#[inline]
pub fn new_ref(path: &'a Path, label: Option<&'a str>) -> AssetPath<'a> {
AssetPath {
path: Cow::Borrowed(path),
label: label.map(Cow::Borrowed),
}
}
/// Creates a new asset path.
#[inline]
pub fn new(path: PathBuf, label: Option<String>) -> AssetPath<'a> {
AssetPath {
path: Cow::Owned(path),
label: label.map(Cow::Owned),
}
}
/// Constructs an identifier from this asset path.
#[inline]
pub fn get_id(&self) -> AssetPathId {
AssetPathId::from(self)
}
/// Gets the sub-asset label.
#[inline]
pub fn label(&self) -> Option<&str> {
self.label.as_ref().map(|label| label.as_ref())
}
/// Gets the path to the asset in the filesystem.
#[inline]
pub fn path(&self) -> &Path {
&self.path
}
/// Converts the borrowed path data to owned.
#[inline]
pub fn to_owned(&self) -> AssetPath<'static> {
AssetPath {
path: Cow::Owned(self.path.to_path_buf()),
label: self
.label
.as_ref()
.map(|value| Cow::Owned(value.to_string())),
}
}
}
/// An unique identifier to an asset path.
#[derive(
2020-11-28 00:39:59 +00:00
Debug, Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, Serialize, Deserialize, Reflect,
)]
2020-11-28 00:39:59 +00:00
#[reflect_value(PartialEq, Hash, Serialize, Deserialize)]
pub struct AssetPathId(SourcePathId, LabelId);
/// An unique identifier to the source path of an asset.
#[derive(
2020-11-28 00:39:59 +00:00
Debug, Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, Serialize, Deserialize, Reflect,
)]
2020-11-28 00:39:59 +00:00
#[reflect_value(PartialEq, Hash, Serialize, Deserialize)]
pub struct SourcePathId(u64);
/// An unique identifier to a sub-asset label.
#[derive(
2020-11-28 00:39:59 +00:00
Debug, Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, Serialize, Deserialize, Reflect,
)]
2020-11-28 00:39:59 +00:00
#[reflect_value(PartialEq, Hash, Serialize, Deserialize)]
pub struct LabelId(u64);
impl<'a> From<&'a Path> for SourcePathId {
fn from(value: &'a Path) -> Self {
let mut hasher = get_hasher();
value.hash(&mut hasher);
SourcePathId(hasher.finish())
}
}
impl From<AssetPathId> for SourcePathId {
fn from(id: AssetPathId) -> Self {
id.source_path_id()
}
}
impl<'a> From<AssetPath<'a>> for SourcePathId {
fn from(path: AssetPath) -> Self {
AssetPathId::from(path).source_path_id()
}
}
impl<'a> From<Option<&'a str>> for LabelId {
fn from(value: Option<&'a str>) -> Self {
let mut hasher = get_hasher();
value.hash(&mut hasher);
LabelId(hasher.finish())
}
}
impl AssetPathId {
/// Gets the id of the source path.
pub fn source_path_id(&self) -> SourcePathId {
self.0
}
/// Gets the id of the sub-asset label.
pub fn label_id(&self) -> LabelId {
self.1
}
}
/// this hasher provides consistent results across runs
pub(crate) fn get_hasher() -> AHasher {
AHasher::new_with_keys(42, 23)
}
impl<'a, T> From<T> for AssetPathId
where
T: Into<AssetPath<'a>>,
{
fn from(value: T) -> Self {
let asset_path: AssetPath = value.into();
AssetPathId(
SourcePathId::from(asset_path.path()),
LabelId::from(asset_path.label()),
)
}
}
impl<'a, 'b> From<&'a AssetPath<'b>> for AssetPathId {
fn from(asset_path: &'a AssetPath<'b>) -> Self {
AssetPathId(
SourcePathId::from(asset_path.path()),
LabelId::from(asset_path.label()),
)
}
}
impl<'a> From<&'a str> for AssetPath<'a> {
fn from(asset_path: &'a str) -> Self {
let mut parts = asset_path.splitn(2, '#');
let path = Path::new(parts.next().expect("Path must be set."));
let label = parts.next();
AssetPath {
path: Cow::Borrowed(path),
label: label.map(Cow::Borrowed),
}
}
}
impl<'a> From<&'a String> for AssetPath<'a> {
fn from(asset_path: &'a String) -> Self {
asset_path.as_str().into()
}
}
impl<'a> From<&'a Path> for AssetPath<'a> {
fn from(path: &'a Path) -> Self {
AssetPath {
path: Cow::Borrowed(path),
label: None,
}
}
}
impl<'a> From<PathBuf> for AssetPath<'a> {
fn from(path: PathBuf) -> Self {
AssetPath {
path: Cow::Owned(path),
label: None,
}
}
}