use crate::error;
use crate::error::Error;
use crate::v2_0::vertex::{VertexIndex, VertexRef};
use std::fmt::{Debug, Display, Formatter};
use std::hash::Hash;
pub(crate) trait ResourceId:
Copy + Debug + Default + Display + PartialEq + Eq + PartialOrd + Ord + Hash
{
fn new(index: u32, generation: u16) -> Self;
fn index(&self) -> u32;
fn generation(&self) -> u16;
#[must_use]
fn max_index() -> u32 {
u32::MAX
}
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub(crate) struct ResourceId32 {
index: u32,
generation: u16,
}
impl ResourceId32 {
#[must_use]
pub(crate) fn new(index: u32, generation: u16) -> Self {
Self { index, generation }
}
#[must_use]
pub(crate) fn index(self) -> u32 {
self.index
}
#[must_use]
pub(crate) fn generation(self) -> u16 {
self.generation
}
#[allow(dead_code)]
pub(crate) fn to_vertex_index<T: VertexRef>(self) -> error::Result<VertexIndex<T>> {
T::from_u32(self.index)
.map(|v| VertexIndex::new(v))
.ok_or(Error::IndexConversion {
source_type: "u32".to_string(),
target_type: std::any::type_name::<T>().to_string(),
value: self.index.to_string(),
})
}
}
impl Display for ResourceId32 {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "index: {}, generation: {}", self.index, self.generation)
}
}
impl ResourceId for ResourceId32 {
fn new(index: u32, generation: u16) -> Self {
ResourceId32 { index, generation }
}
fn index(&self) -> u32 {
self.index
}
fn generation(&self) -> u16 {
self.generation
}
}
#[inline]
pub(crate) fn usize_to_resource_index<RR: ResourceId>(index: usize) -> Option<u32> {
let index_u32 = u32::try_from(index).ok()?;
if index_u32 <= RR::max_index() {
Some(index_u32)
} else {
None
}
}
#[test]
fn test_conversion() {
let vi: VertexIndex<u16> = ResourceId32::new(1, 0).to_vertex_index().unwrap();
assert_eq!(vi.value(), 1u16);
}