1
//! Macros for generating C-ABI-compatible collection types (`Vec`, `Option`, `Result`)
2
//! used throughout the codebase for FFI interop. Each macro produces `#[repr(C)]` types
3
//! with a destructor model: `DefaultRust` (library-owned), `NoDestructor` (`&'static`),
4
//! `External` (caller-provided destructor fn), and `AlreadyDestroyed` (post-drop guard).
5

            
6
#[macro_export]
7
macro_rules! impl_vec {
8
    ($struct_type:ident, $struct_name:ident, $destructor_name:ident, $destructor_type_name:ident, $slice_name:ident, $option_type:ident) => {
9
        pub type $destructor_type_name = extern "C" fn(*mut $struct_name);
10

            
11
        /// C-compatible slice type for $struct_name.
12
        /// This is a non-owning view into a Vec's data.
13
        #[repr(C)]
14
        #[derive(Debug, Copy, Clone)]
15
        pub struct $slice_name {
16
            pub ptr: *const $struct_type,
17
            pub len: usize,
18
        }
19

            
20
        impl $slice_name {
21
            /// Creates an empty slice.
22
            #[inline(always)]
23
            pub const fn empty() -> Self {
24
                Self {
25
                    ptr: core::ptr::null(),
26
                    len: 0,
27
                }
28
            }
29

            
30
            /// Returns the number of elements in the slice.
31
            #[inline(always)]
32
            pub const fn len(&self) -> usize {
33
                self.len
34
            }
35

            
36
            /// Returns true if the slice is empty.
37
            #[inline(always)]
38
            pub const fn is_empty(&self) -> bool {
39
                self.len == 0
40
            }
41

            
42
            /// Returns a pointer to the slice's data.
43
            #[inline(always)]
44
            pub const fn as_ptr(&self) -> *const $struct_type {
45
                self.ptr
46
            }
47

            
48
            /// Converts the C-slice to a Rust slice.
49
            #[inline(always)]
50
2
            pub fn as_slice(&self) -> &[$struct_type] {
51
2
                if self.ptr.is_null() || self.len == 0 {
52
1
                    &[]
53
                } else {
54
1
                    unsafe { core::slice::from_raw_parts(self.ptr, self.len) }
55
                }
56
2
            }
57

            
58
            /// Returns a reference to the element at the given index, or None if out of bounds.
59
            #[inline(always)]
60
            pub fn get(&self, index: usize) -> Option<&$struct_type> {
61
                self.as_slice().get(index)
62
            }
63

            
64
            /// Returns an iterator over the elements.
65
            #[inline]
66
            pub fn iter(&self) -> core::slice::Iter<'_, $struct_type> {
67
                self.as_slice().iter()
68
            }
69
        }
70

            
71
        unsafe impl Send for $slice_name {}
72
        unsafe impl Sync for $slice_name {}
73

            
74
        #[repr(C)]
75
        pub struct $struct_name {
76
            ptr: *const $struct_type,
77
            len: usize,
78
            cap: usize,
79
            destructor: $destructor_name,
80
        }
81

            
82
        #[derive(Debug, Copy, Clone)]
83
        #[repr(C, u8)]
84
        pub enum $destructor_name {
85
            DefaultRust,
86
            NoDestructor,
87
            External($destructor_type_name),
88
            /// Destructor was already run — prevents double-free.
89
            /// Set by Drop impl after destruction.
90
            AlreadyDestroyed,
91
        }
92

            
93
        unsafe impl Send for $struct_name {}
94
        unsafe impl Sync for $struct_name {}
95

            
96
        impl $struct_name {
97
            #[inline(always)]
98
35316
            pub fn new() -> $struct_name {
99
                // lets hope the optimizer catches this
100
35316
                Self::from_vec(alloc::vec::Vec::new())
101
35316
            }
102

            
103
            #[inline]
104
            pub fn with_capacity(cap: usize) -> Self {
105
                Self::from_vec(alloc::vec::Vec::<$struct_type>::with_capacity(cap))
106
            }
107

            
108
            #[inline(always)]
109
952604
            pub const fn from_const_slice(input: &'static [$struct_type]) -> Self {
110
952604
                Self {
111
952604
                    ptr: input.as_ptr(),
112
952604
                    len: input.len(),
113
952604
                    cap: input.len(),
114
952604
                    destructor: $destructor_name::NoDestructor, // because of &'static
115
952604
                }
116
952604
            }
117

            
118
            #[inline(always)]
119
8282715
            pub fn from_vec(input: alloc::vec::Vec<$struct_type>) -> Self {
120
8282715
                let ptr = input.as_ptr();
121
8282715
                let len = input.len();
122
8282715
                let cap = input.capacity();
123

            
124
8282715
                let _ = ::core::mem::ManuallyDrop::new(input);
125

            
126
8282715
                Self {
127
8282715
                    ptr,
128
8282715
                    len,
129
8282715
                    cap,
130
8282715
                    destructor: $destructor_name::DefaultRust,
131
8282715
                }
132
8282715
            }
133

            
134
            #[inline]
135
260736
            pub fn iter(&self) -> core::slice::Iter<'_, $struct_type> {
136
260736
                self.as_ref().iter()
137
260736
            }
138

            
139
            #[inline(always)]
140
209466
            pub const fn len(&self) -> usize {
141
209466
                self.len
142
209466
            }
143

            
144
            #[inline(always)]
145
267180
            pub const fn capacity(&self) -> usize {
146
267180
                self.cap
147
267180
            }
148

            
149
            #[inline(always)]
150
250363
            pub const fn is_empty(&self) -> bool {
151
250363
                self.len == 0
152
250363
            }
153

            
154
            /// Returns a reference to the element at the given index (Rust-only, inline).
155
            #[inline(always)]
156
76536
            pub fn get(&self, index: usize) -> Option<&$struct_type> {
157
76536
                self.as_ref().get(index)
158
76536
            }
159

            
160
            /// C-API compatible get function. Returns a copy of the element at the given index.
161
            /// Returns None if the index is out of bounds.
162
            #[inline]
163
            pub fn c_get(&self, index: usize) -> $option_type
164
            where
165
                $struct_type: Clone,
166
            {
167
                self.get(index).cloned().into()
168
            }
169

            
170
            #[allow(dead_code)]
171
            #[inline(always)]
172
            unsafe fn get_unchecked(&self, index: usize) -> &$struct_type {
173
                self.as_ref().get_unchecked(index)
174
            }
175

            
176
            /// Returns the vec as a Rust slice (Rust-only, not C-API compatible).
177
            #[inline(always)]
178
1651065
            pub fn as_slice(&self) -> &[$struct_type] {
179
1651065
                self.as_ref()
180
1651065
            }
181

            
182
            /// Returns a C-compatible slice of the entire Vec.
183
            #[inline(always)]
184
2
            pub fn as_c_slice(&self) -> $slice_name {
185
2
                $slice_name {
186
2
                    ptr: self.ptr,
187
2
                    len: self.len,
188
2
                }
189
2
            }
190

            
191
            /// Returns a C-compatible slice of a range within the Vec.
192
            /// If the range is out of bounds, it is clamped to the valid range.
193
            #[inline]
194
            pub fn as_c_slice_range(&self, start: usize, end: usize) -> $slice_name {
195
                let start = start.min(self.len);
196
                let end = end.min(self.len).max(start);
197
                let len = end - start;
198
                if len == 0 || self.ptr.is_null() {
199
                    $slice_name::empty()
200
                } else {
201
                    $slice_name {
202
                        ptr: unsafe { self.ptr.add(start) },
203
                        len,
204
                    }
205
                }
206
            }
207

            
208
            /// Returns a pointer to the Vec's data.
209
            /// Use `len()` to get the number of elements.
210
            #[inline(always)]
211
            pub fn as_ptr(&self) -> *const $struct_type {
212
                self.ptr
213
            }
214
        }
