Skip to main content

jni_simple/
jbool.rs

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        //Currently all usages of this are assumed to NOT read the original value.
227        //It is valid that the original value is uninitialized memory so we cannot really read it here.
228        //So we just always use false as the initial value and only write to the pointer after the call completes.
229        let mut bool = jboolean::FALSE;
230        let result = func(&raw mut bool);
231        //SAFETY: if the pointer is non-null then it better not be dangling.
232        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 {}