abi_stable/type_layout/
small_types.rs
1use super::*;
2
3use crate::const_utils::{min_u16, min_u8};
4
5use std::ops::{Range, RangeInclusive};
6
7#[repr(transparent)]
11#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, StableAbi)]
12pub struct StartLen {
13 bits: u32,
14}
15
16pub type StartLenRepr = u32;
18
19impl StartLen {
20 #[inline]
22 pub const fn new(start: u16, len: u16) -> Self {
23 Self {
24 bits: (start as u32) | ((len as u32) << 16),
25 }
26 }
27
28 #[inline]
30 pub const fn start(self) -> u16 {
31 self.bits as u16
32 }
33 #[inline]
35 pub const fn len(self) -> u16 {
36 (self.bits >> 16) as u16
37 }
38
39 pub const fn is_empty(self) -> bool {
41 self.len() == 0
42 }
43
44 #[inline]
46 pub const fn start_usize(self) -> usize {
47 (self.bits & 0xffff) as usize
48 }
49 #[inline]
50 pub const fn len_usize(self) -> usize {
52 (self.bits >> 16) as usize
53 }
54 #[inline]
56 pub const fn end_usize(self) -> usize {
57 self.start_usize() + self.len_usize()
58 }
59
60 #[inline]
62 pub const fn to_range(self) -> Range<usize> {
63 self.start_usize()..self.end_usize()
64 }
65
66 #[inline]
68 pub const fn from_u32(n: StartLenRepr) -> Self {
69 Self { bits: n }
70 }
71
72 pub const EMPTY: Self = Self::new(0, 0);
74
75 abi_stable_shared::declare_start_len_bit_methods! {}
76}
77
78pub struct StartLenConverter<T>(pub T);
80
81#[allow(clippy::wrong_self_convention)]
82impl StartLenConverter<()> {
83 pub const fn to_start_len(self) -> StartLen {
85 StartLen::EMPTY
86 }
87}
88
89#[allow(clippy::wrong_self_convention)]
90impl StartLenConverter<usize> {
91 pub const fn to_start_len(self) -> StartLen {
93 StartLen::new(self.0 as u16, 1)
94 }
95}
96
97#[allow(clippy::wrong_self_convention)]
98impl StartLenConverter<Range<usize>> {
99 pub const fn to_start_len(self) -> StartLen {
101 let start = self.0.start as u16;
102 let len = (self.0.end - self.0.start) as u16;
103 StartLen::new(start, len)
104 }
105}
106
107#[allow(clippy::wrong_self_convention)]
108impl StartLenConverter<RangeInclusive<usize>> {
109 pub const fn to_start_len(self) -> StartLen {
111 let start = *self.0.start();
112 let end = *self.0.end() + 1;
113 StartLen::new(start as u16, (end - start) as u16)
114 }
115}
116
117#[allow(clippy::wrong_self_convention)]
118impl StartLenConverter<StartLen> {
119 pub const fn to_start_len(self) -> StartLen {
121 self.0
122 }
123}
124
125#[repr(transparent)]
129#[derive(Copy, Clone, PartialEq, Eq, Ord, PartialOrd, StableAbi)]
130pub struct OptionU16(u16);
131
132impl OptionU16 {
133 #[allow(non_upper_case_globals)]
135 pub const None: Self = OptionU16(!0);
136
137 const MAX_VAL: u16 = !0 - 1;
138
139 pub const fn some(value: u16) -> Self {
142 OptionU16(min_u16(value, Self::MAX_VAL))
143 }
144
145 pub const fn eq(self, other: Self) -> bool {
147 self.0 == other.0
148 }
149
150 pub const fn ne(self, other: Self) -> bool {
152 self.0 != other.0
153 }
154
155 pub const fn is_some(self) -> bool {
157 self.ne(Self::None)
158 }
159 pub const fn is_none(self) -> bool {
161 self.eq(Self::None)
162 }
163
164 pub const fn to_option(self) -> Option<u16> {
166 if self.is_some() {
167 Some(self.0)
168 } else {
169 None
170 }
171 }
172}
173
174impl Debug for OptionU16 {
175 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
176 Debug::fmt(&self.to_option(), f)
177 }
178}
179
180impl Display for OptionU16 {
181 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
182 if self.is_some() {
183 Display::fmt("None", f)
184 } else {
185 Display::fmt(&self.0, f)
186 }
187 }
188}
189
190#[repr(transparent)]
194#[derive(Copy, Clone, PartialEq, Eq, Ord, PartialOrd, StableAbi)]
195pub struct OptionU8(u8);
196
197impl OptionU8 {
198 #[allow(non_upper_case_globals)]
200 pub const None: Self = OptionU8(!0);
201
202 const MAX_VAL: u8 = !0 - 1;
203
204 pub const fn some(value: u8) -> Self {
207 OptionU8(min_u8(value, Self::MAX_VAL))
208 }
209
210 pub const fn eq(self, other: Self) -> bool {
212 self.0 == other.0
213 }
214
215 pub const fn ne(self, other: Self) -> bool {
217 self.0 != other.0
218 }
219
220 pub const fn is_some(self) -> bool {
222 self.ne(Self::None)
223 }
224 pub const fn is_none(self) -> bool {
226 self.eq(Self::None)
227 }
228
229 pub const fn to_option(self) -> Option<u8> {
231 if self.is_some() {
232 Some(self.0)
233 } else {
234 None
235 }
236 }
237}
238
239impl Debug for OptionU8 {
240 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
241 Debug::fmt(&self.to_option(), f)
242 }
243}
244
245impl Display for OptionU8 {
246 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
247 if self.is_some() {
248 Display::fmt("None", f)
249 } else {
250 Display::fmt(&self.0, f)
251 }
252 }
253}