215

            
216
        impl AsRef<[$struct_type]> for $struct_name {
217
11120518
            fn as_ref(&self) -> &[$struct_type] {
218
11120518
                if self.ptr.is_null() || self.len == 0 {
219
2477262
                    &[]
220
                } else {
221
8643256
                    unsafe { core::slice::from_raw_parts(self.ptr, self.len) }
222
                }
223
11120518
            }
224
        }
225

            
226
        impl Default for $struct_name {
227
70506
            fn default() -> Self {
228
70506
                Self::from_vec(alloc::vec::Vec::new())
229
70506
            }
230
        }
231

            
232
        impl core::iter::FromIterator<$struct_type> for $struct_name {
233
            fn from_iter<T>(iter: T) -> Self
234
            where
235
                T: IntoIterator<Item = $struct_type>,
236
            {
237
                Self::from_vec(alloc::vec::Vec::from_iter(iter))
238
            }
239
        }
240

            
241
        impl From<alloc::vec::Vec<$struct_type>> for $struct_name {
242
765439
            fn from(input: alloc::vec::Vec<$struct_type>) -> $struct_name {
243
765439
                $struct_name::from_vec(input)
244
765439
            }
245
        }
246

            
247
        impl From<&'static [$struct_type]> for $struct_name {
248
            fn from(input: &'static [$struct_type]) -> $struct_name {
249
                Self::from_const_slice(input)
250
            }
251
        }
252

            
253
        impl Drop for $struct_name {
254
9270207
            fn drop(&mut self) {
255
9270207
                match self.destructor {
256
8176234
                    $destructor_name::DefaultRust => {
257
8176234
                        let _ = unsafe {
258
8176234
                            alloc::vec::Vec::from_raw_parts(
259
8176234
                                self.ptr as *mut $struct_type,
260
8176234
                                self.len,
261
8176234
                                self.cap,
262
8176234
                            )
263
8176234
                        };
264
8176234
                        self.destructor = $destructor_name::AlreadyDestroyed;
265
8176234
                    }
266
106
                    $destructor_name::External(f) => {
267
106
                        f(self);
268
106
                        self.destructor = $destructor_name::AlreadyDestroyed;
269
106
                    }
270
1093867
                    $destructor_name::NoDestructor | $destructor_name::AlreadyDestroyed => {}
271
                }
272
9270207
            }
273
        }
