1use core::fmt;
2
3#[derive(Clone, Copy, PartialEq, Eq, Hash)]
4pub struct Value(pub u64);
5
6pub const HANDLE_NONE: u64 = u64::MAX;
7
8const HANDLE_SLOT_BITS: u32 = 24;
9const HANDLE_SLOT_MASK: u64 = (1u64 << HANDLE_SLOT_BITS) - 1;
10const HANDLE_GEN_MASK: u64 = (1u64 << HANDLE_SLOT_BITS) - 1;
11pub const HANDLE_SLOT_MAX: u32 = (1u32 << HANDLE_SLOT_BITS) - 2;
12
13impl Value {
14 pub const ZERO: Value = Value(0);
15 pub const NONE: Value = Value(HANDLE_NONE);
16 pub const UNIT: Value = Value(0);
17 pub const FALSE: Value = Value(0);
18 pub const TRUE: Value = Value(1);
19
20 #[inline(always)]
21 pub fn raw(self) -> u64 { self.0 }
22
23 #[inline(always)]
24 pub fn from_raw(n: u64) -> Value { Value(n) }
25
26 #[inline(always)]
27 pub fn from_int(n: i64) -> Value { Value(n as u64) }
28
29 #[inline(always)]
30 pub fn from_float(f: f64) -> Value { Value(f.to_bits()) }
31
32 #[inline(always)]
33 pub fn from_float_f32(f: f64) -> Value { Value((f as f32).to_bits() as u64) }
34
35 #[inline(always)]
36 pub fn from_bool(b: bool) -> Value { Value(if b { 1 } else { 0 }) }
37
38 #[inline(always)]
39 pub fn from_char(c: char) -> Value { Value(c as u64) }
40
41 #[inline(always)]
42 pub fn from_handle(slot: u32, generation: u32) -> Value {
43 let s = (slot as u64) & HANDLE_SLOT_MASK;
44 let g = (generation as u64) & HANDLE_GEN_MASK;
45 Value((s << HANDLE_SLOT_BITS) | g)
46 }
47
48 #[inline(always)]
49 pub fn is_handle_none(self) -> bool { self.0 == HANDLE_NONE }
50
51 #[inline(always)]
52 pub fn as_int(self) -> i64 { self.0 as i64 }
53
54 #[inline(always)]
55 pub fn as_float(self) -> f64 { f64::from_bits(self.0) }
56
57 #[inline(always)]
58 pub fn as_bool(self) -> bool { self.0 != 0 }
59
60 #[inline(always)]
61 pub fn as_char(self) -> Option<char> { char::from_u32(self.0 as u32) }
62
63 #[inline(always)]
64 pub fn as_handle(self) -> (u32, u32) {
65 let slot = ((self.0 >> HANDLE_SLOT_BITS) & HANDLE_SLOT_MASK) as u32;
66 let gen_ = (self.0 & HANDLE_GEN_MASK) as u32;
67 (slot, gen_)
68 }
69}
70
71impl fmt::Debug for Value {
72 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73 if self.is_handle_none() { return write!(f, "None"); }
74 write!(f, "Value({:#018x})", self.0)
75 }
76}
77