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 #[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 #[inline(always)]
18 pub const fn empty() -> Self {
19 Self {
20 ptr: core::ptr::null(),
21 len: 0,
22 }
23 }
24
25 #[inline(always)]
27 pub const fn len(&self) -> usize {
28 self.len
29 }
30
31 #[inline(always)]
33 pub const fn is_empty(&self) -> bool {
34 self.len == 0
35 }
36
37 #[inline(always)]
39 pub const fn as_ptr(&self) -> *const $struct_type {
40 self.ptr
41 }
42
43 #[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 #[inline(always)]
55 pub fn get(&self, index: usize) -> Option<&$struct_type> {
56 self.as_slice().get(index)
57 }
58
59 #[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 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 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, run_destructor: false, }
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 #[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 #[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 #[inline(always)]
183 pub fn as_slice(&self) -> &[$struct_type] {
184 self.as_ref()
185 }
186
187 #[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 #[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 #[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 self.run_destructor = false;
276 }
277 }
278 };
279}
280
281macro_rules! impl_from {
293 ($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 ($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 ($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
321macro_rules! impl_display {
336 ($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 ($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
369macro_rules! impl_debug_as_display {
372 ($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 ($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#[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 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 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 if len == self.capacity() {
485 self.reserve(1);
486 }
487
488 unsafe {
489 {
492 let p = self.as_mut_ptr().add(index);
493 core::ptr::copy(p, p.offset(1), len - index);
496 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 let ret;
513 {
514 let ptr = self.as_mut_ptr().add(index);
516 ret = core::ptr::read(ptr);
519
520 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 let required_cap = used_cap.checked_add(needed_extra_cap).ok_or(true)?;
559 let double_cap = self.cap * 2;
561 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 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 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 $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 ) => {
635 panic!("memory allocation failed: overflow");
636 }
637 Err(false ) => {
638 panic!("memory allocation failed: error allocating new memory");
639 }
640 Ok(()) => { }
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 #[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 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 #[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 #[inline(always)]
774 pub fn from_item(item: $struct_type) -> Self {
775 Self::from_vec(alloc::vec![item])
776 }
777
778 #[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 #[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 #[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)}