1use std::{
2 ffi::OsStr,
3 hash::{Hash, Hasher},
4 path::{Path, PathBuf},
5};
6
7use crate::{AssetTypeId, AssetUuid};
8
9pub fn make_array<A, T>(slice: &[T]) -> A
10where
11 A: Sized + Default + AsMut<[T]>,
12 T: Copy,
13{
14 let mut a = Default::default();
15 <A as AsMut<[T]>>::as_mut(&mut a).copy_from_slice(slice);
16 a
17}
18
19pub fn type_from_slice(slice: &[u8]) -> Option<AssetTypeId> {
20 uuid_from_slice(slice).map(|uuid| AssetTypeId(uuid.0))
21}
22
23pub fn uuid_from_slice(slice: &[u8]) -> Option<AssetUuid> {
24 const BYTES_LEN: usize = 16;
25
26 let len = slice.len();
27
28 if len != BYTES_LEN {
29 return None;
30 }
31
32 let mut bytes: uuid::Bytes = [0; 16];
33 bytes.copy_from_slice(slice);
34 Some(AssetUuid(bytes))
35}
36
37pub fn to_meta_path(p: &Path) -> PathBuf {
38 p.with_file_name(OsStr::new(
39 &(p.file_name().unwrap().to_str().unwrap().to_owned() + ".meta"),
40 ))
41}
42
43pub fn calc_import_artifact_hash<T, V>(id: &AssetUuid, import_hash: u64, dep_list: T) -> u64
44where
45 V: std::borrow::Borrow<AssetUuid>,
46 T: IntoIterator<Item = V>,
47{
48 let mut hasher = ::std::collections::hash_map::DefaultHasher::new();
49 import_hash.hash(&mut hasher);
50 (*id).hash(&mut hasher);
51 let mut deps: Vec<_> = dep_list.into_iter().collect();
52 deps.sort_by_key(|dep| *dep.borrow());
53 deps.dedup_by_key(|dep| *dep.borrow());
54 for dep in &deps {
55 dep.borrow().hash(&mut hasher);
56 }
57 hasher.finish()
58}
59
60#[cfg(feature = "path_utils")]
61pub fn canonicalize_path(path: &Path) -> PathBuf {
62 use path_slash::{PathBufExt, PathExt};
63 let cleaned_path = PathBuf::from_slash(path_clean::clean(&path.to_slash_lossy()));
64 PathBuf::from(dunce::simplified(&cleaned_path))
65}