1use core::borrow::Borrow;
2use core::cmp::Ordering;
3use core::fmt::{self, Debug, Display, Formatter};
4use core::hash::{Hash, Hasher};
5use core::ops::{Deref, DerefMut, Not};
6
7use crate::private::{SealedJBooleanInputLayout, SealedJBooleanMutPtr};
8use crate::{JBooleanInputLayout, JBooleanMutPtr};
9use alloc::vec::Vec;
10use core::ffi::c_uchar;
11use core::ptr::null_mut;
12
13#[derive(Clone, Copy)]
14#[repr(transparent)]
15pub struct jboolean(c_uchar);
16
17#[test]
18fn test_jboolean_alignments_and_size() {
19 assert_eq!(align_of::<jboolean>(), align_of::<bool>());
20 assert_eq!(size_of::<jboolean>(), size_of::<bool>());
21}
22
23impl jboolean {
24 pub const FALSE: Self = Self(0);
25
26 pub const TRUE: Self = Self(1);
27
28 #[must_use]
29 pub const fn from(value: bool) -> Self {
30 if value { Self::TRUE } else { Self::FALSE }
31 }
32
33 #[must_use]
34 pub const fn from_wide(value: c_uchar) -> Self {
35 Self(value)
36 }
37
38 #[must_use]
39 pub const fn as_bool(self) -> bool {
40 self.0 != 0
41 }
42
43 #[must_use]
44 pub const fn as_wide(self) -> c_uchar {
45 self.0
46 }
47
48 pub const fn narrow(&mut self) {
49 if self.0 != 0 {
50 self.0 = 1;
51 }
52 }
53 #[must_use]
54 pub const fn is_wide(&self) -> bool {
55 (self.0 & 0x1) != self.0
56 }
57
58 #[must_use]
59 pub const fn transmute_slice(input: &[Self]) -> &[c_uchar] {
60 unsafe { core::slice::from_raw_parts(input.as_ptr().cast(), input.len()) }
61 }
62
63 #[must_use]
64 pub const fn transmute_slice_mut(input: &mut [Self]) -> &mut [c_uchar] {
65 unsafe { core::slice::from_raw_parts_mut(input.as_mut_ptr().cast(), input.len()) }
66 }
67
68 #[must_use]
69 pub const fn transmute_bool_slice(input: &[bool]) -> &[Self] {
70 unsafe { core::slice::from_raw_parts(input.as_ptr().cast(), input.len()) }
71 }
72
73 #[must_use]
74 pub const fn transmute_wide_slice(input: &[c_uchar]) -> &[Self] {
75 unsafe { core::slice::from_raw_parts(input.as_ptr().cast(), input.len()) }
76 }
77
78 #[must_use]
79 pub const fn transmute_wide_slice_mut(input: &mut [c_uchar]) -> &mut [Self] {
80 unsafe { core::slice::from_raw_parts_mut(input.as_mut_ptr().cast(), input.len()) }
81 }
82
83 #[must_use]
84 pub fn transmute_wide_vec(input: Vec<c_uchar>) -> Vec<Self> {
85 let mut input = core::mem::ManuallyDrop::new(input);
86 unsafe { Vec::from_raw_parts(input.as_mut_ptr().cast(), input.len(), input.capacity()) }
87 }
88
89 #[must_use]
90 pub fn narrow_vec(mut input: Vec<Self>) -> Vec<bool> {
91 input.iter_mut().for_each(Self::narrow);
92 let mut input = core::mem::ManuallyDrop::new(input);
93 unsafe { Vec::from_raw_parts(input.as_mut_ptr().cast(), input.len(), input.capacity()) }
94 }
95}
96
97impl AsRef<bool> for jboolean {
98 fn as_ref(&self) -> &bool {
99 if self.0 != 0 { &true } else { &false }
100 }
101}
102
103impl Borrow<bool> for jboolean {
104 fn borrow(&self) -> &bool {
105 if self.0 != 0 { &true } else { &false }
106 }
107}
108
109impl Deref for jboolean {
110 type Target = core::ffi::c_uchar;
111 fn deref(&self) -> &Self::Target {
112 &self.0
113 }
114}
115impl DerefMut for jboolean {
116 fn deref_mut(&mut self) -> &mut Self::Target {
117 &mut self.0
118 }
119}
120
121impl Default for jboolean {
122 fn default() -> Self {
123 Self::FALSE
124 }
125}
126impl Debug for jboolean {
127 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
128 Debug::fmt(&bool::from(*self), f)
129 }
130}
131impl Display for jboolean {
132 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
133 Display::fmt(&bool::from(*self), f)
134 }
135}
136
137impl From<bool> for jboolean {
138 fn from(value: bool) -> Self {
139 Self(value.into())
140 }
141}
142impl From<jboolean> for bool {
143 fn from(value: jboolean) -> Self {
144 value.0 != 0
145 }
146}
147
148impl Not for jboolean {
149 type Output = bool;
150 fn not(self) -> Self::Output {
151 self.0 == 0
152 }
153}
154
155impl Eq for jboolean {}
156impl PartialEq<Self> for jboolean {
157 fn eq(&self, other: &Self) -> bool {
158 bool::from(*self) == bool::from(*other)
159 }
160}
161
162impl PartialEq<bool> for jboolean {
163 fn eq(&self, other: &bool) -> bool {
164 bool::from(*self) == *other
165 }
166}
167impl PartialEq<jboolean> for bool {
168 fn eq(&self, other: &jboolean) -> bool {
169 Self::from(*other) == *self
170 }
171}
172
173impl PartialOrd<Self> for jboolean {
174 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
175 Some(self.cmp(other))
176 }
177}
178
179impl PartialOrd<bool> for jboolean {
180 fn partial_cmp(&self, other: &bool) -> Option<Ordering> {
181 PartialOrd::partial_cmp(&bool::from(*self), other)
182 }
183}
184impl PartialOrd<jboolean> for bool {
185 fn partial_cmp(&self, other: &jboolean) -> Option<Ordering> {
186 PartialOrd::partial_cmp(self, &Self::from(*other))
187 }
188}
189
190impl Ord for jboolean {
191 fn cmp(&self, other: &Self) -> Ordering {
192 Ord::cmp(&bool::from(*self), &bool::from(*other))
193 }
194}
195
196impl Hash for jboolean {
197 fn hash<H: Hasher>(&self, state: &mut H) {
198 bool::from(*self).hash(state);
199 }
200}
201
202impl JBooleanMutPtr for &mut bool {}
203
204impl SealedJBooleanMutPtr for &mut bool {
205 fn use_jboolean_mut<R>(self, func: impl FnOnce(*mut jboolean) -> R) -> R {
206 let mut value = jboolean::from(*self);
207 let res = func(&raw mut value);
208 *self = value.as_bool();
209 res
210 }
211}
212
213impl JBooleanMutPtr for *mut jboolean {}
214impl SealedJBooleanMutPtr for *mut jboolean {
215 fn use_jboolean_mut<R>(self, func: impl FnOnce(*mut jboolean) -> R) -> R {
216 func(self)
217 }
218}
219
220impl JBooleanMutPtr for *mut bool {}
221impl SealedJBooleanMutPtr for *mut bool {
222 fn use_jboolean_mut<R>(self, func: impl FnOnce(*mut jboolean) -> R) -> R {
223 if self.is_null() {
224 return func(null_mut());
225 }
226 let mut bool = jboolean::FALSE;
230 let result = func(&raw mut bool);
231 unsafe {
233 self.write_unaligned(bool.as_bool());
234 }
235 result
236 }
237}
238
239impl JBooleanMutPtr for () {}
240impl SealedJBooleanMutPtr for () {
241 fn use_jboolean_mut<R>(self, func: impl FnOnce(*mut jboolean) -> R) -> R {
242 func(null_mut())
243 }
244}
245
246impl SealedJBooleanInputLayout for c_uchar {}
247
248impl JBooleanInputLayout for c_uchar {}
249
250impl SealedJBooleanInputLayout for jboolean {}
251
252impl JBooleanInputLayout for jboolean {}
253
254impl SealedJBooleanInputLayout for bool {}
255
256impl JBooleanInputLayout for bool {}