1use crate::Arena;
2use crate::Index;
3use crate::ArenaResult;
4
5use std::fmt;
6use std::cmp;
7
8use vec_cell::{ElementRef, ElementRefMut};
9
10pub trait Handle<'arena>
11where
12 Self: 'arena,
13{
14 type Type;
15 type Userdata: Clone;
16
17 fn from_raw(raw: RawHandle<'arena, Self::Type>, userdata: Self::Userdata) -> Self;
18 fn to_raw(&self) -> RawHandle<'arena, Self::Type>;
19
20 fn get(&self) -> ArenaResult<ElementRef<'arena, Self::Type>> {
21 self.to_raw().get()
22 }
23
24 fn get_mut(&self) -> ArenaResult<ElementRefMut<'arena, Self::Type>> {
25 self.to_raw().get_mut()
26 }
27
28 fn exists(&self) -> bool {
29 self.to_raw().get().is_ok()
30 }
31
32 fn arena(&self) -> &'arena Arena<Self::Type> {
33 self.to_raw().arena()
34 }
35
36 fn index(&self) -> Index {
37 self.to_raw().index()
38 }
39}
40
41pub struct RawHandle<'arena, T> {
42 arena: &'arena Arena<T>,
43 index: Index,
44}
45
46impl<'arena, T> RawHandle<'arena, T> {
47 pub(crate) fn new(arena: &'arena Arena<T>, index: Index) -> Self {
48 Self { arena, index }
49 }
50}
51
52impl<'arena, T> Handle<'arena> for RawHandle<'arena, T> {
53 type Type = T;
54 type Userdata = ();
55
56 fn from_raw(raw: RawHandle<'arena, Self::Type>, _userdata: Self::Userdata) -> Self {
57 raw
58 }
59
60 fn to_raw(&self) -> RawHandle<'arena, Self::Type> {
61 *self
62 }
63
64 fn get(&self) -> ArenaResult<ElementRef<'arena, Self::Type>> {
65 self.arena().lookup(self.index())
66 }
67
68 fn get_mut(&self) -> ArenaResult<ElementRefMut<'arena, Self::Type>> {
69 self.arena().lookup_mut(self.index())
70 }
71
72 fn arena(&self) -> &'arena Arena<Self::Type> {
73 self.arena
74 }
75
76 fn index(&self) -> Index {
77 self.index
78 }
79}
80
81impl<T> fmt::Debug for RawHandle<'_, T> {
82 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83 f.write_fmt(format_args!("Handle({})", <Index as Into<i64>>::into(self.index)))
84 }
85}
86
87impl<T> Clone for RawHandle<'_, T> {
88 fn clone(&self) -> Self {
89 Self::new(self.arena(), self.index())
90 }
91}
92
93impl<T> Copy for RawHandle<'_, T> {}
94
95impl<T> cmp::PartialEq for RawHandle<'_, T> {
96 fn eq(&self, other: &Self) -> bool {
97 self.index() == other.index()
98 }
99}
100
101impl<T> cmp::Eq for RawHandle<'_, T> {}
102
103impl<T> cmp::PartialOrd for RawHandle<'_, T> {
104 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
105 self.index.partial_cmp(&other.index)
106 }
107}
108
109impl<T> cmp::Ord for RawHandle<'_, T> {
110 fn cmp(&self, other: &Self) -> cmp::Ordering {
111 self.index.cmp(&other.index)
112 }
113}