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