1use crate::{Scalar, Uint24};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8#[cfg_attr(feature = "bytemuck", derive(bytemuck::AnyBitPattern))]
9#[repr(transparent)]
10pub struct Nullable<T>(T);
11
12trait NullValue {
14 const NULL: Self;
15}
16
17impl<T: Scalar> Scalar for Nullable<T> {
18 type Raw = T::Raw;
19
20 #[inline]
21 fn from_raw(raw: Self::Raw) -> Self {
22 Self(T::from_raw(raw))
23 }
24
25 #[inline]
26 fn to_raw(self) -> Self::Raw {
27 self.0.to_raw()
28 }
29}
30
31impl<T> Nullable<T> {
32 #[inline]
34 pub fn offset(&self) -> &T {
35 &self.0
36 }
37}
38
39impl<T: PartialEq<u32>> Nullable<T> {
40 #[inline]
41 pub fn is_null(&self) -> bool {
42 self.0 == 0
43 }
44}
45
46impl<T: PartialEq<u32>> PartialEq<u32> for Nullable<T> {
47 #[inline]
48 fn eq(&self, other: &u32) -> bool {
49 self.0 == *other
50 }
51}
52
53impl<T: NullValue> Default for Nullable<T> {
54 fn default() -> Self {
55 Self(T::NULL)
56 }
57}
58
59macro_rules! impl_offset {
60 ($name:ident, $bits:literal, $rawty:ty) => {
61 #[doc = concat!("A", stringify!($bits), "-bit offset to a table.")]
62 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
67 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
68 #[cfg_attr(feature = "bytemuck", derive(bytemuck::AnyBitPattern))]
69 #[repr(transparent)]
70 pub struct $name($rawty);
71
72 impl $name {
73 #[inline]
75 pub const fn new(raw: $rawty) -> Self {
76 Self(raw)
77 }
78
79 #[inline]
81 pub fn is_null(self) -> bool {
82 self.to_u32() == 0
83 }
84
85 #[inline]
86 pub fn to_u32(self) -> u32 {
87 self.0.into()
88 }
89 }
90
91 impl crate::raw::Scalar for $name {
92 type Raw = <$rawty as crate::raw::Scalar>::Raw;
93 fn from_raw(raw: Self::Raw) -> Self {
94 let raw = <$rawty>::from_raw(raw);
95 $name::new(raw)
96 }
97
98 fn to_raw(self) -> Self::Raw {
99 self.0.to_raw()
100 }
101 }
102
103 impl PartialEq<u32> for $name {
105 fn eq(&self, other: &u32) -> bool {
106 self.to_u32() == *other
107 }
108 }
109
110 impl NullValue for $name {
111 const NULL: $name = $name(<$rawty>::MIN);
112 }
113 };
114}
115
116impl_offset!(Offset16, 16, u16);
117impl_offset!(Offset24, 24, Uint24);
118impl_offset!(Offset32, 32, u32);