Skip to main content

azul_css/
macros.rs

1#[macro_export]
2macro_rules! impl_vec {
3    ($struct_type:ident, $struct_name:ident, $destructor_name:ident, $destructor_type_name:ident, $slice_name:ident, $option_type:ident) => {
4        pub type $destructor_type_name = extern "C" fn(*mut $struct_name);
5
6        /// C-compatible slice type for $struct_name.
7        /// This is a non-owning view into a Vec's data.
8        #[repr(C)]
9        #[derive(Debug, Copy, Clone)]
10        pub struct $slice_name {
11            pub ptr: *const $struct_type,
12            pub len: usize,
13        }
14
15        impl $slice_name {
16            /// Creates an empty slice.
17            #[inline(always)]
18            pub const fn empty() -> Self {
19                Self {
20                    ptr: core::ptr::null(),
21                    len: 0,
22                }
23            }
24
25            /// Returns the number of elements in the slice.
26            #[inline(always)]
27            pub const fn len(&self) -> usize {
28                self.len
29            }
30
31            /// Returns true if the slice is empty.
32            #[inline(always)]
33            pub const fn is_empty(&self) -> bool {
34                self.len == 0
35            }
36
37            /// Returns a pointer to the slice's data.
38            #[inline(always)]
39            pub const fn as_ptr(&self) -> *const $struct_type {
40                self.ptr
41            }
42
43            /// Converts the C-slice to a Rust slice.
44            #[inline(always)]
45            pub fn as_slice(&self) -> &[$struct_type] {
46                if self.ptr.is_null() || self.len == 0 {
47                    &[]
48                } else {
49                    unsafe { core::slice::from_raw_parts(self.ptr, self.len) }
50                }
51            }
52
53            /// Returns a reference to the element at the given index, or None if out of bounds.
54            #[inline(always)]
55            pub fn get(&self, index: usize) -> Option<&$struct_type> {
56                self.as_slice().get(index)
57            }
58
59            /// Returns an iterator over the elements.
60            #[inline]
61            pub fn iter(&self) -> core::slice::Iter<$struct_type> {
62                self.as_slice().iter()
63            }
64        }
65
66        unsafe impl Send for $slice_name {}
67        unsafe impl Sync for $slice_name {}
68
69        #[repr(C)]
70        pub struct $struct_name {
71            ptr: *const $struct_type,
72            len: usize,
73            cap: usize,
74            destructor: $destructor_name,
75            /// Whether to run the destructor on drop (prevents double-free when cloned to C)
76            pub run_destructor: bool,
77        }
78
79        #[derive(Debug, Copy, Clone)]
80        #[repr(C, u8)]
81        pub enum $destructor_name {
82            DefaultRust,
83            NoDestructor,
84            External($destructor_type_name),
85        }
86
87        unsafe impl Send for $struct_name {}
88        unsafe impl Sync for $struct_name {}
89
90        impl $struct_name {
91            #[inline(always)]
92            pub fn new() -> $struct_name {
93                // lets hope the optimizer catches this
94                Self::from_vec(alloc::vec::Vec::new())
95            }
96
97            #[inline]
98            pub fn with_capacity(cap: usize) -> Self {
99                Self::from_vec(alloc::vec::Vec::<$struct_type>::with_capacity(cap))
100            }
101
102            #[inline(always)]
103            pub const fn from_const_slice(input: &'static [$struct_type]) -> Self {
104                Self {
105                    ptr: input.as_ptr(),
106                    len: input.len(),
107                    cap: input.len(),
108                    destructor: $destructor_name::NoDestructor, // because of &'static
109                    run_destructor: false, // static slice, no destructor needed
110                }
111            }
112
113            #[inline(always)]
114            pub fn from_vec(input: alloc::vec::Vec<$struct_type>) -> Self {
115                let ptr = input.as_ptr();
116                let len = input.len();
117                let cap = input.capacity();
118
119                let _ = ::core::mem::ManuallyDrop::new(input);
120
121                Self {
122                    ptr,
123                    len,
124                    cap,
125                    destructor: $destructor_name::DefaultRust,
126                    run_destructor: true,
127                }
128            }
129
130            #[inline]
131            pub fn iter(&self) -> core::slice::Iter<$struct_type> {
132                self.as_ref().iter()
133            }
134
135            #[inline(always)]
136            pub fn ptr_as_usize(&self) -> usize {
137                self.ptr as usize
138            }
139
140            #[inline(always)]
141            pub const fn len(&self) -> usize {
142                self.len
143            }
144
145            #[inline(always)]
146            pub const fn capacity(&self) -> usize {
147                self.cap
148            }
149
150            #[inline(always)]
151            pub const fn is_empty(&self) -> bool {
152                self.len == 0
153            }
154
155            /// Returns a reference to the element at the given index (Rust-only, inline).
156            #[inline(always)]
157            pub fn get(&self, index: usize) -> Option<&$struct_type> {
158                let v1: &[$struct_type] = self.as_ref();
159                let res = v1.get(index);
160                res
161            }
162
163            /// C-API compatible get function. Returns a copy of the element at the given index.
164            /// Returns None if the index is out of bounds.
165            #[inline]
166            pub fn c_get(&self, index: usize) -> $option_type
167            where
168                $struct_type: Clone,
169            {
170                self.get(index).cloned().into()
171            }
172
173            #[allow(dead_code)]
174            #[inline(always)]
175            unsafe fn get_unchecked(&self, index: usize) -> &$struct_type {
176                let v1: &[$struct_type] = self.as_ref();
177                let res = v1.get_unchecked(index);
178                res
179            }
180
181            /// Returns the vec as a Rust slice (Rust-only, not C-API compatible).
182            #[inline(always)]
183            pub fn as_slice(&self) -> &[$struct_type] {
184                self.as_ref()
185            }
186
187            /// Returns a C-compatible slice of the entire Vec.
188            #[inline(always)]
189            pub fn as_c_slice(&self) -> $slice_name {
190                $slice_name {
191                    ptr: self.ptr,
192                    len: self.len,
193                }
194            }
195
196            /// Returns a C-compatible slice of a range within the Vec.
197            /// If the range is out of bounds, it is clamped to the valid range.
198            #[inline]
199            pub fn as_c_slice_range(&self, start: usize, end: usize) -> $slice_name {
200                let start = start.min(self.len);
201                let end = end.min(self.len).max(start);
202                let len = end - start;
203                if len == 0 || self.ptr.is_null() {
204                    $slice_name::empty()
205                } else {
206                    $slice_name {
207                        ptr: unsafe { self.ptr.add(start) },
208                        len,
209                    }
210                }
211            }
212
213            /// Returns a pointer to the Vec's data.
214            /// Use `len()` to get the number of elements.
215            #[inline(always)]
216            pub fn as_ptr(&self) -> *const $struct_type {
217                self.ptr
218            }
219        }
220
221        impl AsRef<[$struct_type]> for $struct_name {
222            fn as_ref(&self) -> &[$struct_type] {
223                unsafe { core::slice::from_raw_parts(self.ptr, self.len) }
224            }
225        }
226
227        impl Default for $struct_name {
228            fn default() -> Self {
229                Self::from_vec(alloc::vec::Vec::new())
230            }
231        }
232
233        impl core::iter::FromIterator<$struct_type> for $struct_name {
234            fn from_iter<T>(iter: T) -> Self
235            where
236                T: IntoIterator<Item = $struct_type>,
237            {
238                Self::from_vec(alloc::vec::Vec::from_iter(iter))
239            }
240        }
241
242        impl From<alloc::vec::Vec<$struct_type>> for $struct_name {
243            fn from(input: alloc::vec::Vec<$struct_type>) -> $struct_name {
244                $struct_name::from_vec(input)
245            }
246        }
247
248        impl From<&'static [$struct_type]> for $struct_name {
249            fn from(input: &'static [$struct_type]) -> $struct_name {
250                Self::from_const_slice(input)
251            }
252        }
253
254        impl Drop for $struct_name {
255            fn drop(&mut self) {
256                if !self.run_destructor {
257                    return;
258                }
259                match self.destructor {
260                    $destructor_name::DefaultRust => {
261                        let _ = unsafe {
262                            alloc::vec::Vec::from_raw_parts(
263                                self.ptr as *mut $struct_type,
264                                self.len,
265                                self.cap,
266                            )
267                        };
268                    }
269                    $destructor_name::NoDestructor => {}
270                    $destructor_name::External(f) => {
271                        f(self);
272                    }
273                }
274                // necessary so that double-frees are avoided
275                self.run_destructor = false;
276            }
277        }
278    };
279}
280
281/// Implement the `From` trait for any type.
282/// Example usage:
283/// ```no_run,ignore
284/// enum MyError<'a> {
285///     Bar(BarError<'a>),
286///     Foo(FooError<'a>)
287/// }
288///
289/// impl_from!(BarError<'a>, Error::Bar);
290/// impl_from!(BarError<'a>, Error::Bar);
291/// ```
292macro_rules! impl_from {
293    // From a type with a lifetime to a type which also has a lifetime
294    ($a:ident < $c:lifetime > , $b:ident:: $enum_type:ident) => {
295        impl<$c> From<$a<$c>> for $b<$c> {
296            fn from(e: $a<$c>) -> Self {
297                $b::$enum_type(e)
298            }
299        }
300    };
301
302    // From a type without a lifetime to a type with a lifetime
303    ($a:ident, $b:ident < $c:lifetime > :: $enum_type:ident) => {
304        impl<$c> From<$a> for $b<$c> {
305            fn from(e: $a) -> Self {
306                $b::$enum_type(e)
307            }
308        }
309    };
310
311    // From a type without a lifetime to a type which also does not have a lifetime
312    ($a:ident, $b:ident:: $enum_type:ident) => {
313        impl From<$a> for $b {
314            fn from(e: $a) -> Self {
315                $b::$enum_type(e)
316            }
317        }
318    };
319}
320
321/// Implement `Display` for an enum.
322///
323/// Example usage:
324/// ```no_run,ignore
325/// enum Foo<'a> {
326///     Bar(&'a str),
327///     Baz(i32)
328/// }
329///
330/// impl_display!{ Foo<'a>, {
331///     Bar(s) => s,
332///     Baz(i) => format!("{}", i)
333/// }}
334/// ```
335macro_rules! impl_display {
336    // For a type with a lifetime
337    ($enum:ident<$lt:lifetime>, {$($variant:pat => $fmt_string:expr),+$(,)* }) => {
338
339        impl<$lt> ::core::fmt::Display for $enum<$lt> {
340            fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
341                use self::$enum::*;
342                match &self {
343                    $(
344                        $variant => write!(f, "{}", $fmt_string),
345                    )+
346                }
347            }
348        }
349
350    };
351
352    // For a type without a lifetime
353    ($enum:ident, {$($variant:pat => $fmt_string:expr),+$(,)* }) => {
354
355        impl ::core::fmt::Display for $enum {
356            fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
357                use self::$enum::*;
358                match &self {
359                    $(
360                        $variant => write!(f, "{}", $fmt_string),
361                    )+
362                }
363            }
364        }
365
366    };
367}
368
369/// Implements `Debug` to use `Display` instead - assumes the that the type has implemented
370/// `Display`
371macro_rules! impl_debug_as_display {
372    // For a type with a lifetime
373    ($enum:ident < $lt:lifetime >) => {
374        impl<$lt> ::core::fmt::Debug for $enum<$lt> {
375            fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
376                write!(f, "{}", self)
377            }
378        }
379    };
380
381    // For a type without a lifetime
382    ($enum:ident) => {
383        impl ::core::fmt::Debug for $enum {
384            fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
385                write!(f, "{}", self)
386            }
387        }
388    };
389}
390
391#[macro_export]
392macro_rules! impl_vec_as_hashmap {
393    ($struct_type:ident, $struct_name:ident) => {
394        impl $struct_name {
395            pub fn insert_hm_item(&mut self, item: $struct_type) {
396                if !self.contains_hm_item(&item) {
397                    let mut vec = self.clone().into_library_owned_vec();
398                    vec.push(item);
399                    *self = Self::from_vec(vec);
400                }
401            }
402
403            pub fn remove_hm_item(&mut self, remove_key: &$struct_type) {
404                *self = Self::from_vec(
405                    self.as_ref()
406                        .iter()
407                        .filter_map(|r| if *r == *remove_key { None } else { Some(*r) })
408                        .collect::<Vec<_>>(),
409                );
410            }
411
412            pub fn contains_hm_item(&self, searched: &$struct_type) -> bool {
413                self.as_ref().iter().any(|i| i == searched)
414            }
415        }
416    };
417}
418
419/// NOTE: impl_vec_mut can only exist for vectors that are known to be library-allocated!
420#[macro_export]
421macro_rules! impl_vec_mut {
422    ($struct_type:ident, $struct_name:ident) => {
423        impl AsMut<[$struct_type]> for $struct_name {
424            fn as_mut(&mut self) -> &mut [$struct_type] {
425                unsafe { core::slice::from_raw_parts_mut(self.ptr as *mut $struct_type, self.len) }
426            }
427        }
428
429        impl From<$struct_name> for alloc::vec::Vec<$struct_type> {
430            #[allow(unused_mut)]
431            fn from(mut input: $struct_name) -> alloc::vec::Vec<$struct_type> {
432                input.into_library_owned_vec()
433            }
434        }
435
436        impl core::iter::Extend<$struct_type> for $struct_name {
437            fn extend<T: core::iter::IntoIterator<Item = $struct_type>>(&mut self, iter: T) {
438                for elem in iter {
439                    self.push(elem);
440                }
441            }
442        }
443
444        impl $struct_name {
445            // <'a> has to live longer thant &'self
446            pub fn as_mut_slice_extended<'a>(&mut self) -> &'a mut [$struct_type] {
447                unsafe { core::slice::from_raw_parts_mut(self.ptr as *mut $struct_type, self.len) }
448            }
449
450            #[inline]
451            pub fn as_mut_ptr(&mut self) -> *mut $struct_type {
452                self.ptr as *mut $struct_type
453            }
454
455            #[inline]
456            pub fn sort_by<F: FnMut(&$struct_type, &$struct_type) -> core::cmp::Ordering>(
457                &mut self,
458                compare: F,
459            ) {
460                self.as_mut().sort_by(compare);
461            }
462
463            #[inline]
464            pub fn push(&mut self, value: $struct_type) {
465                // code is copied from the rust stdlib, since it's not possible to
466                // create a temporary Vec here. Doing that would create two
467                if self.len == self.capacity() {
468                    self.buf_reserve(self.len, 1);
469                }
470                unsafe {
471                    let end = self.as_mut_ptr().add(self.len);
472                    core::ptr::write(end, value);
473                    self.len += 1;
474                }
475            }
476
477            pub fn insert(&mut self, index: usize, element: $struct_type) {
478                let len = self.len();
479                if index > len {
480                    return;
481                }
482
483                // space for the new element
484                if len == self.capacity() {
485                    self.reserve(1);
486                }
487
488                unsafe {
489                    // infallible
490                    // The spot to put the new value
491                    {
492                        let p = self.as_mut_ptr().add(index);
493                        // Shift everything over to make space. (Duplicating the
494                        // `index`th element into two consecutive places.)
495                        core::ptr::copy(p, p.offset(1), len - index);
496                        // Write it in, overwriting the first copy of the `index`th
497                        // element.
498                        core::ptr::write(p, element);
499                    }
500                    self.set_len(len + 1);
501                }
502            }
503
504            pub fn remove(&mut self, index: usize) {
505                let len = self.len();
506                if index >= len {
507                    return;
508                }
509
510                unsafe {
511                    // infallible
512                    let ret;
513                    {
514                        // the place we are taking from.
515                        let ptr = self.as_mut_ptr().add(index);
516                        // copy it out, unsafely having a copy of the value on
517                        // the stack and in the vector at the same time.
518                        ret = core::ptr::read(ptr);
519
520                        // Shift everything down to fill in that spot.
521                        core::ptr::copy(ptr.offset(1), ptr, len - index - 1);
522                    }
523                    self.set_len(len - 1);
524                    let _ = ret;
525                }
526            }
527
528            #[inline]
529            pub fn pop(&mut self) -> Option<$struct_type> {
530                if self.len == 0 {
531                    None
532                } else {
533                    unsafe {
534                        self.len -= 1;
535                        Some(core::ptr::read(self.ptr.add(self.len())))
536                    }
537                }
538            }
539
540            #[inline]
541            pub fn iter_mut(&mut self) -> core::slice::IterMut<$struct_type> {
542                self.as_mut().iter_mut()
543            }
544
545            #[inline]
546            pub fn into_iter(self) -> alloc::vec::IntoIter<$struct_type> {
547                let v1: alloc::vec::Vec<$struct_type> = self.into();
548                v1.into_iter()
549            }
550
551            #[inline]
552            fn amortized_new_size(
553                &self,
554                used_cap: usize,
555                needed_extra_cap: usize,
556            ) -> Result<usize, bool> {
557                // Nothing we can really do about these checks :(
558                let required_cap = used_cap.checked_add(needed_extra_cap).ok_or(true)?;
559                // Cannot overflow, because `cap <= isize::MAX`, and type of `cap` is `usize`.
560                let double_cap = self.cap * 2;
561                // `double_cap` guarantees exponential growth.
562                Ok(core::cmp::max(double_cap, required_cap))
563            }
564
565            #[inline]
566            fn current_layout(&self) -> Option<core::alloc::Layout> {
567                if self.cap == 0 {
568                    None
569                } else {
570                    // We have an allocated chunk of memory, so we can bypass runtime
571                    // checks to get our current layout.
572                    unsafe {
573                        let align = core::mem::align_of::<$struct_type>();
574                        let size = core::mem::size_of::<$struct_type>() * self.cap;
575                        Some(core::alloc::Layout::from_size_align_unchecked(size, align))
576                    }
577                }
578            }
579
580            #[inline]
581            fn alloc_guard(alloc_size: usize) -> Result<(), bool> {
582                if core::mem::size_of::<usize>() < 8 && alloc_size > ::core::isize::MAX as usize {
583                    Err(true)
584                } else {
585                    Ok(())
586                }
587            }
588
589            #[inline]
590            fn try_reserve(
591                &mut self,
592                used_cap: usize,
593                needed_extra_cap: usize,
594            ) -> Result<(), bool> {
595                // NOTE: we don't early branch on ZSTs here because we want this
596                // to actually catch "asking for more than usize::MAX" in that case.
597                // If we make it past the first branch then we are guaranteed to
598                // panic.
599
600                // Don't actually need any more capacity.
601                // Wrapping in case they give a bad `used_cap`
602                if self.capacity().wrapping_sub(used_cap) >= needed_extra_cap {
603                    return Ok(());
604                }
605
606                let new_cap = self.amortized_new_size(used_cap, needed_extra_cap)?;
607                let new_layout =
608                    alloc::alloc::Layout::array::<$struct_type>(new_cap).map_err(|_| true)?;
609
610                // FIXME: may crash and burn on over-reserve
611                $struct_name::alloc_guard(new_layout.size())?;
612
613                let res = unsafe {
614                    match self.current_layout() {
615                        Some(layout) => {
616                            alloc::alloc::realloc(self.ptr as *mut u8, layout, new_layout.size())
617                        }
618                        None => alloc::alloc::alloc(new_layout),
619                    }
620                };
621
622                if res == core::ptr::null_mut() {
623                    return Err(false);
624                }
625
626                self.ptr = res as *mut $struct_type;
627                self.cap = new_cap;
628
629                Ok(())
630            }
631
632            fn buf_reserve(&mut self, used_cap: usize, needed_extra_cap: usize) {
633                match self.try_reserve(used_cap, needed_extra_cap) {
634                    Err(true /* Overflow */) => {
635                        panic!("memory allocation failed: overflow");
636                    }
637                    Err(false /* AllocError(_) */) => {
638                        panic!("memory allocation failed: error allocating new memory");
639                    }
640                    Ok(()) => { /* yay */ }
641                }
642            }
643
644            pub fn append(&mut self, other: &mut Self) {
645                unsafe {
646                    self.append_elements(other.as_slice() as _);
647                    other.set_len(0);
648                }
649            }
650
651            unsafe fn set_len(&mut self, new_len: usize) {
652                debug_assert!(new_len <= self.capacity());
653                self.len = new_len;
654            }
655
656            pub fn reserve(&mut self, additional: usize) {
657                self.buf_reserve(self.len, additional);
658            }
659
660            /// Appends elements to `Self` from other buffer.
661            #[inline]
662            unsafe fn append_elements(&mut self, other: *const [$struct_type]) {
663                let count = (&(*other)).len();
664                self.reserve(count);
665                let len = self.len();
666                core::ptr::copy_nonoverlapping(
667                    other as *const $struct_type,
668                    self.as_mut_ptr().add(len),
669                    count,
670                );
671                self.len += count;
672            }
673
674            pub fn truncate(&mut self, len: usize) {
675                // This is safe because:
676                //
677                // * the slice passed to `drop_in_place` is valid; the `len > self.len` case avoids
678                //   creating an invalid slice, and
679                // * the `len` of the vector is shrunk before calling `drop_in_place`, such that no
680                //   value will be dropped twice in case `drop_in_place` were to panic once (if it
681                //   panics twice, the program aborts).
682                unsafe {
683                    if len > self.len {
684                        return;
685                    }
686                    let remaining_len = self.len - len;
687                    let s = core::ptr::slice_from_raw_parts_mut(
688                        self.as_mut_ptr().add(len),
689                        remaining_len,
690                    );
691                    self.len = len;
692                    core::ptr::drop_in_place(s);
693                }
694            }
695
696            pub fn retain<F>(&mut self, mut f: F)
697            where
698                F: FnMut(&$struct_type) -> bool,
699            {
700                let len = self.len();
701                let mut del = 0;
702
703                {
704                    for i in 0..len {
705                        if unsafe { !f(self.get_unchecked(i)) } {
706                            del += 1;
707                        } else if del > 0 {
708                            self.as_mut().swap(i - del, i);
709                        }
710                    }
711                }
712
713                if del > 0 {
714                    self.truncate(len - del);
715                }
716            }
717        }
718    };
719}
720
721#[macro_export]
722macro_rules! impl_vec_debug {
723    ($struct_type:ident, $struct_name:ident) => {
724        impl core::fmt::Debug for $struct_name {
725            fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
726                self.as_ref().fmt(f)
727            }
728        }
729    };
730}
731
732#[macro_export]
733macro_rules! impl_vec_partialord {
734    ($struct_type:ident, $struct_name:ident) => {
735        impl PartialOrd for $struct_name {
736            fn partial_cmp(&self, rhs: &Self) -> Option<core::cmp::Ordering> {
737                self.as_ref().partial_cmp(rhs.as_ref())
738            }
739        }
740    };
741}
742
743#[macro_export]
744macro_rules! impl_vec_ord {
745    ($struct_type:ident, $struct_name:ident) => {
746        impl Ord for $struct_name {
747            fn cmp(&self, rhs: &Self) -> core::cmp::Ordering {
748                self.as_ref().cmp(rhs.as_ref())
749            }
750        }
751    };
752}
753
754#[macro_export]
755macro_rules! impl_vec_clone {
756    ($struct_type:ident, $struct_name:ident, $destructor_name:ident) => {
757        impl $struct_name {
758            // Creates a `Vec` from a `Cow<'static, [T]>` - useful to avoid allocating in the case
759            // of &'static memory
760            #[inline(always)]
761            pub fn from_copy_on_write(
762                input: alloc::borrow::Cow<'static, [$struct_type]>,
763            ) -> $struct_name {
764                match input {
765                    alloc::borrow::Cow::Borrowed(static_array) => {
766                        Self::from_const_slice(static_array)
767                    }
768                    alloc::borrow::Cow::Owned(owned_vec) => Self::from_vec(owned_vec),
769                }
770            }
771
772            /// Creates a Vec containing a single element
773            #[inline(always)]
774            pub fn from_item(item: $struct_type) -> Self {
775                Self::from_vec(alloc::vec![item])
776            }
777
778            /// Copies elements from a C array pointer into a new Vec.
779            /// 
780            /// # Safety
781            /// - `ptr` must be valid for reading `len` elements
782            /// - The memory must be properly aligned for `$struct_type`
783            /// - The elements are cloned, so `$struct_type` must implement `Clone`
784            #[inline]
785            pub unsafe fn copy_from_ptr(ptr: *const $struct_type, len: usize) -> Self {
786                if ptr.is_null() || len == 0 {
787                    return Self::new();
788                }
789                let slice = core::slice::from_raw_parts(ptr, len);
790                Self::from_vec(slice.to_vec())
791            }
792
793            /// NOTE: CLONES the memory if the memory is external or &'static
794            /// Moves the memory out if the memory is library-allocated
795            #[inline(always)]
796            pub fn clone_self(&self) -> Self {
797                match self.destructor {
798                    $destructor_name::NoDestructor => Self {
799                        ptr: self.ptr,
800                        len: self.len,
801                        cap: self.cap,
802                        destructor: $destructor_name::NoDestructor,
803                        run_destructor: false,
804                    },
805                    $destructor_name::External(_) | $destructor_name::DefaultRust => {
806                        Self::from_vec(self.as_ref().to_vec())
807                    }
808                }
809            }
810
811            /// NOTE: CLONES the memory if the memory is external or &'static
812            /// Moves the memory out if the memory is library-allocated
813            #[inline(always)]
814            pub fn into_library_owned_vec(self) -> alloc::vec::Vec<$struct_type> {
815                match self.destructor {
816                    $destructor_name::NoDestructor | $destructor_name::External(_) => {
817                        self.as_ref().to_vec()
818                    }
819                    $destructor_name::DefaultRust => {
820                        let v = unsafe {
821                            alloc::vec::Vec::from_raw_parts(
822                                self.ptr as *mut $struct_type,
823                                self.len,
824                                self.cap,
825                            )
826                        };
827                        core::mem::forget(self);
828                        v
829                    }
830                }
831            }
832        }
833        impl Clone for $struct_name {
834            fn clone(&self) -> Self {
835                self.clone_self()
836            }
837        }
838    };
839}
840
841#[macro_export]
842macro_rules! impl_vec_partialeq {
843    ($struct_type:ident, $struct_name:ident) => {
844        impl PartialEq for $struct_name {
845            fn eq(&self, rhs: &Self) -> bool {
846                self.as_ref().eq(rhs.as_ref())
847            }
848        }
849    };
850}
851
852#[macro_export]
853macro_rules! impl_vec_eq {
854    ($struct_type:ident, $struct_name:ident) => {
855        impl Eq for $struct_name {}
856    };
857}
858
859#[macro_export]
860macro_rules! impl_vec_hash {
861    ($struct_type:ident, $struct_name:ident) => {
862        impl core::hash::Hash for $struct_name {
863            fn hash<H>(&self, state: &mut H)
864            where
865                H: core::hash::Hasher,
866            {
867                self.as_ref().hash(state);
868            }
869        }
870    };
871}
872
873#[macro_export]
874macro_rules! impl_option_inner {
875    ($struct_type:ident, $struct_name:ident) => {
876        impl From<$struct_name> for Option<$struct_type> {
877            fn from(o: $struct_name) -> Option<$struct_type> {
878                match o {
879                    $struct_name::None => None,
880                    $struct_name::Some(t) => Some(t),
881                }
882            }
883        }
884
885        impl From<Option<$struct_type>> for $struct_name {
886            fn from(o: Option<$struct_type>) -> $struct_name {
887                match o {
888                    None => $struct_name::None,
889                    Some(t) => $struct_name::Some(t),
890                }
891            }
892        }
893
894        impl Default for $struct_name {
895            fn default() -> $struct_name {
896                $struct_name::None
897            }
898        }
899
900        impl $struct_name {
901            pub fn as_option(&self) -> Option<&$struct_type> {
902                match self {
903                    $struct_name::None => None,
904                    $struct_name::Some(t) => Some(t),
905                }
906            }
907            pub fn replace(&mut self, value: $struct_type) -> $struct_name {
908                ::core::mem::replace(self, $struct_name::Some(value))
909            }
910            pub fn is_some(&self) -> bool {
911                match self {
912                    $struct_name::None => false,
913                    $struct_name::Some(_) => true,
914                }
915            }
916            pub fn is_none(&self) -> bool {
917                !self.is_some()
918            }
919            pub const fn as_ref(&self) -> Option<&$struct_type> {
920                match *self {
921                    $struct_name::Some(ref x) => Some(x),
922                    $struct_name::None => None,
923                }
924            }
925            pub fn as_mut(&mut self) -> Option<&mut $struct_type> {
926                match self {
927                    $struct_name::Some(x) => Some(x),
928                    $struct_name::None => None,
929                }
930            }
931            pub fn map<U, F: FnOnce($struct_type) -> U>(self, f: F) -> Option<U> {
932                match self {
933                    $struct_name::Some(x) => Some(f(x)),
934                    $struct_name::None => None,
935                }
936            }
937            pub fn and_then<U, F>(self, f: F) -> Option<U>
938            where
939                F: FnOnce($struct_type) -> Option<U>,
940            {
941                match self {
942                    $struct_name::None => None,
943                    $struct_name::Some(x) => f(x),
944                }
945            }
946        }
947    };
948}
949
950#[macro_export]
951macro_rules! impl_option {
952    ($struct_type:ident, $struct_name:ident, copy = false, clone = false, [$($derive:meta),* ]) => (
953        $(#[derive($derive)])*
954        #[repr(C, u8)]
955        pub enum $struct_name {
956            None,
957            Some($struct_type)
958        }
959
960        impl $struct_name {
961            pub fn into_option(self) -> Option<$struct_type> {
962                match self {
963                    $struct_name::None => None,
964                    $struct_name::Some(t) => Some(t),
965                }
966            }
967        }
968
969        impl_option_inner!($struct_type, $struct_name);
970    );
971    ($struct_type:ident, $struct_name:ident, copy = false, [$($derive:meta),* ]) => (
972        $(#[derive($derive)])*
973        #[repr(C, u8)]
974        pub enum $struct_name {
975            None,
976            Some($struct_type)
977        }
978
979        impl $struct_name {
980            pub fn into_option(&self) -> Option<$struct_type> {
981                match self {
982                    $struct_name::None => None,
983                    $struct_name::Some(t) => Some(t.clone()),
984                }
985            }
986        }
987
988        impl_option_inner!($struct_type, $struct_name);
989    );
990    ($struct_type:ident, $struct_name:ident, [$($derive:meta),* ]) => (
991        $(#[derive($derive)])*
992        #[repr(C, u8)]
993        pub enum $struct_name {
994            None,
995            Some($struct_type)
996        }
997
998        impl $struct_name {
999            pub fn into_option(&self) -> Option<$struct_type> {
1000                match self {
1001                    $struct_name::None => None,
1002                    $struct_name::Some(t) => Some(t.clone()),
1003                }
1004            }
1005        }
1006
1007        impl_option_inner!($struct_type, $struct_name);
1008    );
1009}
1010
1011#[macro_export]
1012macro_rules! impl_result_inner {
1013    ($ok_struct_type:ident, $err_struct_type:ident, $struct_name:ident) => {
1014        impl From<$struct_name> for Result<$ok_struct_type, $err_struct_type> {
1015            fn from(o: $struct_name) -> Result<$ok_struct_type, $err_struct_type> {
1016                match o {
1017                    $struct_name::Ok(o) => Ok(o),
1018                    $struct_name::Err(e) => Err(e),
1019                }
1020            }
1021        }
1022
1023        impl From<Result<$ok_struct_type, $err_struct_type>> for $struct_name {
1024            fn from(o: Result<$ok_struct_type, $err_struct_type>) -> $struct_name {
1025                match o {
1026                    Ok(o) => $struct_name::Ok(o),
1027                    Err(e) => $struct_name::Err(e),
1028                }
1029            }
1030        }
1031
1032        impl $struct_name {
1033            pub fn as_result(&self) -> Result<&$ok_struct_type, &$err_struct_type> {
1034                match self {
1035                    $struct_name::Ok(o) => Ok(o),
1036                    $struct_name::Err(e) => Err(e),
1037                }
1038            }
1039            pub fn is_ok(&self) -> bool {
1040                match self {
1041                    $struct_name::Ok(_) => true,
1042                    $struct_name::Err(_) => false,
1043                }
1044            }
1045            pub fn is_err(&self) -> bool {
1046                !self.is_ok()
1047            }
1048        }
1049    };
1050}
1051
1052#[macro_export]
1053macro_rules! impl_result {
1054    ($ok_struct_type:ident, $err_struct_type:ident, $struct_name:ident, copy = false, clone = false, [$($derive:meta),* ]) => (
1055        $(#[derive($derive)])*
1056        #[repr(C, u8)]
1057        pub enum $struct_name {
1058            Ok($ok_struct_type),
1059            Err($err_struct_type)
1060        }
1061
1062        impl $struct_name {
1063            pub fn into_result(self) -> Result<$ok_struct_type, $err_struct_type> {
1064                match self {
1065                    $struct_name::Ok(o) => Ok(o),
1066                    $struct_name::Err(e) => Err(e),
1067                }
1068            }
1069        }
1070
1071        impl_result_inner!($ok_struct_type, $err_struct_type, $struct_name);
1072    );
1073    ($ok_struct_type:ident, $err_struct_type:ident, $struct_name:ident, copy = false, [$($derive:meta),* ]) => (
1074        $(#[derive($derive)])*
1075        #[repr(C, u8)]
1076        pub enum $struct_name {
1077            Ok($ok_struct_type),
1078            Err($err_struct_type)
1079        }
1080        impl $struct_name {
1081            pub fn into_result(&self) -> Result<$ok_struct_type, $err_struct_type> {
1082                match self {
1083                    $struct_name::Ok(o) => Ok(o.clone()),
1084                    $struct_name::Err(e) => Err(e.clone()),
1085                }
1086            }
1087        }
1088
1089        impl_result_inner!($ok_struct_type, $err_struct_type, $struct_name);
1090    );
1091    ($ok_struct_type:ident, $err_struct_type:ident,  $struct_name:ident, [$($derive:meta),* ]) => (
1092        $(#[derive($derive)])*
1093        #[repr(C, u8)]
1094        pub enum $struct_name {
1095            Ok($ok_struct_type),
1096            Err($err_struct_type)
1097        }
1098
1099        impl $struct_name {
1100            pub fn into_result(&self) -> Result<$ok_struct_type, $err_struct_type> {
1101                match self {
1102                    $struct_name::Ok(o) => Ok(*o),
1103                    $struct_name::Err(e) => Err(*e),
1104                }
1105            }
1106        }
1107
1108        impl_result_inner!($ok_struct_type, $err_struct_type, $struct_name);
1109    );
1110}
1111
1112macro_rules! impl_grid_value_fmt {
1113    ($struct_name:ident) => {
1114        impl FormatAsRustCode for $struct_name {
1115            fn format_as_rust_code(&self, _tabs: usize) -> String {
1116                format!("{} {{ /* TODO */ }}", stringify!($struct_name))
1117            }
1118        }
1119    };
1120}
1121
1122macro_rules! impl_color_value_fmt {
1123    ($struct_name:ty) => {
1124        impl FormatAsRustCode for $struct_name {
1125            fn format_as_rust_code(&self, _tabs: usize) -> String {
1126                format!(
1127                    "{} {{ inner: {} }}",
1128                    stringify!($struct_name),
1129                    format_color_value(&self.inner)
1130                )
1131            }
1132        }
1133    };
1134}
1135
1136macro_rules! impl_enum_fmt {($enum_name:ident, $($enum_type:ident),+) => (
1137    impl crate::format_rust_code::FormatAsRustCode for $enum_name {
1138        fn format_as_rust_code(&self, _tabs: usize) -> String {
1139            match self {
1140                $(
1141                    $enum_name::$enum_type => {
1142                        String::from(
1143                            concat!(stringify!($enum_name), "::", stringify!($enum_type))
1144                        )
1145                    },
1146                )+
1147            }
1148        }
1149    }
1150)}