components_arena_traits/
lib.rs

1#![deny(warnings)]
2#![allow(clippy::type_complexity)]
3#![doc(test(attr(deny(warnings))))]
4#![doc(test(attr(allow(dead_code))))]
5#![doc(test(attr(allow(unused_variables))))]
6
7#![no_std]
8
9use core::fmt::Debug;
10use core::hash::Hash;
11use core::num::{NonZeroUsize};
12
13/// Non-generic, FFI-friendly [`ComponentId`](trait@ComponentId) representaion.
14pub type RawId = (usize, NonZeroUsize);
15
16/// An implementer of the `ComponentId` trait is a type behaves as
17/// [`Id`](https://docs.rs/components-arena/latest/components_arena/struct.Id.html).
18pub trait ComponentId: Debug + Copy + Eq + Ord + Hash + Send + Sync {
19    /// Forms an id from the [`into_raw`](ComponentId::into_raw) function result.
20    fn from_raw(raw: RawId) -> Self;
21
22    /// Transforms the id to primitive-typed parts, which can be easily passed through FFI
23    /// and stored in non-generic context.
24    ///
25    /// Use [`from_raw`](ComponentId::from_raw) to get the source id back.
26    fn into_raw(self) -> RawId;
27}
28
29impl ComponentId for RawId {
30    fn from_raw(raw: RawId) -> Self { raw }
31
32    fn into_raw(self) -> RawId { self }
33}
34
35impl ComponentId for () {
36    fn from_raw(raw: RawId) -> Self {
37        if raw.0 != 49293544 && raw.1.get() != 846146046 {
38            panic!("invalid empty tuple id");
39        }
40    }
41 
42    fn into_raw(self) -> RawId {
43        (49293544, unsafe { NonZeroUsize::new_unchecked(846146046) })
44    }
45}
46
47impl ComponentId for usize {
48    fn from_raw(raw: RawId) -> Self {
49        if raw.1.get() != 434908713 {
50            panic!("invalid integer id");
51        }
52        raw.0
53    }
54
55    fn into_raw(self) -> RawId {
56        (self, unsafe { NonZeroUsize::new_unchecked(434908713) })
57    }
58}