274
    };
275
}
276

            
277
/// Implement the `From` trait for any type.
278
/// Example usage:
279
/// ```no_run,ignore
280
/// enum MyError<'a> {
281
///     Bar(BarError<'a>),
282
///     Foo(FooError<'a>)
283
/// }
284
///
285
/// impl_from!(BarError<'a>, MyError::Bar);
286
/// impl_from!(FooError<'a>, MyError::Foo);
287
/// ```
288
macro_rules! impl_from {
289
    // From a type with a lifetime to a type which also has a lifetime
290
    ($a:ident < $c:lifetime > , $b:ident:: $enum_type:ident) => {
291
        impl<$c> From<$a<$c>> for $b<$c> {
292
105
            fn from(e: $a<$c>) -> Self {
293
105
                $b::$enum_type(e)
294
105
            }
295
        }
296
    };
297

            
298
    // From a type without a lifetime to a type with a lifetime
299
    ($a:ident, $b:ident < $c:lifetime > :: $enum_type:ident) => {
300
        impl<$c> From<$a> for $b<$c> {
301
            fn from(e: $a) -> Self {
302
                $b::$enum_type(e)
303
            }
304
        }
305
    };
306

            
307
    // From a type without a lifetime to a type which also does not have a lifetime
308
    ($a:ident, $b:ident:: $enum_type:ident) => {
309
        impl From<$a> for $b {
310
            fn from(e: $a) -> Self {
311
                $b::$enum_type(e)
312
            }
313
        }
314
    };
315
}
316

            
317
/// Implement `Display` for an enum.
318
///
319
/// Example usage:
320
/// ```no_run,ignore
321
/// enum Foo<'a> {
322
///     Bar(&'a str),
323
///     Baz(i32)
324
/// }
325
///
326
/// impl_display!{ Foo<'a>, {
327
///     Bar(s) => s,
328
///     Baz(i) => format!("{}", i)
329
/// }}
330
/// ```
331
#[macro_export]
332
macro_rules! impl_display {
333
    // For a type with a lifetime
334
    ($enum:ident<$lt:lifetime>, {$($variant:pat => $fmt_string:expr),+$(,)* }) => {
335

            
336
        impl<$lt> ::core::fmt::Display for $enum<$lt> {
337
            fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
338
                use self::$enum::*;
339
                match &self {
340
                    $(
341
                        $variant => write!(f, "{}", $fmt_string),
342
                    )+
343
                }
344
            }
345
        }
346

            
347
    };
348

            
349
    // For a type without a lifetime
350
    ($enum:ident, {$($variant:pat => $fmt_string:expr),+$(,)* }) => {
351

            
352
        impl ::core::fmt::Display for $enum {
353
            fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
354
                use self::$enum::*;
355
                match &self {
356
                    $(
357
                        $variant => write!(f, "{}", $fmt_string),
358
                    )+
359
                }
360
            }
361
        }
362

            
363
    };
364
}
365

            
366
/// Implements `Debug` to use `Display` instead - assumes the that the type has implemented
367
/// `Display`
368
#[macro_export]
369
macro_rules! impl_debug_as_display {
370
    // For a type with a lifetime
371
    ($enum:ident < $lt:lifetime >) => {
372
        impl<$lt> ::core::fmt::Debug for $enum<$lt> {
373
            fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
374
                write!(f, "{}", self)
375
            }
376
        }
377
    };
378

            
379
    // For a type without a lifetime
380
    ($enum:ident) => {
381
        impl ::core::fmt::Debug for $enum {
382
            fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
383
                write!(f, "{}", self)
384
            }
385
        }
386
    };
