1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
use paste::paste;
use serde::{Deserialize, Serialize};
use ulid::Ulid;

#[macro_export]
macro_rules! procedural_storage_handle_definitions {
    ($macro_to_instantiate:ident) => {
        // Handle names must be in snake_case.
        $macro_to_instantiate!(mesh, texture, sampler, material);
    };
}

macro_rules! make_procedural_storage_handles {
    ($($name:ident),*) => { paste!{$(
        #[derive(
            Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Serialize, Deserialize,
        )]
        pub struct [<Procedural $name:camel Handle>](Ulid);

        impl [<Procedural $name:camel Handle>] {
            pub fn as_u128(&self) -> u128 {
                self.0. 0
            }
        }

        impl Default for [<Procedural $name:camel Handle>] {
            fn default() -> Self {
                Self(Ulid::nil())
            }
        }

        impl std::fmt::Display for [<Procedural $name:camel Handle>] {
            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
                write!(f, concat!(stringify!([<Procedural $name:camel Handle>]), "({})"), self.0)
            }
        }

        impl From<Ulid> for [<Procedural $name:camel Handle>] {
            fn from(ulid: Ulid) -> Self {
                Self(ulid)
            }
        }

        impl From<[<Procedural $name:camel Handle>]> for Ulid {
            fn from(handle: [<Procedural $name:camel Handle>]) -> Self {
                handle.0
            }
        }
    )*}};
}

procedural_storage_handle_definitions!(make_procedural_storage_handles);