1#[macro_export]
9macro_rules! impl_vec {
10 ($struct_type:ident, $struct_name:ident, $destructor_name:ident, $destructor_type_name:ident, $slice_name:ident, $option_type:ident) => {
11 pub type $destructor_type_name = extern "C" fn(*mut $struct_name);
12
13 #[repr(C)]
16 #[derive(Debug, Copy, Clone)]
17 pub struct $slice_name {
18 pub ptr: *const $struct_type,
19 pub len: usize,
20 }
21
22 impl $slice_name {
23 #[inline]
25 #[must_use] pub const fn empty() -> Self {
26 Self {
27 ptr: core::ptr::null(),
28 len: 0,
29 }
30 }
31
32 #[inline]
34 #[must_use] pub const fn len(&self) -> usize {
35 self.len
36 }
37
38 #[inline]
40 #[must_use] pub const fn is_empty(&self) -> bool {
41 self.len == 0
42 }
43
44 #[inline]
46 #[must_use] pub const fn as_ptr(&self) -> *const $struct_type {
47 self.ptr
48 }
49
50 #[inline]
52 #[must_use] pub const fn as_slice(&self) -> &[$struct_type] {
53 if self.ptr.is_null() || self.len == 0 {
54 &[]
55 } else {
56 unsafe { core::slice::from_raw_parts(self.ptr, self.len) }
57 }
58 }
59
60 #[inline]
62 #[must_use] pub fn get(&self, index: usize) -> Option<&$struct_type> {
63 self.as_slice().get(index)
64 }
65
66 #[inline]
68 pub fn iter(&self) -> core::slice::Iter<'_, $struct_type> {
69 self.as_slice().iter()
70 }
71 }
72
73 unsafe impl Send for $slice_name {}
74 unsafe impl Sync for $slice_name {}
75
76 impl<'a> IntoIterator for &'a $slice_name {
77 type Item = &'a $struct_type;
78 type IntoIter = core::slice::Iter<'a, $struct_type>;
79 #[inline]
80 fn into_iter(self) -> Self::IntoIter {
81 self.iter()
82 }
83 }
84
85 impl<'a> IntoIterator for &'a $struct_name {
86 type Item = &'a $struct_type;
87 type IntoIter = core::slice::Iter<'a, $struct_type>;
88 #[inline]
89 fn into_iter(self) -> Self::IntoIter {
90 self.iter()
91 }
92 }
93
94 #[repr(C)]
95 pub struct $struct_name {
96 ptr: *const $struct_type,
97 len: usize,
98 cap: usize,
99 destructor: $destructor_name,
100 }
101
102 #[derive(Debug, Copy, Clone)]
103 #[repr(C, u8)]
104 pub enum $destructor_name {
105 DefaultRust,
106 NoDestructor,
107 External($destructor_type_name),
108 AlreadyDestroyed,
111 }
112
113 unsafe impl Send for $struct_name {}
114 unsafe impl Sync for $struct_name {}
115
116 impl $struct_name {
117 #[inline]
118 #[must_use] pub const fn new() -> $struct_name {
119 Self::from_vec(alloc::vec::Vec::new())
121 }
122
123 #[inline]
124 #[must_use] pub fn with_capacity(cap: usize) -> Self {
125 Self::from_vec(alloc::vec::Vec::<$struct_type>::with_capacity(cap))
126 }
127
128 #[inline]
129 #[must_use] pub const fn from_const_slice(input: &'static [$struct_type]) -> Self {
130 Self {
131 ptr: input.as_ptr(),
132 len: input.len(),
133 cap: input.len(),
134 destructor: $destructor_name::NoDestructor, }
136 }
137
138 #[inline]
139 #[must_use] pub const fn from_vec(input: alloc::vec::Vec<$struct_type>) -> Self {
140 let ptr = input.as_ptr();
141 let len = input.len();
142 let cap = input.capacity();
143
144 let _ = ::core::mem::ManuallyDrop::new(input);
145
146 Self {
147 ptr,
148 len,
149 cap,
150 destructor: $destructor_name::DefaultRust,
151 }
152 }
153
154 #[inline]
155 pub fn iter(&self) -> core::slice::Iter<'_, $struct_type> {
156 self.as_ref().iter()
157 }
158
159 #[inline]
160 #[must_use] pub const fn len(&self) -> usize {
161 self.len
162 }
163
164 #[inline]
165 #[must_use] pub const fn capacity(&self) -> usize {
166 self.cap
167 }
168
169 #[inline]
170 #[must_use] pub const fn is_empty(&self) -> bool {
171 self.len == 0
172 }
173
174 #[inline]
176 #[must_use] pub fn get(&self, index: usize) -> Option<&$struct_type> {
177 self.as_ref().get(index)
178 }
179
180 #[inline]
183 #[must_use] pub fn c_get(&self, index: usize) -> $option_type
184 where
185 $struct_type: Clone,
186 {
187 self.get(index).cloned().into()
188 }
189
190 #[allow(dead_code)]
191 #[inline]
192 unsafe fn get_unchecked(&self, index: usize) -> &$struct_type { unsafe {
193 self.as_ref().get_unchecked(index)
194 }}
195
196 #[inline]
198 #[must_use] pub fn as_slice(&self) -> &[$struct_type] {
199 self.as_ref()
200 }
201
202 #[inline]
204 #[must_use] pub const fn as_c_slice(&self) -> $slice_name {
205 $slice_name {
206 ptr: self.ptr,
207 len: self.len,
208 }
209 }
210
211 #[inline]
214 #[must_use] pub fn as_c_slice_range(&self, start: usize, end: usize) -> $slice_name {
215 let start = start.min(self.len);
216 let end = end.min(self.len).max(start);
217 let len = end - start;
218 if len == 0 || self.ptr.is_null() {
219 $slice_name::empty()
220 } else {
221 $slice_name {
222 ptr: unsafe { self.ptr.add(start) },
223 len,
224 }
225 }
226 }
227
228 #[inline]
231 #[must_use] pub const fn as_ptr(&self) -> *const $struct_type {
232 self.ptr
233 }
234 }
235
236 impl AsRef<[$struct_type]> for $struct_name {
237 fn as_ref(&self) -> &[$struct_type] {
238 if self.ptr.is_null() || self.len == 0 {
239 &[]
240 } else {
241 unsafe { core::slice::from_raw_parts(self.ptr, self.len) }
242 }
243 }
244 }
245
246 impl Default for $struct_name {
247 fn default() -> Self {
248 Self::from_vec(alloc::vec::Vec::new())
249 }
250 }
251
252 impl core::iter::FromIterator<$struct_type> for $struct_name {
253 fn from_iter<T>(iter: T) -> Self
254 where
255 T: IntoIterator<Item = $struct_type>,
256 {
257 Self::from_vec(alloc::vec::Vec::from_iter(iter))
258 }
259 }
260
261 impl From<alloc::vec::Vec<$struct_type>> for $struct_name {
262 fn from(input: alloc::vec::Vec<$struct_type>) -> $struct_name {
263 $struct_name::from_vec(input)
264 }
265 }
266
267 impl From<&'static [$struct_type]> for $struct_name {
268 fn from(input: &'static [$struct_type]) -> $struct_name {
269 Self::from_const_slice(input)
270 }
271 }
272
273 impl Drop for $struct_name {
274 fn drop(&mut self) {
275 match self.destructor {
276 $destructor_name::DefaultRust => {
277 if !self.ptr.is_null() && self.cap != 0 {
286 drop(unsafe {
287 alloc::vec::Vec::from_raw_parts(
288 self.ptr.cast_mut(),
289 self.len,
290 self.cap,
291 )
292 });
293 }
294 self.destructor = $destructor_name::AlreadyDestroyed;
295 }
296 $destructor_name::External(f) => {
297 f(self);
298 self.destructor = $destructor_name::AlreadyDestroyed;
299 }
300 $destructor_name::NoDestructor | $destructor_name::AlreadyDestroyed => {}
301 }
302 }
303 }
304 };
305}
306
307macro_rules! impl_from {
319 ($a:ident < $c:lifetime > , $b:ident:: $enum_type:ident) => {
321 impl<$c> From<$a<$c>> for $b<$c> {
322 fn from(e: $a<$c>) -> Self {
323 $b::$enum_type(e)
324 }
325 }
326 };
327
328 ($a:ident, $b:ident:: $enum_type:ident) => {
334 impl From<$a> for $b {
335 fn from(e: $a) -> Self {
336 $b::$enum_type(e)
337 }
338 }
339 };
340}
341
342#[macro_export]
357macro_rules! impl_display {
358 ($enum:ident<$lt:lifetime>, {$($variant:pat => $fmt_string:expr),+$(,)* }) => {
360
361 impl ::core::fmt::Display for $enum<'_> {
362 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
363 use self::$enum::*;
364 match &self {
365 $(
366 $variant => write!(f, "{}", $fmt_string),
367 )+
368 }
369 }
370 }
371
372 };
373
374 ($enum:ident, {$($variant:pat => $fmt_string:expr),+$(,)* }) => {
376
377 impl ::core::fmt::Display for $enum {
378 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
379 use self::$enum::*;
380 match &self {
381 $(
382 $variant => write!(f, "{}", $fmt_string),
383 )+
384 }
385 }
386 }
387
388 };
389}
390
391#[macro_export]
394macro_rules! impl_debug_as_display {
395 ($enum:ident < $lt:lifetime >) => {
397 impl ::core::fmt::Debug for $enum<'_> {
398 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
399 write!(f, "{}", self)
400 }
401 }
402 };
403
404 ($enum:ident) => {
406 impl ::core::fmt::Debug for $enum {
407 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
408 write!(f, "{}", self)
409 }
410 }
411 };
412}
413
414#[macro_export]
415macro_rules! impl_vec_as_hashmap {
416 ($struct_type:ident, $struct_name:ident) => {
417 impl $struct_name {
418 pub fn insert_hm_item(&mut self, item: $struct_type) {
419 if !self.contains_hm_item(&item) {
420 self.push(item);
421 }
422 }
423
424 pub fn remove_hm_item(&mut self, remove_key: &$struct_type) {
425 *self = Self::from_vec(
426 self.as_ref()
427 .iter()
428 .filter_map(|r| if *r == *remove_key { None } else { Some(*r) })
429 .collect::<Vec<_>>(),
430 );
431 }
432
433 pub fn contains_hm_item(&self, searched: &$struct_type) -> bool {
434 self.as_ref().iter().any(|i| i == searched)
435 }
436 }
437 };
438}
439
440#[macro_export]
442macro_rules! impl_vec_mut {
443 ($struct_type:ident, $struct_name:ident) => {
444 impl<'a> IntoIterator for &'a mut $struct_name {
445 type Item = &'a mut $struct_type;
446 type IntoIter = core::slice::IterMut<'a, $struct_type>;
447 #[inline]
448 fn into_iter(self) -> Self::IntoIter {
449 self.iter_mut()
450 }
451 }
452
453 impl AsMut<[$struct_type]> for $struct_name {
454 fn as_mut(&mut self) -> &mut [$struct_type] {
455 unsafe { core::slice::from_raw_parts_mut(self.ptr.cast_mut(), self.len) }
456 }
457 }
458
459 impl From<$struct_name> for alloc::vec::Vec<$struct_type> {
460 #[allow(unused_mut)]
461 fn from(mut input: $struct_name) -> alloc::vec::Vec<$struct_type> {
462 input.into_library_owned_vec()
463 }
464 }
465
466 impl core::iter::Extend<$struct_type> for $struct_name {
467 fn extend<T: core::iter::IntoIterator<Item = $struct_type>>(&mut self, iter: T) {
468 for elem in iter {
469 self.push(elem);
470 }
471 }
472 }
473
474 impl $struct_name {
475 #[inline]
476 pub const fn as_mut_ptr(&mut self) -> *mut $struct_type {
477 self.ptr.cast_mut()
478 }
479
480 #[inline]
481 pub fn sort_by<F: FnMut(&$struct_type, &$struct_type) -> core::cmp::Ordering>(
482 &mut self,
483 compare: F,
484 ) {
485 self.as_mut().sort_by(compare);
486 }
487
488 #[inline]
489 pub fn push(&mut self, value: $struct_type) {
490 if self.len == self.capacity() {
493 self.buf_reserve(self.len, 1);
494 }
495 unsafe {
496 let end = self.as_mut_ptr().add(self.len);
497 core::ptr::write(end, value);
498 self.len += 1;
499 }
500 }
501
502 pub fn insert(&mut self, index: usize, element: $struct_type) {
503 let len = self.len();
504 if index > len {
505 return;
506 }
507
508 if len == self.capacity() {
510 self.reserve(1);
511 }
512
513 unsafe {
514 {
517 let p = self.as_mut_ptr().add(index);
518 core::ptr::copy(p, p.offset(1), len - index);
521 core::ptr::write(p, element);
524 }
525 self.set_len(len + 1);
526 }
527 }
528
529 pub fn remove(&mut self, index: usize) {
530 let len = self.len();
531 if index >= len {
532 return;
533 }
534
535 unsafe {
536 let ret;
538 {
539 let ptr = self.as_mut_ptr().add(index);
541 ret = core::ptr::read(ptr);
544
545 core::ptr::copy(ptr.offset(1), ptr, len - index - 1);
547 }
548 self.set_len(len - 1);
549 let _ret = ret;
555 }
556 }
557
558 #[inline]
559 pub const fn pop(&mut self) -> Option<$struct_type> {
560 if self.len == 0 {
561 None
562 } else {
563 unsafe {
564 self.len -= 1;
565 Some(core::ptr::read(self.ptr.add(self.len())))
566 }
567 }
568 }
569
570 #[inline]
571 pub fn iter_mut(&mut self) -> core::slice::IterMut<'_, $struct_type> {
572 self.as_mut().iter_mut()
573 }
574
575 #[inline]
576 #[must_use] pub fn into_iter(self) -> alloc::vec::IntoIter<$struct_type> {
577 let v1: alloc::vec::Vec<$struct_type> = self.into();
578 v1.into_iter()
579 }
580
581 #[inline]
582 fn amortized_new_size(
583 &self,
584 used_cap: usize,
585 needed_extra_cap: usize,
586 ) -> Result<usize, bool> {
587 let required_cap = used_cap.checked_add(needed_extra_cap).ok_or(true)?;
589 let double_cap = self.cap * 2;
591 Ok(core::cmp::max(double_cap, required_cap))
593 }
594
595 #[inline]
596 const fn current_layout(&self) -> Option<core::alloc::Layout> {
597 if self.cap == 0 {
598 None
599 } else {
600 unsafe {
603 let align = core::mem::align_of::<$struct_type>();
604 let size = core::mem::size_of::<$struct_type>() * self.cap;
605 Some(core::alloc::Layout::from_size_align_unchecked(size, align))
606 }
607 }
608 }
609
610 #[inline]
611 const fn alloc_guard(alloc_size: usize) -> Result<(), bool> {
612 if core::mem::size_of::<usize>() < 8 && alloc_size > ::core::isize::MAX as usize {
613 Err(true)
614 } else {
615 Ok(())
616 }
617 }
618
619 #[inline]
620 #[allow(clippy::cast_ptr_alignment)]
623 fn try_reserve(
624 &mut self,
625 used_cap: usize,
626 needed_extra_cap: usize,
627 ) -> Result<(), bool> {
628 if self.capacity().wrapping_sub(used_cap) >= needed_extra_cap {
636 return Ok(());
637 }
638
639 let new_cap = self.amortized_new_size(used_cap, needed_extra_cap)?;
640 let new_layout =
641 alloc::alloc::Layout::array::<$struct_type>(new_cap).map_err(|_| true)?;
642
643 $struct_name::alloc_guard(new_layout.size())?;
644
645 let res = unsafe {
646 match self.current_layout() {
647 Some(layout) => {
648 alloc::alloc::realloc(self.ptr.cast::<u8>().cast_mut(), layout, new_layout.size())
649 }
650 None => alloc::alloc::alloc(new_layout),
651 }
652 };
653
654 if res.is_null() {
655 return Err(false);
656 }
657
658 self.ptr = res as *mut $struct_type;
659 self.cap = new_cap;
660
661 Ok(())
662 }
663
664 fn buf_reserve(&mut self, used_cap: usize, needed_extra_cap: usize) {
665 match self.try_reserve(used_cap, needed_extra_cap) {
666 Err(true ) => {
667 panic!("memory allocation failed: overflow");
668 }
669 Err(false ) => {
670 panic!("memory allocation failed: error allocating new memory");
671 }
672 Ok(()) => { }
673 }
674 }
675
676 pub fn append(&mut self, other: &mut Self) {
677 unsafe {
678 self.append_elements(core::ptr::from_ref(other.as_slice()));
679 other.set_len(0);
680 }
681 }
682
683 unsafe fn set_len(&mut self, new_len: usize) {
684 debug_assert!(new_len <= self.capacity());
685 self.len = new_len;
686 }
687
688 pub fn reserve(&mut self, additional: usize) {
689 self.buf_reserve(self.len, additional);
690 }
691
692 #[inline]
694 unsafe fn append_elements(&mut self, other: *const [$struct_type]) { unsafe {
695 let count = (&(*other)).len();
696 self.reserve(count);
697 let len = self.len();
698 core::ptr::copy_nonoverlapping(
699 other as *const $struct_type,
700 self.as_mut_ptr().add(len),
701 count,
702 );
703 self.len += count;
704 }}
705
706 pub fn truncate(&mut self, len: usize) {
707 unsafe {
715 if len > self.len {
716 return;
717 }
718 let remaining_len = self.len - len;
719 let s = core::ptr::slice_from_raw_parts_mut(
720 self.as_mut_ptr().add(len),
721 remaining_len,
722 );
723 self.len = len;
724 core::ptr::drop_in_place(s);
725 }
726 }
727
728 pub fn retain<F>(&mut self, mut f: F)
729 where
730 F: FnMut(&$struct_type) -> bool,
731 {
732 let len = self.len();
733 let mut del = 0;
734
735 {
736 for i in 0..len {
737 if unsafe { !f(self.get_unchecked(i)) } {
738 del += 1;
739 } else if del > 0 {
740 self.as_mut().swap(i - del, i);
741 }
742 }
743 }
744
745 if del > 0 {
746 self.truncate(len - del);
747 }
748 }
749 }
750 };
751}
752
753#[macro_export]
754macro_rules! impl_vec_debug {
755 ($struct_type:ident, $struct_name:ident) => {
756 impl core::fmt::Debug for $struct_name {
757 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
758 self.as_ref().fmt(f)
759 }
760 }
761 };
762}
763
764#[macro_export]
765macro_rules! impl_vec_partialord {
766 ($struct_type:ident, $struct_name:ident) => {
767 impl PartialOrd for $struct_name {
768 fn partial_cmp(&self, rhs: &Self) -> Option<core::cmp::Ordering> {
769 self.as_ref().partial_cmp(rhs.as_ref())
770 }
771 }
772 };
773}
774
775#[macro_export]
776macro_rules! impl_vec_ord {
777 ($struct_type:ident, $struct_name:ident) => {
778 impl Ord for $struct_name {
779 fn cmp(&self, rhs: &Self) -> core::cmp::Ordering {
780 self.as_ref().cmp(rhs.as_ref())
781 }
782 }
783 };
784}
785
786#[macro_export]
787macro_rules! impl_vec_clone {
788 ($struct_type:ident, $struct_name:ident, $destructor_name:ident) => {
789 impl $struct_name {
790 #[inline]
793 #[must_use] pub fn from_copy_on_write(
794 input: alloc::borrow::Cow<'static, [$struct_type]>,
795 ) -> $struct_name {
796 match input {
797 alloc::borrow::Cow::Borrowed(static_array) => {
798 Self::from_const_slice(static_array)
799 }
800 alloc::borrow::Cow::Owned(owned_vec) => Self::from_vec(owned_vec),
801 }
802 }
803
804 #[inline]
806 #[must_use] pub fn from_item(item: $struct_type) -> Self {
807 Self::from_vec(alloc::vec![item])
808 }
809
810 #[inline]
817 #[must_use] pub unsafe fn copy_from_ptr(ptr: *const $struct_type, len: usize) -> Self { unsafe {
818 if ptr.is_null() || len == 0 {
819 return Self::new();
820 }
821 let slice = core::slice::from_raw_parts(ptr, len);
822 Self::from_vec(slice.to_vec())
823 }}
824
825 #[inline]
828 #[must_use] pub fn clone_self(&self) -> Self {
829 match self.destructor {
830 $destructor_name::NoDestructor | $destructor_name::AlreadyDestroyed => Self {
831 ptr: self.ptr,
832 len: self.len,
833 cap: self.cap,
834 destructor: $destructor_name::NoDestructor,
835 },
836 $destructor_name::External(_) | $destructor_name::DefaultRust => {
837 Self::from_vec(self.as_ref().to_vec())
838 }
839 }
840 }
841
842 #[inline]
845 #[must_use] pub fn into_library_owned_vec(self) -> alloc::vec::Vec<$struct_type> {
846 match self.destructor {
847 $destructor_name::NoDestructor | $destructor_name::External(_) | $destructor_name::AlreadyDestroyed => {
848 self.as_ref().to_vec()
849 }
850 $destructor_name::DefaultRust => {
851 let v = unsafe {
852 alloc::vec::Vec::from_raw_parts(
853 self.ptr.cast_mut(),
854 self.len,
855 self.cap,
856 )
857 };
858 core::mem::forget(self);
859 v
860 }
861 }
862 }
863 }
864 impl Clone for $struct_name {
865 fn clone(&self) -> Self {
866 self.clone_self()
867 }
868 }
869 };
870}
871
872#[macro_export]
873macro_rules! impl_vec_partialeq {
874 ($struct_type:ident, $struct_name:ident) => {
875 impl PartialEq for $struct_name {
876 fn eq(&self, rhs: &Self) -> bool {
877 self.as_ref().eq(rhs.as_ref())
878 }
879 }
880 };
881}
882
883#[macro_export]
884macro_rules! impl_vec_eq {
885 ($struct_type:ident, $struct_name:ident) => {
886 impl Eq for $struct_name {}
887 };
888}
889
890#[macro_export]
891macro_rules! impl_vec_hash {
892 ($struct_type:ident, $struct_name:ident) => {
893 impl core::hash::Hash for $struct_name {
894 fn hash<H>(&self, state: &mut H)
895 where
896 H: core::hash::Hasher,
897 {
898 self.as_ref().hash(state);
899 }
900 }
901 };
902}
903
904#[macro_export]
905macro_rules! impl_option_inner {
906 ($struct_type:ident, $struct_name:ident) => {
907 impl From<$struct_name> for Option<$struct_type> {
908 fn from(o: $struct_name) -> Option<$struct_type> {
909 match o {
910 $struct_name::None => None,
911 $struct_name::Some(t) => Some(t),
912 }
913 }
914 }
915
916 impl From<Option<$struct_type>> for $struct_name {
917 fn from(o: Option<$struct_type>) -> $struct_name {
918 match o {
919 None => $struct_name::None,
920 Some(t) => $struct_name::Some(t),
921 }
922 }
923 }
924
925 impl Default for $struct_name {
926 fn default() -> $struct_name {
927 $struct_name::None
928 }
929 }
930
931 impl $struct_name {
932 #[must_use] pub const fn as_option(&self) -> Option<&$struct_type> {
933 match self {
934 $struct_name::None => None,
935 $struct_name::Some(t) => Some(t),
936 }
937 }
938 #[allow(clippy::return_self_not_must_use)]
941 pub const fn replace(&mut self, value: $struct_type) -> $struct_name {
942 ::core::mem::replace(self, $struct_name::Some(value))
943 }
944 #[must_use] pub const fn is_some(&self) -> bool {
945 match self {
946 $struct_name::None => false,
947 $struct_name::Some(_) => true,
948 }
949 }
950 #[must_use] pub const fn is_none(&self) -> bool {
951 !self.is_some()
952 }
953 #[must_use] pub const fn as_ref(&self) -> Option<&$struct_type> {
954 match *self {
955 $struct_name::Some(ref x) => Some(x),
956 $struct_name::None => None,
957 }
958 }
959 pub const fn as_mut(&mut self) -> Option<&mut $struct_type> {
960 match self {
961 $struct_name::Some(x) => Some(x),
962 $struct_name::None => None,
963 }
964 }
965 pub fn map<U, F: FnOnce($struct_type) -> U>(self, f: F) -> Option<U> {
966 match self {
967 $struct_name::Some(x) => Some(f(x)),
968 $struct_name::None => None,
969 }
970 }
971 pub fn and_then<U, F>(self, f: F) -> Option<U>
972 where
973 F: FnOnce($struct_type) -> Option<U>,
974 {
975 match self {
976 $struct_name::None => None,
977 $struct_name::Some(x) => f(x),
978 }
979 }
980 }
981 };
982}
983
984#[macro_export]
985macro_rules! impl_option {
986 ($struct_type:ident, $struct_name:ident, copy = false, clone = false, [$($derive:meta),* ]) => (
987 $(#[derive($derive)])*
988 #[repr(C, u8)]
989 pub enum $struct_name {
990 None,
991 Some($struct_type)
992 }
993
994 impl $struct_name {
995 pub fn into_option(self) -> Option<$struct_type> {
996 match self {
997 $struct_name::None => None,
998 $struct_name::Some(t) => Some(t),
999 }
1000 }
1001 }
1002
1003 impl_option_inner!($struct_type, $struct_name);
1004 );
1005 ($struct_type:ident, $struct_name:ident, copy = false, [$($derive:meta),* ]) => (
1006 $(#[derive($derive)])*
1007 #[repr(C, u8)]
1008 #[allow(missing_copy_implementations, variant_size_differences)]
1012 pub enum $struct_name {
1013 None,
1014 Some($struct_type)
1015 }
1016
1017 impl $struct_name {
1018 #[must_use] pub fn into_option(&self) -> Option<$struct_type> {
1019 match self {
1020 $struct_name::None => None,
1021 $struct_name::Some(t) => Some(t.clone()),
1022 }
1023 }
1024 }
1025
1026 impl_option_inner!($struct_type, $struct_name);
1027 );
1028 ($struct_type:ident, $struct_name:ident, [$($derive:meta),* ]) => (
1029 $(#[derive($derive)])*
1030 #[repr(C, u8)]
1031 #[allow(missing_copy_implementations, variant_size_differences)]
1035 pub enum $struct_name {
1036 None,
1037 Some($struct_type)
1038 }
1039
1040 impl $struct_name {
1041 #[must_use] pub fn into_option(&self) -> Option<$struct_type> {
1042 match self {
1043 $struct_name::None => None,
1044 $struct_name::Some(t) => Some(t.clone()),
1045 }
1046 }
1047 }
1048
1049 impl_option_inner!($struct_type, $struct_name);
1050 );
1051}
1052
1053#[macro_export]
1054macro_rules! impl_result_inner {
1055 ($ok_struct_type:ident, $err_struct_type:ident, $struct_name:ident) => {
1056 impl From<$struct_name> for Result<$ok_struct_type, $err_struct_type> {
1057 fn from(o: $struct_name) -> Result<$ok_struct_type, $err_struct_type> {
1058 match o {
1059 $struct_name::Ok(o) => Ok(o),
1060 $struct_name::Err(e) => Err(e),
1061 }
1062 }
1063 }
1064
1065 impl From<Result<$ok_struct_type, $err_struct_type>> for $struct_name {
1066 fn from(o: Result<$ok_struct_type, $err_struct_type>) -> $struct_name {
1067 match o {
1068 Ok(o) => $struct_name::Ok(o),
1069 Err(e) => $struct_name::Err(e),
1070 }
1071 }
1072 }
1073
1074 impl $struct_name {
1075 pub fn as_result(&self) -> Result<&$ok_struct_type, &$err_struct_type> {
1076 match self {
1077 $struct_name::Ok(o) => Ok(o),
1078 $struct_name::Err(e) => Err(e),
1079 }
1080 }
1081 pub fn is_ok(&self) -> bool {
1082 match self {
1083 $struct_name::Ok(_) => true,
1084 $struct_name::Err(_) => false,
1085 }
1086 }
1087 pub fn is_err(&self) -> bool {
1088 !self.is_ok()
1089 }
1090 }
1091 };
1092}
1093
1094#[macro_export]
1095macro_rules! impl_result {
1096 ($ok_struct_type:ident, $err_struct_type:ident, $struct_name:ident, copy = false, clone = false, [$($derive:meta),* ]) => (
1097 $(#[derive($derive)])*
1098 #[repr(C, u8)]
1099 pub enum $struct_name {
1100 Ok($ok_struct_type),
1101 Err($err_struct_type)
1102 }
1103
1104 impl $struct_name {
1105 pub fn into_result(self) -> Result<$ok_struct_type, $err_struct_type> {
1106 match self {
1107 $struct_name::Ok(o) => Ok(o),
1108 $struct_name::Err(e) => Err(e),
1109 }
1110 }
1111 }
1112
1113 impl_result_inner!($ok_struct_type, $err_struct_type, $struct_name);
1114 );
1115 ($ok_struct_type:ident, $err_struct_type:ident, $struct_name:ident, copy = false, [$($derive:meta),* ]) => (
1116 $(#[derive($derive)])*
1117 #[repr(C, u8)]
1118 pub enum $struct_name {
1119 Ok($ok_struct_type),
1120 Err($err_struct_type)
1121 }
1122 impl $struct_name {
1123 pub fn into_result(&self) -> Result<$ok_struct_type, $err_struct_type> {
1124 match self {
1125 $struct_name::Ok(o) => Ok(o.clone()),
1126 $struct_name::Err(e) => Err(e.clone()),
1127 }
1128 }
1129 }
1130
1131 impl_result_inner!($ok_struct_type, $err_struct_type, $struct_name);
1132 );
1133 ($ok_struct_type:ident, $err_struct_type:ident, $struct_name:ident, [$($derive:meta),* ]) => (
1134 $(#[derive($derive)])*
1135 #[repr(C, u8)]
1136 pub enum $struct_name {
1137 Ok($ok_struct_type),
1138 Err($err_struct_type)
1139 }
1140
1141 impl $struct_name {
1142 pub fn into_result(&self) -> Result<$ok_struct_type, $err_struct_type> {
1143 match self {
1144 $struct_name::Ok(o) => Ok(*o),
1145 $struct_name::Err(e) => Err(*e),
1146 }
1147 }
1148 }
1149
1150 impl_result_inner!($ok_struct_type, $err_struct_type, $struct_name);
1151 );
1152}
1153
1154macro_rules! impl_color_value_fmt {
1155 ($struct_name:ty) => {
1156 impl FormatAsRustCode for $struct_name {
1157 fn format_as_rust_code(&self, _tabs: usize) -> String {
1158 format!(
1159 "{} {{ inner: {} }}",
1160 stringify!($struct_name),
1161 format_color_value(&self.inner)
1162 )
1163 }
1164 }
1165 };
1166}
1167
1168macro_rules! impl_enum_fmt {($enum_name:ident, $($enum_type:ident),+) => (
1169 impl crate::codegen::format::FormatAsRustCode for $enum_name {
1170 fn format_as_rust_code(&self, _tabs: usize) -> String {
1171 match self {
1172 $(
1173 $enum_name::$enum_type => {
1174 String::from(
1175 concat!(stringify!($enum_name), "::", stringify!($enum_type))
1176 )
1177 },
1178 )+
1179 }
1180 }
1181 }
1182)}