387
}
388

            
389
#[macro_export]
390
macro_rules! impl_vec_as_hashmap {
391
    ($struct_type:ident, $struct_name:ident) => {
392
        impl $struct_name {
393
            pub fn insert_hm_item(&mut self, item: $struct_type) {
394
                if !self.contains_hm_item(&item) {
395
                    self.push(item);
396
                }
397
            }
398

            
399
            pub fn remove_hm_item(&mut self, remove_key: &$struct_type) {
400
                *self = Self::from_vec(
401
                    self.as_ref()
402
                        .iter()
403
                        .filter_map(|r| if *r == *remove_key { None } else { Some(*r) })
404
                        .collect::<Vec<_>>(),
405
                );
406
            }
407

            
408
            pub fn contains_hm_item(&self, searched: &$struct_type) -> bool {
409
                self.as_ref().iter().any(|i| i == searched)
410
            }
411
        }
412
    };
413
}
414

            
415
/// NOTE: impl_vec_mut can only exist for vectors that are known to be library-allocated!
416
#[macro_export]
417
macro_rules! impl_vec_mut {
418
    ($struct_type:ident, $struct_name:ident) => {
419
        impl AsMut<[$struct_type]> for $struct_name {
420
93730
            fn as_mut(&mut self) -> &mut [$struct_type] {
421
93730
                unsafe { core::slice::from_raw_parts_mut(self.ptr as *mut $struct_type, self.len) }
422
93730
            }
423
        }
424

            
425
        impl From<$struct_name> for alloc::vec::Vec<$struct_type> {
426
            #[allow(unused_mut)]
427
3864
            fn from(mut input: $struct_name) -> alloc::vec::Vec<$struct_type> {
428
3864
                input.into_library_owned_vec()
429
3864
            }
430
        }
431

            
432
        impl core::iter::Extend<$struct_type> for $struct_name {
433
            fn extend<T: core::iter::IntoIterator<Item = $struct_type>>(&mut self, iter: T) {
434
                for elem in iter {
435
                    self.push(elem);
436
                }
437
            }
438
        }
439

            
440
        impl $struct_name {
441
            #[inline]
442
148656
            pub fn as_mut_ptr(&mut self) -> *mut $struct_type {
443
148656
                self.ptr as *mut $struct_type
444
148656
            }
445

            
446
            #[inline]
447
204
            pub fn sort_by<F: FnMut(&$struct_type, &$struct_type) -> core::cmp::Ordering>(
448
204
                &mut self,
449
204
                compare: F,
450
204
            ) {
451
204
                self.as_mut().sort_by(compare);
452
204
            }
453

            
454
            #[inline]
455
122605
            pub fn push(&mut self, value: $struct_type) {
456
                // code is copied from the rust stdlib, since it's not possible to
457
                // create a temporary Vec here. Doing that would create two
458
122605
                if self.len == self.capacity() {
459
98770
                    self.buf_reserve(self.len, 1);
460
98770
                }
461
122605
                unsafe {
462
122605
                    let end = self.as_mut_ptr().add(self.len);
463
122605
                    core::ptr::write(end, value);
464
122605
                    self.len += 1;
465
122605
                }
466
122605
            }
467

            
468
            pub fn insert(&mut self, index: usize, element: $struct_type) {
469
                let len = self.len();
470
                if index > len {
471
                    return;
472
                }
473

            
474
                // space for the new element
475
                if len == self.capacity() {
476
                    self.reserve(1);
477
                }
478

            
479
                unsafe {
480
                    // infallible
481
                    // The spot to put the new value
482
                    {
483
                        let p = self.as_mut_ptr().add(index);
484
                        // Shift everything over to make space. (Duplicating the
485
                        // `index`th element into two consecutive places.)
486
                        core::ptr::copy(p, p.offset(1), len - index);
487
                        // Write it in, overwriting the first copy of the `index`th
488
                        // element.
489
                        core::ptr::write(p, element);
490
                    }
491
                    self.set_len(len + 1);
492
                }
493
            }
494

            
495
            pub fn remove(&mut self, index: usize) {
496
                let len = self.len();
497
                if index >= len {
498
                    return;
499
                }
500

            
501
                unsafe {
502
                    // infallible
503
                    let ret;
504
                    {
505
                        // the place we are taking from.
506
                        let ptr = self.as_mut_ptr().add(index);
507
                        // copy it out, unsafely having a copy of the value on
508
                        // the stack and in the vector at the same time.
509
                        ret = core::ptr::read(ptr);
510

            
511
                        // Shift everything down to fill in that spot.
512
                        core::ptr::copy(ptr.offset(1), ptr, len - index - 1);
513
                    }
514
                    self.set_len(len - 1);
515
                    let _ = ret;
516
                }
517
            }
518

            
519
            #[inline]
520
            pub fn pop(&mut self) -> Option<$struct_type> {
521
                if self.len == 0 {
522
                    None
523
                } else {
524
                    unsafe {
525
                        self.len -= 1;
526
                        Some(core::ptr::read(self.ptr.add(self.len())))
527
                    }
528
                }
529
            }
530

            
531
            #[inline]
532
17426
            pub fn iter_mut(&mut self) -> core::slice::IterMut<'_, $struct_type> {
533
17426
                self.as_mut().iter_mut()
534
17426
            }
535

            
536
            #[inline]
537
            pub fn into_iter(self) -> alloc::vec::IntoIter<$struct_type> {
538
                let v1: alloc::vec::Vec<$struct_type> = self.into();
539
                v1.into_iter()
540
            }
541

            
542
            #[inline]
543
119289
            fn amortized_new_size(
544
119289
                &self,
545
119289
                used_cap: usize,
546
119289
                needed_extra_cap: usize,
547
119289
            ) -> Result<usize, bool> {
548
                // Nothing we can really do about these checks :(
549
119289
                let required_cap = used_cap.checked_add(needed_extra_cap).ok_or(true)?;
550
                // Cannot overflow, because `cap <= isize::MAX`, and type of `cap` is `usize`.
551
119289
                let double_cap = self.cap * 2;
552
                // `double_cap` guarantees exponential growth.
553
119289
                Ok(core::cmp::max(double_cap, required_cap))
554
119289
            }
555

            
556
            #[inline]
557
119289
            fn current_layout(&self) -> Option<core::alloc::Layout> {
558
119289
                if self.cap == 0 {
559
57658
                    None
560
                } else {
561
                    // We have an allocated chunk of memory, so we can bypass runtime
562
                    // checks to get our current layout.
563
                    unsafe {
564
61631
                        let align = core::mem::align_of::<$struct_type>();
565
61631
                        let size = core::mem::size_of::<$struct_type>() * self.cap;
566
61631
                        Some(core::alloc::Layout::from_size_align_unchecked(size, align))
567
                    }
568
                }
569
119289
            }
570

            
571
            #[inline]
572
119289
            fn alloc_guard(alloc_size: usize) -> Result<(), bool> {
573
119289
                if core::mem::size_of::<usize>() < 8 && alloc_size > ::core::isize::MAX as usize {
574
                    Err(true)
575
                } else {
576
119289
                    Ok(())
577
                }
578
119289
            }
579

            
580
            #[inline]
581
120054
            fn try_reserve(
582
120054
                &mut self,
583
120054
                used_cap: usize,
584
120054
                needed_extra_cap: usize,
585
120054
            ) -> Result<(), bool> {
586
                // NOTE: we don't early branch on ZSTs here because we want this
587
                // to actually catch "asking for more than usize::MAX" in that case.
588
                // If we make it past the first branch then we are guaranteed to
589
                // panic.
590

            
591
                // Don't actually need any more capacity.
592
                // Wrapping in case they give a bad `used_cap`
593
120054
                if self.capacity().wrapping_sub(used_cap) >= needed_extra_cap {
594
765
                    return Ok(());
595
119289
                }
596

            
597
119289
                let new_cap = self.amortized_new_size(used_cap, needed_extra_cap)?;
598
119289
                let new_layout =
599
119289
                    alloc::alloc::Layout::array::<$struct_type>(new_cap).map_err(|_| true)?;
600

            
601
119289
                $struct_name::alloc_guard(new_layout.size())?;
602

            
603
119289
                let res = unsafe {
604
119289
                    match self.current_layout() {
605
61631
                        Some(layout) => {
606
61631
                            alloc::alloc::realloc(self.ptr as *mut u8, layout, new_layout.size())
607
                        }
608
57658
                        None => alloc::alloc::alloc(new_layout),
609
                    }
610
                };
611

            
612
119289
                if res == core::ptr::null_mut() {
613
                    return Err(false);
614
119289
                }
615

            
616
119289
                self.ptr = res as *mut $struct_type;
617
119289
                self.cap = new_cap;
618

            
619
119289
                Ok(())
620
120054
            }
621

            
622
120054
            fn buf_reserve(&mut self, used_cap: usize, needed_extra_cap: usize) {
623
120054
                match self.try_reserve(used_cap, needed_extra_cap) {
624
                    Err(true /* Overflow */) => {
625
                        panic!("memory allocation failed: overflow");
626
                    }
627
                    Err(false /* AllocError(_) */) => {
628
                        panic!("memory allocation failed: error allocating new memory");
629
                    }
630
120054
                    Ok(()) => { /* yay */ }
631
                }
632
120054
            }
633

            
634
1530
            pub fn append(&mut self, other: &mut Self) {
635
1530
                unsafe {
636
1530
                    self.append_elements(other.as_slice() as _);
637
1530
                    other.set_len(0);
638
1530
                }
639
1530
            }
640

            
641
1530
            unsafe fn set_len(&mut self, new_len: usize) {
642
1530
                debug_assert!(new_len <= self.capacity());
643
1530
                self.len = new_len;
644
1530
            }
645

            
646
1530
            pub fn reserve(&mut self, additional: usize) {
647
1530
                self.buf_reserve(self.len, additional);
648
1530
            }
649

            
650
            /// Appends elements to `Self` from other buffer.
651
            #[inline]
652
1530
            unsafe fn append_elements(&mut self, other: *const [$struct_type]) {
653
1530
                let count = (&(*other)).len();
654
1530
                self.reserve(count);
655
1530
                let len = self.len();
656
1530
                core::ptr::copy_nonoverlapping(
657
1530
                    other as *const $struct_type,
658
1530
                    self.as_mut_ptr().add(len),
659
1530
                    count,
660
                );
661
1530
                self.len += count;
662
1530
            }
663

            
664
            pub fn truncate(&mut self, len: usize) {
665
                // This is safe because:
666
                //
667
                // * the slice passed to `drop_in_place` is valid; the `len > self.len` case avoids
668
                //   creating an invalid slice, and
669
                // * the `len` of the vector is shrunk before calling `drop_in_place`, such that no
670
                //   value will be dropped twice in case `drop_in_place` were to panic once (if it
671
                //   panics twice, the program aborts).
672
                unsafe {
673
                    if len > self.len {
674
                        return;
675
                    }
676
                    let remaining_len = self.len - len;
677
                    let s = core::ptr::slice_from_raw_parts_mut(
678
                        self.as_mut_ptr().add(len),
679
                        remaining_len,
680
                    );
681
                    self.len = len;
682
                    core::ptr::drop_in_place(s);
683
                }
684
            }
685

            
686
            pub fn retain<F>(&mut self, mut f: F)
687
            where
688
                F: FnMut(&$struct_type) -> bool,
689
            {
690
                let len = self.len();
691
                let mut del = 0;
692

            
693
                {
694
                    for i in 0..len {
695
                        if unsafe { !f(self.get_unchecked(i)) } {
696
                            del += 1;
697
                        } else if del > 0 {
698
                            self.as_mut().swap(i - del, i);
699
                        }
700
                    }
701
                }
702

            
703
                if del > 0 {
704
                    self.truncate(len - del);
705
                }
706
            }
707
        }
708
    };
