bevy/crates/bevy_asset/src/path.rs
Joshua J. Bouw 9f4c8b1b9a
Fix errors and panics to typical Rust conventions (#968)
Fix errors and panics to typical Rust conventions
2020-12-02 11:31:16 -08:00

171 lines
4.1 KiB
Rust

use bevy_reflect::{Reflect, ReflectDeserialize};
use bevy_utils::AHasher;
use serde::{Deserialize, Serialize};
use std::{
borrow::Cow,
hash::{Hash, Hasher},
path::{Path, PathBuf},
};
#[derive(Debug, Hash, Clone, Serialize, Deserialize)]
pub struct AssetPath<'a> {
path: Cow<'a, Path>,
label: Option<Cow<'a, str>>,
}
impl<'a> AssetPath<'a> {
#[inline]
pub fn new_ref(path: &'a Path, label: Option<&'a str>) -> AssetPath<'a> {
AssetPath {
path: Cow::Borrowed(path),
label: label.map(|val| Cow::Borrowed(val)),
}
}
#[inline]
pub fn new(path: PathBuf, label: Option<String>) -> AssetPath<'a> {
AssetPath {
path: Cow::Owned(path),
label: label.map(Cow::Owned),
}
}
#[inline]
pub fn get_id(&self) -> AssetPathId {
AssetPathId::from(self)
}
#[inline]
pub fn label(&self) -> Option<&str> {
self.label.as_ref().map(|label| label.as_ref())
}
#[inline]
pub fn path(&self) -> &Path {
&self.path
}
#[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())),
}
}
}
#[derive(
Debug, Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, Serialize, Deserialize, Reflect,
)]
#[reflect_value(PartialEq, Hash, Serialize, Deserialize)]
pub struct AssetPathId(SourcePathId, LabelId);
#[derive(
Debug, Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, Serialize, Deserialize, Reflect,
)]
#[reflect_value(PartialEq, Hash, Serialize, Deserialize)]
pub struct SourcePathId(u64);
#[derive(
Debug, Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, Serialize, Deserialize, Reflect,
)]
#[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 {
pub fn source_path_id(&self) -> SourcePathId {
self.0
}
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.split('#');
let path = Path::new(parts.next().expect("Path must be set."));
let label = parts.next();
AssetPath {
path: Cow::Borrowed(path),
label: label.map(|label| Cow::Borrowed(label)),
}
}
}
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,
}
}
}