709
}
710

            
711
#[macro_export]
712
macro_rules! impl_vec_debug {
713
    ($struct_type:ident, $struct_name:ident) => {
714
        impl core::fmt::Debug for $struct_name {
715
14
            fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
716
14
                self.as_ref().fmt(f)
717
14
            }
718
        }
719
    };
720
}
721

            
722
#[macro_export]
723
macro_rules! impl_vec_partialord {
724
    ($struct_type:ident, $struct_name:ident) => {
725
        impl PartialOrd for $struct_name {
726
            fn partial_cmp(&self, rhs: &Self) -> Option<core::cmp::Ordering> {
727
                self.as_ref().partial_cmp(rhs.as_ref())
728
            }
729
        }
730
    };
731
}
732

            
733
#[macro_export]
734
macro_rules! impl_vec_ord {
735
    ($struct_type:ident, $struct_name:ident) => {
736
        impl Ord for $struct_name {
737
            fn cmp(&self, rhs: &Self) -> core::cmp::Ordering {
738
                self.as_ref().cmp(rhs.as_ref())
739
            }
740
        }
741
    };
742
}
743

            
744
#[macro_export]
745
macro_rules! impl_vec_clone {
746
    ($struct_type:ident, $struct_name:ident, $destructor_name:ident) => {
747
        impl $struct_name {
748
            // Creates a `Vec` from a `Cow<'static, [T]>` - useful to avoid allocating in the case
749
            // of &'static memory
750
            #[inline(always)]
751
            pub fn from_copy_on_write(
752
                input: alloc::borrow::Cow<'static, [$struct_type]>,
753
            ) -> $struct_name {
754
                match input {
755
                    alloc::borrow::Cow::Borrowed(static_array) => {
756
                        Self::from_const_slice(static_array)
757
                    }
758
                    alloc::borrow::Cow::Owned(owned_vec) => Self::from_vec(owned_vec),
759
                }
760
            }
761

            
762
            /// Creates a Vec containing a single element
763
            #[inline(always)]
764
            pub fn from_item(item: $struct_type) -> Self {
765
                Self::from_vec(alloc::vec![item])
766
            }
767

            
768
            /// Copies elements from a C array pointer into a new Vec.
769
            /// 
770
            /// # Safety
771
            /// - `ptr` must be valid for reading `len` elements
772
            /// - The memory must be properly aligned for `$struct_type`
773
            /// - The elements are cloned, so `$struct_type` must implement `Clone`
774
            #[inline]
775
            pub unsafe fn copy_from_ptr(ptr: *const $struct_type, len: usize) -> Self {
776
                if ptr.is_null() || len == 0 {
777
                    return Self::new();
778
                }
779
                let slice = core::slice::from_raw_parts(ptr, len);
780
                Self::from_vec(slice.to_vec())
781
            }
782

            
783
            /// NOTE: CLONES the memory if the memory is external or &'static
784
            /// Moves the memory out if the memory is library-allocated
785
            #[inline(always)]
786
377992
            pub fn clone_self(&self) -> Self {
787
377992
                match self.destructor {
788
138002
                    $destructor_name::NoDestructor | $destructor_name::AlreadyDestroyed => Self {
789
138002
                        ptr: self.ptr,
790
138002
                        len: self.len,
791
138002
                        cap: self.cap,
792
138002
                        destructor: $destructor_name::NoDestructor,
793
138002
                    },
794
                    $destructor_name::External(_) | $destructor_name::DefaultRust => {
795
239990
                        Self::from_vec(self.as_ref().to_vec())
796
                    }
797
                }
798
377992
            }
799

            
800
            /// NOTE: CLONES the memory if the memory is external or &'static
801
            /// Moves the memory out if the memory is library-allocated
802
            #[inline(always)]
803
70058
            pub fn into_library_owned_vec(self) -> alloc::vec::Vec<$struct_type> {
804
70058
                match self.destructor {
805
                    $destructor_name::NoDestructor | $destructor_name::External(_) | $destructor_name::AlreadyDestroyed => {
806
7547
                        self.as_ref().to_vec()
807
                    }
808
                    $destructor_name::DefaultRust => {
809
62511
                        let v = unsafe {
810
62511
                            alloc::vec::Vec::from_raw_parts(
811
62511
                                self.ptr as *mut $struct_type,
812
62511
                                self.len,
813
62511
                                self.cap,
814
                            )
815
                        };
816
62511
                        core::mem::forget(self);
817
62511
                        v
818
                    }
819
                }
820
70058
            }
821
        }
822
        impl Clone for $struct_name {
823
227608
            fn clone(&self) -> Self {
824
227608
                self.clone_self()
825
227608
            }
826
        }
827
    };
828
}
829

            
830
#[macro_export]
831
macro_rules! impl_vec_partialeq {
832
    ($struct_type:ident, $struct_name:ident) => {
833
        impl PartialEq for $struct_name {
834
1463
            fn eq(&self, rhs: &Self) -> bool {
835
1463
                self.as_ref().eq(rhs.as_ref())
836
1463
            }
837
        }
838
    };
839
}
840

            
841
#[macro_export]
842
macro_rules! impl_vec_eq {
843
    ($struct_type:ident, $struct_name:ident) => {
844
        impl Eq for $struct_name {}
845
    };
846
}
847

            
848
#[macro_export]
849
macro_rules! impl_vec_hash {
850
    ($struct_type:ident, $struct_name:ident) => {
851
        impl core::hash::Hash for $struct_name {
852
1059
            fn hash<H>(&self, state: &mut H)
853
1059
            where
854
1059
                H: core::hash::Hasher,
855
            {
856
1059
                self.as_ref().hash(state);
857
1059
            }
858
        }
859
    };
860
}
861

            
862
#[macro_export]
863
macro_rules! impl_option_inner {
864
    ($struct_type:ident, $struct_name:ident) => {
865
        impl From<$struct_name> for Option<$struct_type> {
866
            fn from(o: $struct_name) -> Option<$struct_type> {
867
                match o {
868
                    $struct_name::None => None,
869
                    $struct_name::Some(t) => Some(t),
870
                }
871
            }
872
        }
873

            
874
        impl From<Option<$struct_type>> for $struct_name {
875
763211
            fn from(o: Option<$struct_type>) -> $struct_name {
876
763211
                match o {
877
756198
                    None => $struct_name::None,
878
7013
                    Some(t) => $struct_name::Some(t),
879
                }
880
763211
            }
881
        }
882

            
883
        impl Default for $struct_name {
884
75434
            fn default() -> $struct_name {
885
75434
                $struct_name::None
886
75434
            }
887
        }
888

            
889
        impl $struct_name {
890
4
            pub fn as_option(&self) -> Option<&$struct_type> {
891
4
                match self {
892
2
                    $struct_name::None => None,
893
2
                    $struct_name::Some(t) => Some(t),
894
                }
895
4
            }
896
            pub fn replace(&mut self, value: $struct_type) -> $struct_name {
897
                ::core::mem::replace(self, $struct_name::Some(value))
898
            }
899
1
            pub fn is_some(&self) -> bool {
900
1
                match self {
901
1
                    $struct_name::None => false,
902
                    $struct_name::Some(_) => true,
903
                }
904
1
            }
905
1
            pub fn is_none(&self) -> bool {
906
1
                !self.is_some()
907
1
            }
908
453
            pub const fn as_ref(&self) -> Option<&$struct_type> {
909
453
                match *self {
910
401
                    $struct_name::Some(ref x) => Some(x),
911
52
                    $struct_name::None => None,
912
                }
913
453
            }
914
            pub fn as_mut(&mut self) -> Option<&mut $struct_type> {
915
                match self {
916
                    $struct_name::Some(x) => Some(x),
917
                    $struct_name::None => None,
918
                }
919
            }
920
            pub fn map<U, F: FnOnce($struct_type) -> U>(self, f: F) -> Option<U> {
921
                match self {
922
                    $struct_name::Some(x) => Some(f(x)),
923
                    $struct_name::None => None,
924
                }
925
            }
926
            pub fn and_then<U, F>(self, f: F) -> Option<U>
927
            where
928
                F: FnOnce($struct_type) -> Option<U>,
929
            {
930
                match self {
931
                    $struct_name::None => None,
932
                    $struct_name::Some(x) => f(x),
933
                }
934
            }
935
        }
936
    };
937
}
938

            
939
#[macro_export]
940
macro_rules! impl_option {
941
    ($struct_type:ident, $struct_name:ident, copy = false, clone = false, [$($derive:meta),* ]) => (
942
        $(#[derive($derive)])*
943
        #[repr(C, u8)]
944
        pub enum $struct_name {
945
            None,
946
            Some($struct_type)
947
        }
948

            
949
        impl $struct_name {
950
            pub fn into_option(self) -> Option<$struct_type> {
951
                match self {
952
                    $struct_name::None => None,
953
                    $struct_name::Some(t) => Some(t),
954
                }
955
            }
956
        }
957

            
958
        impl_option_inner!($struct_type, $struct_name);
959
    );
960
    ($struct_type:ident, $struct_name:ident, copy = false, [$($derive:meta),* ]) => (
961
        $(#[derive($derive)])*
962
        #[repr(C, u8)]
963
        pub enum $struct_name {
964
            None,
965
            Some($struct_type)
966
        }
967

            
968
        impl $struct_name {
969
42
            pub fn into_option(&self) -> Option<$struct_type> {
970
42
                match self {
971
42
                    $struct_name::None => None,
972
                    $struct_name::Some(t) => Some(t.clone()),
973
                }
974
42
            }
975
        }
976

            
977
        impl_option_inner!($struct_type, $struct_name);
978
    );
979
    ($struct_type:ident, $struct_name:ident, [$($derive:meta),* ]) => (
980
        $(#[derive($derive)])*
981
        #[repr(C, u8)]
982
        pub enum $struct_name {
983
            None,
984
            Some($struct_type)
985
        }
986

            
987
        impl $struct_name {
988
1204
            pub fn into_option(&self) -> Option<$struct_type> {
989
1204
                match self {
990
719
                    $struct_name::None => None,
991
485
                    $struct_name::Some(t) => Some(t.clone()),
992
                }
993
1204
            }
994
        }
995

            
996
        impl_option_inner!($struct_type, $struct_name);
997
    );
998
}
999

            
#[macro_export]
macro_rules! impl_result_inner {
    ($ok_struct_type:ident, $err_struct_type:ident, $struct_name:ident) => {
        impl From<$struct_name> for Result<$ok_struct_type, $err_struct_type> {
            fn from(o: $struct_name) -> Result<$ok_struct_type, $err_struct_type> {
                match o {
                    $struct_name::Ok(o) => Ok(o),
                    $struct_name::Err(e) => Err(e),
                }
            }
        }
        impl From<Result<$ok_struct_type, $err_struct_type>> for $struct_name {
            fn from(o: Result<$ok_struct_type, $err_struct_type>) -> $struct_name {
                match o {
                    Ok(o) => $struct_name::Ok(o),
                    Err(e) => $struct_name::Err(e),
                }
            }
        }
        impl $struct_name {
            pub fn as_result(&self) -> Result<&$ok_struct_type, &$err_struct_type> {
                match self {
                    $struct_name::Ok(o) => Ok(o),
                    $struct_name::Err(e) => Err(e),
                }
            }
            pub fn is_ok(&self) -> bool {
                match self {
                    $struct_name::Ok(_) => true,
                    $struct_name::Err(_) => false,
                }
            }
            pub fn is_err(&self) -> bool {
                !self.is_ok()
            }
        }
    };
}
#[macro_export]
macro_rules! impl_result {
    ($ok_struct_type:ident, $err_struct_type:ident, $struct_name:ident, copy = false, clone = false, [$($derive:meta),* ]) => (
        $(#[derive($derive)])*
        #[repr(C, u8)]
        pub enum $struct_name {
            Ok($ok_struct_type),
            Err($err_struct_type)
        }
        impl $struct_name {
            pub fn into_result(self) -> Result<$ok_struct_type, $err_struct_type> {
                match self {
                    $struct_name::Ok(o) => Ok(o),
                    $struct_name::Err(e) => Err(e),
                }
            }
        }
        impl_result_inner!($ok_struct_type, $err_struct_type, $struct_name);
    );
    ($ok_struct_type:ident, $err_struct_type:ident, $struct_name:ident, copy = false, [$($derive:meta),* ]) => (
        $(#[derive($derive)])*
        #[repr(C, u8)]
        pub enum $struct_name {
            Ok($ok_struct_type),
            Err($err_struct_type)
        }
        impl $struct_name {
            pub fn into_result(&self) -> Result<$ok_struct_type, $err_struct_type> {
                match self {
                    $struct_name::Ok(o) => Ok(o.clone()),
                    $struct_name::Err(e) => Err(e.clone()),
                }
            }
        }
        impl_result_inner!($ok_struct_type, $err_struct_type, $struct_name);
    );
    ($ok_struct_type:ident, $err_struct_type:ident,  $struct_name:ident, [$($derive:meta),* ]) => (
        $(#[derive($derive)])*
        #[repr(C, u8)]
        pub enum $struct_name {
            Ok($ok_struct_type),
            Err($err_struct_type)
        }
        impl $struct_name {
            pub fn into_result(&self) -> Result<$ok_struct_type, $err_struct_type> {
                match self {
                    $struct_name::Ok(o) => Ok(*o),
                    $struct_name::Err(e) => Err(*e),
                }
            }
        }
        impl_result_inner!($ok_struct_type, $err_struct_type, $struct_name);
    );
}
macro_rules! impl_color_value_fmt {
    ($struct_name:ty) => {
        impl FormatAsRustCode for $struct_name {
            fn format_as_rust_code(&self, _tabs: usize) -> String {
                format!(
                    "{} {{ inner: {} }}",
                    stringify!($struct_name),
                    format_color_value(&self.inner)
                )
            }
        }
    };
}
macro_rules! impl_enum_fmt {($enum_name:ident, $($enum_type:ident),+) => (
    impl crate::format_rust_code::FormatAsRustCode for $enum_name {
        fn format_as_rust_code(&self, _tabs: usize) -> String {
            match self {
                $(
                    $enum_name::$enum_type => {
                        String::from(
                            concat!(stringify!($enum_name), "::", stringify!($enum_type))
                        )
                    },
                )+
            }
        }
    }
)}