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]
26 pub const fn empty() -> Self {
27 Self {
28 ptr: core::ptr::null(),
29 len: 0,
30 }
31 }
32
33 #[inline]
35 #[must_use]
36 pub const fn len(&self) -> usize {
37 self.len
38 }
39
40 #[inline]
42 #[must_use]
43 pub const fn is_empty(&self) -> bool {
44 self.len == 0
45 }
46
47 #[inline]
49 #[must_use]
50 pub const fn as_ptr(&self) -> *const $struct_type {
51 self.ptr
52 }
53
54 #[inline]
56 #[must_use]
57 pub const fn as_slice(&self) -> &[$struct_type] {
58 if self.ptr.is_null() || self.len == 0 {
59 &[]
60 } else {
61 unsafe { core::slice::from_raw_parts(self.ptr, self.len) }
62 }
63 }
64
65 #[inline]
67 #[must_use]
68 pub fn get(&self, index: usize) -> Option<&$struct_type> {
69 self.as_slice().get(index)
70 }
71
72 #[inline]
74 pub fn iter(&self) -> core::slice::Iter<'_, $struct_type> {
75 self.as_slice().iter()
76 }
77 }
78
79 unsafe impl Send for $slice_name {}
80 unsafe impl Sync for $slice_name {}
81
82 impl<'a> IntoIterator for &'a $slice_name {
83 type Item = &'a $struct_type;
84 type IntoIter = core::slice::Iter<'a, $struct_type>;
85 #[inline]
86 fn into_iter(self) -> Self::IntoIter {
87 self.iter()
88 }
89 }
90
91 impl<'a> IntoIterator for &'a $struct_name {
92 type Item = &'a $struct_type;
93 type IntoIter = core::slice::Iter<'a, $struct_type>;
94 #[inline]
95 fn into_iter(self) -> Self::IntoIter {
96 self.iter()
97 }
98 }
99
100 #[repr(C)]
101 pub struct $struct_name {
102 ptr: *const $struct_type,
103 len: usize,
104 cap: usize,
105 destructor: $destructor_name,
106 }
107
108 #[derive(Debug, Copy, Clone)]
109 #[repr(C, u8)]
110 pub enum $destructor_name {
111 DefaultRust,
112 NoDestructor,
113 External($destructor_type_name),
114 AlreadyDestroyed,
117 }
118
119 unsafe impl Send for $struct_name {}
120 unsafe impl Sync for $struct_name {}
121
122 impl $struct_name {
123 #[inline]
124 #[must_use]
125 pub const fn new() -> $struct_name {
126 Self::from_vec(alloc::vec::Vec::new())
128 }
129
130 #[inline]
131 #[must_use]
132 pub fn with_capacity(cap: usize) -> Self {
133 Self::from_vec(alloc::vec::Vec::<$struct_type>::with_capacity(cap))
134 }
135
136 #[inline]
137 #[must_use]
138 pub const fn from_const_slice(input: &'static [$struct_type]) -> Self {
139 Self {
140 ptr: input.as_ptr(),
141 len: input.len(),
142 cap: input.len(),
143 destructor: $destructor_name::NoDestructor, }
145 }
146
147 #[inline]
154 const fn owns_buffer(&self) -> bool {
155 matches!(self.destructor, $destructor_name::DefaultRust)
156 }
157
158 #[inline]
162 const fn mark_rust_owned(&mut self) {
163 self.destructor = $destructor_name::DefaultRust;
164 }
165
166 #[inline]
167 #[must_use]
168 pub const fn from_vec(input: alloc::vec::Vec<$struct_type>) -> Self {
169 let ptr = input.as_ptr();
170 let len = input.len();
171 let cap = input.capacity();
172
173 let _ = ::core::mem::ManuallyDrop::new(input);
174
175 Self {
176 ptr,
177 len,
178 cap,
179 destructor: $destructor_name::DefaultRust,
180 }
181 }
182
183 #[inline]
184 pub fn iter(&self) -> core::slice::Iter<'_, $struct_type> {
185 self.as_ref().iter()
186 }
187
188 #[inline]
189 #[must_use]
190 pub const fn len(&self) -> usize {
191 self.len
192 }
193
194 #[inline]
195 #[must_use]
196 pub const fn capacity(&self) -> usize {
197 self.cap
198 }
199
200 #[inline]
201 #[must_use]
202 pub const fn is_empty(&self) -> bool {
203 self.len == 0
204 }
205
206 #[inline]
208 #[must_use]
209 pub fn get(&self, index: usize) -> Option<&$struct_type> {
210 self.as_ref().get(index)
211 }
212
213 #[inline]
216 #[must_use]
217 pub fn c_get(&self, index: usize) -> $option_type
218 where
219 $struct_type: Clone,
220 {
221 self.get(index).cloned().into()
222 }
223
224 #[allow(dead_code)]
225 #[inline]
226 unsafe fn get_unchecked(&self, index: usize) -> &$struct_type {
227 unsafe { self.as_ref().get_unchecked(index) }
228 }
229
230 #[inline]
232 #[must_use]
233 pub fn as_slice(&self) -> &[$struct_type] {
234 self.as_ref()
235 }
236
237 #[inline]
239 #[must_use]
240 pub const fn as_c_slice(&self) -> $slice_name {
241 $slice_name {
242 ptr: self.ptr,
243 len: self.len,
244 }
245 }
246
247 #[inline]
250 #[must_use]
251 pub fn as_c_slice_range(&self, start: usize, end: usize) -> $slice_name {
252 let start = start.min(self.len);
253 let end = end.min(self.len).max(start);
254 let len = end - start;
255 if len == 0 || self.ptr.is_null() {
256 $slice_name::empty()
257 } else {
258 $slice_name {
259 ptr: unsafe { self.ptr.add(start) },
260 len,
261 }
262 }
263 }
264
265 #[inline]
268 #[must_use]
269 pub const fn as_ptr(&self) -> *const $struct_type {
270 self.ptr
271 }
272 }
273
274 impl AsRef<[$struct_type]> for $struct_name {
275 fn as_ref(&self) -> &[$struct_type] {
276 if self.ptr.is_null() || self.len == 0 {
277 &[]
278 } else {
279 unsafe { core::slice::from_raw_parts(self.ptr, self.len) }
280 }
281 }
282 }
283
284 impl Default for $struct_name {
285 fn default() -> Self {
286 Self::from_vec(alloc::vec::Vec::new())
287 }
288 }
289
290 impl core::iter::FromIterator<$struct_type> for $struct_name {
291 fn from_iter<T>(iter: T) -> Self
292 where
293 T: IntoIterator<Item = $struct_type>,
294 {
295 Self::from_vec(alloc::vec::Vec::from_iter(iter))
296 }
297 }
298
299 impl From<alloc::vec::Vec<$struct_type>> for $struct_name {
300 fn from(input: alloc::vec::Vec<$struct_type>) -> $struct_name {
301 $struct_name::from_vec(input)
302 }
303 }
304
305 impl From<&'static [$struct_type]> for $struct_name {
306 fn from(input: &'static [$struct_type]) -> $struct_name {
307 Self::from_const_slice(input)
308 }
309 }
310
311 impl Drop for $struct_name {
312 fn drop(&mut self) {
313 match self.destructor {
314 $destructor_name::DefaultRust => {
315 if !self.ptr.is_null() && self.cap != 0 {
324 drop(unsafe {
325 alloc::vec::Vec::from_raw_parts(
326 self.ptr.cast_mut(),
327 self.len,
328 self.cap,
329 )
330 });
331 }
332 self.destructor = $destructor_name::AlreadyDestroyed;
333 }
334 $destructor_name::External(f) => {
335 f(self);
336 self.destructor = $destructor_name::AlreadyDestroyed;
337 }
338 $destructor_name::NoDestructor | $destructor_name::AlreadyDestroyed => {}
339 }
340 }
341 }
342 };
343}
344
345macro_rules! impl_from {
357 ($a:ident < $c:lifetime > , $b:ident:: $enum_type:ident) => {
359 impl<$c> From<$a<$c>> for $b<$c> {
360 fn from(e: $a<$c>) -> Self {
361 $b::$enum_type(e)
362 }
363 }
364 };
365
366 ($a:ident, $b:ident:: $enum_type:ident) => {
372 impl From<$a> for $b {
373 fn from(e: $a) -> Self {
374 $b::$enum_type(e)
375 }
376 }
377 };
378}
379
380#[macro_export]
395macro_rules! impl_display {
396 ($enum:ident<$lt:lifetime>, {$($variant:pat => $fmt_string:expr),+$(,)* }) => {
398
399 impl ::core::fmt::Display for $enum<'_> {
400 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
401 use self::$enum::*;
402 match &self {
403 $(
404 $variant => write!(f, "{}", $fmt_string),
405 )+
406 }
407 }
408 }
409
410 };
411
412 ($enum:ident, {$($variant:pat => $fmt_string:expr),+$(,)* }) => {
414
415 impl ::core::fmt::Display for $enum {
416 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
417 use self::$enum::*;
418 match &self {
419 $(
420 $variant => write!(f, "{}", $fmt_string),
421 )+
422 }
423 }
424 }
425
426 };
427}
428
429#[macro_export]
432macro_rules! impl_debug_as_display {
433 ($enum:ident < $lt:lifetime >) => {
435 impl ::core::fmt::Debug for $enum<'_> {
436 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
437 write!(f, "{}", self)
438 }
439 }
440 };
441
442 ($enum:ident) => {
444 impl ::core::fmt::Debug for $enum {
445 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
446 write!(f, "{}", self)
447 }
448 }
449 };
450}
451
452#[macro_export]
453macro_rules! impl_vec_as_hashmap {
454 ($struct_type:ident, $struct_name:ident) => {
455 impl $struct_name {
456 pub fn insert_hm_item(&mut self, item: $struct_type) {
457 if !self.contains_hm_item(&item) {
458 self.push(item);
459 }
460 }
461
462 pub fn remove_hm_item(&mut self, remove_key: &$struct_type) {
463 *self = Self::from_vec(
464 self.as_ref()
465 .iter()
466 .filter_map(|r| if *r == *remove_key { None } else { Some(*r) })
467 .collect::<Vec<_>>(),
468 );
469 }
470
471 pub fn contains_hm_item(&self, searched: &$struct_type) -> bool {
472 self.as_ref().iter().any(|i| i == searched)
473 }
474 }
475 };
476}
477
478#[macro_export]
480macro_rules! impl_vec_mut {
481 ($struct_type:ident, $struct_name:ident) => {
482 impl<'a> IntoIterator for &'a mut $struct_name {
483 type Item = &'a mut $struct_type;
484 type IntoIter = core::slice::IterMut<'a, $struct_type>;
485 #[inline]
486 fn into_iter(self) -> Self::IntoIter {
487 self.iter_mut()
488 }
489 }
490
491 impl AsMut<[$struct_type]> for $struct_name {
492 fn as_mut(&mut self) -> &mut [$struct_type] {
493 unsafe { core::slice::from_raw_parts_mut(self.ptr.cast_mut(), self.len) }
494 }
495 }
496
497 impl From<$struct_name> for alloc::vec::Vec<$struct_type> {
498 #[allow(unused_mut)]
499 fn from(mut input: $struct_name) -> alloc::vec::Vec<$struct_type> {
500 input.into_library_owned_vec()
501 }
502 }
503
504 impl core::iter::Extend<$struct_type> for $struct_name {
505 fn extend<T: core::iter::IntoIterator<Item = $struct_type>>(&mut self, iter: T) {
506 for elem in iter {
507 self.push(elem);
508 }
509 }
510 }
511
512 impl $struct_name {
513 #[inline]
514 pub const fn as_mut_ptr(&mut self) -> *mut $struct_type {
515 self.ptr.cast_mut()
516 }
517
518 #[inline]
519 pub fn sort_by<F: FnMut(&$struct_type, &$struct_type) -> core::cmp::Ordering>(
520 &mut self,
521 compare: F,
522 ) {
523 self.as_mut().sort_by(compare);
524 }
525
526 #[inline]
527 pub fn push(&mut self, value: $struct_type) {
528 if self.len == self.capacity() {
531 self.buf_reserve(self.len, 1);
532 }
533 unsafe {
534 let end = self.as_mut_ptr().add(self.len);
535 core::ptr::write(end, value);
536 self.len += 1;
537 }
538 }
539
540 pub fn insert(&mut self, index: usize, element: $struct_type) {
541 let len = self.len();
542 if index > len {
543 return;
544 }
545
546 if len == self.capacity() {
548 self.reserve(1);
549 }
550
551 unsafe {
552 {
555 let p = self.as_mut_ptr().add(index);
556 core::ptr::copy(p, p.offset(1), len - index);
559 core::ptr::write(p, element);
562 }
563 self.set_len(len + 1);
564 }
565 }
566
567 pub fn remove(&mut self, index: usize) {
568 let len = self.len();
569 if index >= len {
570 return;
571 }
572
573 unsafe {
574 let ret;
576 {
577 let ptr = self.as_mut_ptr().add(index);
579 ret = core::ptr::read(ptr);
582
583 core::ptr::copy(ptr.offset(1), ptr, len - index - 1);
585 }
586 self.set_len(len - 1);
587 let _ret = ret;
593 }
594 }
595
596 #[inline]
597 pub const fn pop(&mut self) -> Option<$struct_type> {
598 if self.len == 0 {
599 None
600 } else {
601 unsafe {
602 self.len -= 1;
603 Some(core::ptr::read(self.ptr.add(self.len())))
604 }
605 }
606 }
607
608 #[inline]
609 pub fn iter_mut(&mut self) -> core::slice::IterMut<'_, $struct_type> {
610 self.as_mut().iter_mut()
611 }
612
613 #[inline]
614 #[must_use]
615 pub fn into_iter(self) -> alloc::vec::IntoIter<$struct_type> {
616 let v1: alloc::vec::Vec<$struct_type> = self.into();
617 v1.into_iter()
618 }
619
620 #[inline]
621 fn amortized_new_size(
622 &self,
623 used_cap: usize,
624 needed_extra_cap: usize,
625 ) -> Result<usize, bool> {
626 let required_cap = used_cap.checked_add(needed_extra_cap).ok_or(true)?;
628 let double_cap = self.cap * 2;
630 Ok(core::cmp::max(double_cap, required_cap))
632 }
633
634 #[inline]
635 const fn current_layout(&self) -> Option<core::alloc::Layout> {
636 if self.cap == 0 {
637 None
638 } else {
639 unsafe {
642 let align = core::mem::align_of::<$struct_type>();
643 let size = core::mem::size_of::<$struct_type>() * self.cap;
644 Some(core::alloc::Layout::from_size_align_unchecked(size, align))
645 }
646 }
647 }
648
649 #[inline]
650 const fn alloc_guard(alloc_size: usize) -> Result<(), bool> {
651 if core::mem::size_of::<usize>() < 8 && alloc_size > ::core::isize::MAX as usize {
652 Err(true)
653 } else {
654 Ok(())
655 }
656 }
657
658 #[inline]
659 #[allow(clippy::cast_ptr_alignment)]
662 fn try_reserve(
663 &mut self,
664 used_cap: usize,
665 needed_extra_cap: usize,
666 ) -> Result<(), bool> {
667 if self.capacity().wrapping_sub(used_cap) >= needed_extra_cap {
675 return Ok(());
676 }
677
678 let new_cap = self.amortized_new_size(used_cap, needed_extra_cap)?;
679 let new_layout =
680 alloc::alloc::Layout::array::<$struct_type>(new_cap).map_err(|_| true)?;
681
682 $struct_name::alloc_guard(new_layout.size())?;
683
684 let owns_buffer = self.owns_buffer();
694
695 let res = unsafe {
696 match self.current_layout() {
697 Some(layout) if owns_buffer => alloc::alloc::realloc(
698 self.ptr.cast::<u8>().cast_mut(),
699 layout,
700 new_layout.size(),
701 ),
702 _ => {
703 let fresh = alloc::alloc::alloc(new_layout);
704 if !fresh.is_null() && self.len > 0 {
709 core::ptr::copy_nonoverlapping(
710 self.ptr,
711 fresh.cast::<$struct_type>(),
712 self.len,
713 );
714 }
715 fresh
716 }
717 }
718 };
719
720 if res.is_null() {
721 return Err(false);
722 }
723
724 self.ptr = res as *mut $struct_type;
725 self.cap = new_cap;
726 self.mark_rust_owned();
733
734 Ok(())
735 }
736
737 fn buf_reserve(&mut self, used_cap: usize, needed_extra_cap: usize) {
738 match self.try_reserve(used_cap, needed_extra_cap) {
739 Err(true ) => {
740 panic!("memory allocation failed: overflow");
741 }
742 Err(false ) => {
743 panic!("memory allocation failed: error allocating new memory");
744 }
745 Ok(()) => { }
746 }
747 }
748
749 pub fn append(&mut self, other: &mut Self) {
750 unsafe {
751 self.append_elements(core::ptr::from_ref(other.as_slice()));
752 other.set_len(0);
753 }
754 }
755
756 unsafe fn set_len(&mut self, new_len: usize) {
757 debug_assert!(new_len <= self.capacity());
758 self.len = new_len;
759 }
760
761 pub fn reserve(&mut self, additional: usize) {
762 self.buf_reserve(self.len, additional);
763 }
764
765 #[inline]
767 unsafe fn append_elements(&mut self, other: *const [$struct_type]) {
768 unsafe {
769 let count = (&(*other)).len();
770 self.reserve(count);
771 let len = self.len();
772 core::ptr::copy_nonoverlapping(
773 other as *const $struct_type,
774 self.as_mut_ptr().add(len),
775 count,
776 );
777 self.len += count;
778 }
779 }
780
781 pub fn truncate(&mut self, len: usize) {
782 unsafe {
790 if len > self.len {
791 return;
792 }
793 let remaining_len = self.len - len;
794 let s = core::ptr::slice_from_raw_parts_mut(
795 self.as_mut_ptr().add(len),
796 remaining_len,
797 );
798 self.len = len;
799 core::ptr::drop_in_place(s);
800 }
801 }
802
803 pub fn retain<F>(&mut self, mut f: F)
804 where
805 F: FnMut(&$struct_type) -> bool,
806 {
807 let len = self.len();
808 let mut del = 0;
809
810 {
811 for i in 0..len {
812 if unsafe { !f(self.get_unchecked(i)) } {
813 del += 1;
814 } else if del > 0 {
815 self.as_mut().swap(i - del, i);
816 }
817 }
818 }
819
820 if del > 0 {
821 self.truncate(len - del);
822 }
823 }
824 }
825 };
826}
827
828#[macro_export]
829macro_rules! impl_vec_debug {
830 ($struct_type:ident, $struct_name:ident) => {
831 impl core::fmt::Debug for $struct_name {
832 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
833 self.as_ref().fmt(f)
834 }
835 }
836 };
837}
838
839#[macro_export]
840macro_rules! impl_vec_partialord {
841 ($struct_type:ident, $struct_name:ident) => {
842 impl PartialOrd for $struct_name {
843 fn partial_cmp(&self, rhs: &Self) -> Option<core::cmp::Ordering> {
844 self.as_ref().partial_cmp(rhs.as_ref())
845 }
846 }
847 };
848}
849
850#[macro_export]
851macro_rules! impl_vec_ord {
852 ($struct_type:ident, $struct_name:ident) => {
853 impl Ord for $struct_name {
854 fn cmp(&self, rhs: &Self) -> core::cmp::Ordering {
855 self.as_ref().cmp(rhs.as_ref())
856 }
857 }
858 };
859}
860
861#[macro_export]
862macro_rules! impl_vec_clone {
863 ($struct_type:ident, $struct_name:ident, $destructor_name:ident) => {
864 impl $struct_name {
865 #[inline]
868 #[must_use]
869 pub fn from_copy_on_write(
870 input: alloc::borrow::Cow<'static, [$struct_type]>,
871 ) -> $struct_name {
872 match input {
873 alloc::borrow::Cow::Borrowed(static_array) => {
874 Self::from_const_slice(static_array)
875 }
876 alloc::borrow::Cow::Owned(owned_vec) => Self::from_vec(owned_vec),
877 }
878 }
879
880 #[inline]
882 #[must_use]
883 pub fn from_item(item: $struct_type) -> Self {
884 Self::from_vec(alloc::vec![item])
885 }
886
887 #[inline]
894 #[must_use]
895 pub unsafe fn copy_from_ptr(ptr: *const $struct_type, len: usize) -> Self {
896 unsafe {
897 if ptr.is_null() || len == 0 {
898 return Self::new();
899 }
900 let slice = core::slice::from_raw_parts(ptr, len);
901 Self::from_vec(slice.to_vec())
902 }
903 }
904
905 #[inline]
908 #[must_use]
909 pub fn clone_self(&self) -> Self {
910 match self.destructor {
911 $destructor_name::NoDestructor | $destructor_name::AlreadyDestroyed => Self {
912 ptr: self.ptr,
913 len: self.len,
914 cap: self.cap,
915 destructor: $destructor_name::NoDestructor,
916 },
917 $destructor_name::External(_) | $destructor_name::DefaultRust => {
918 Self::from_vec(self.as_ref().to_vec())
919 }
920 }
921 }
922
923 #[inline]
926 #[must_use]
927 pub fn into_library_owned_vec(self) -> alloc::vec::Vec<$struct_type> {
928 match self.destructor {
929 $destructor_name::NoDestructor
930 | $destructor_name::External(_)
931 | $destructor_name::AlreadyDestroyed => self.as_ref().to_vec(),
932 $destructor_name::DefaultRust => {
933 let v = unsafe {
934 alloc::vec::Vec::from_raw_parts(self.ptr.cast_mut(), self.len, self.cap)
935 };
936 core::mem::forget(self);
937 v
938 }
939 }
940 }
941 }
942 impl Clone for $struct_name {
943 fn clone(&self) -> Self {
944 self.clone_self()
945 }
946 }
947 };
948}
949
950#[macro_export]
951macro_rules! impl_vec_partialeq {
952 ($struct_type:ident, $struct_name:ident) => {
953 impl PartialEq for $struct_name {
954 fn eq(&self, rhs: &Self) -> bool {
955 self.as_ref().eq(rhs.as_ref())
956 }
957 }
958 };
959}
960
961#[macro_export]
962macro_rules! impl_vec_eq {
963 ($struct_type:ident, $struct_name:ident) => {
964 impl Eq for $struct_name {}
965 };
966}
967
968#[macro_export]
969macro_rules! impl_vec_hash {
970 ($struct_type:ident, $struct_name:ident) => {
971 impl core::hash::Hash for $struct_name {
972 fn hash<H>(&self, state: &mut H)
973 where
974 H: core::hash::Hasher,
975 {
976 self.as_ref().hash(state);
977 }
978 }
979 };
980}
981
982#[macro_export]
983macro_rules! impl_option_inner {
984 ($struct_type:ident, $struct_name:ident) => {
985 impl From<$struct_name> for Option<$struct_type> {
986 fn from(o: $struct_name) -> Option<$struct_type> {
987 match o {
988 $struct_name::None => None,
989 $struct_name::Some(t) => Some(t),
990 }
991 }
992 }
993
994 impl From<Option<$struct_type>> for $struct_name {
995 fn from(o: Option<$struct_type>) -> $struct_name {
996 match o {
997 None => $struct_name::None,
998 Some(t) => $struct_name::Some(t),
999 }
1000 }
1001 }
1002
1003 impl Default for $struct_name {
1004 fn default() -> $struct_name {
1005 $struct_name::None
1006 }
1007 }
1008
1009 impl $struct_name {
1010 #[must_use]
1011 pub const fn as_option(&self) -> Option<&$struct_type> {
1012 match self {
1013 $struct_name::None => None,
1014 $struct_name::Some(t) => Some(t),
1015 }
1016 }
1017 #[allow(clippy::return_self_not_must_use)]
1020 pub const fn replace(&mut self, value: $struct_type) -> $struct_name {
1021 ::core::mem::replace(self, $struct_name::Some(value))
1022 }
1023 #[must_use]
1024 pub const fn is_some(&self) -> bool {
1025 match self {
1026 $struct_name::None => false,
1027 $struct_name::Some(_) => true,
1028 }
1029 }
1030 #[must_use]
1031 pub const fn is_none(&self) -> bool {
1032 !self.is_some()
1033 }
1034 #[must_use]
1035 pub const fn as_ref(&self) -> Option<&$struct_type> {
1036 match *self {
1037 $struct_name::Some(ref x) => Some(x),
1038 $struct_name::None => None,
1039 }
1040 }
1041 pub const fn as_mut(&mut self) -> Option<&mut $struct_type> {
1042 match self {
1043 $struct_name::Some(x) => Some(x),
1044 $struct_name::None => None,
1045 }
1046 }
1047 pub fn map<U, F: FnOnce($struct_type) -> U>(self, f: F) -> Option<U> {
1048 match self {
1049 $struct_name::Some(x) => Some(f(x)),
1050 $struct_name::None => None,
1051 }
1052 }
1053 pub fn and_then<U, F>(self, f: F) -> Option<U>
1054 where
1055 F: FnOnce($struct_type) -> Option<U>,
1056 {
1057 match self {
1058 $struct_name::None => None,
1059 $struct_name::Some(x) => f(x),
1060 }
1061 }
1062 }
1063 };
1064}
1065
1066#[macro_export]
1067macro_rules! impl_option {
1068 ($struct_type:ident, $struct_name:ident, copy = false, clone = false, [$($derive:meta),* ]) => (
1069 $(#[derive($derive)])*
1070 #[repr(C, u8)]
1071 pub enum $struct_name {
1072 None,
1073 Some($struct_type)
1074 }
1075
1076 impl $struct_name {
1077 pub fn into_option(self) -> Option<$struct_type> {
1078 match self {
1079 $struct_name::None => None,
1080 $struct_name::Some(t) => Some(t),
1081 }
1082 }
1083 }
1084
1085 impl_option_inner!($struct_type, $struct_name);
1086 );
1087 ($struct_type:ident, $struct_name:ident, copy = false, [$($derive:meta),* ]) => (
1088 $(#[derive($derive)])*
1089 #[repr(C, u8)]
1090 #[allow(missing_copy_implementations, variant_size_differences)]
1094 pub enum $struct_name {
1095 None,
1096 Some($struct_type)
1097 }
1098
1099 impl $struct_name {
1100 #[must_use] pub fn into_option(&self) -> Option<$struct_type> {
1101 match self {
1102 $struct_name::None => None,
1103 $struct_name::Some(t) => Some(t.clone()),
1104 }
1105 }
1106 }
1107
1108 impl_option_inner!($struct_type, $struct_name);
1109 );
1110 ($struct_type:ident, $struct_name:ident, [$($derive:meta),* ]) => (
1111 $(#[derive($derive)])*
1112 #[repr(C, u8)]
1113 #[allow(missing_copy_implementations, variant_size_differences)]
1117 pub enum $struct_name {
1118 None,
1119 Some($struct_type)
1120 }
1121
1122 impl $struct_name {
1123 #[must_use] pub fn into_option(&self) -> Option<$struct_type> {
1124 match self {
1125 $struct_name::None => None,
1126 $struct_name::Some(t) => Some(t.clone()),
1127 }
1128 }
1129 }
1130
1131 impl_option_inner!($struct_type, $struct_name);
1132 );
1133}
1134
1135#[macro_export]
1136macro_rules! impl_result_inner {
1137 ($ok_struct_type:ident, $err_struct_type:ident, $struct_name:ident) => {
1138 impl From<$struct_name> for Result<$ok_struct_type, $err_struct_type> {
1139 fn from(o: $struct_name) -> Result<$ok_struct_type, $err_struct_type> {
1140 match o {
1141 $struct_name::Ok(o) => Ok(o),
1142 $struct_name::Err(e) => Err(e),
1143 }
1144 }
1145 }
1146
1147 impl From<Result<$ok_struct_type, $err_struct_type>> for $struct_name {
1148 fn from(o: Result<$ok_struct_type, $err_struct_type>) -> $struct_name {
1149 match o {
1150 Ok(o) => $struct_name::Ok(o),
1151 Err(e) => $struct_name::Err(e),
1152 }
1153 }
1154 }
1155
1156 impl $struct_name {
1157 pub fn as_result(&self) -> Result<&$ok_struct_type, &$err_struct_type> {
1158 match self {
1159 $struct_name::Ok(o) => Ok(o),
1160 $struct_name::Err(e) => Err(e),
1161 }
1162 }
1163 pub fn is_ok(&self) -> bool {
1164 match self {
1165 $struct_name::Ok(_) => true,
1166 $struct_name::Err(_) => false,
1167 }
1168 }
1169 pub fn is_err(&self) -> bool {
1170 !self.is_ok()
1171 }
1172 }
1173 };
1174}
1175
1176#[macro_export]
1177macro_rules! impl_result {
1178 ($ok_struct_type:ident, $err_struct_type:ident, $struct_name:ident, copy = false, clone = false, [$($derive:meta),* ]) => (
1179 $(#[derive($derive)])*
1180 #[repr(C, u8)]
1181 pub enum $struct_name {
1182 Ok($ok_struct_type),
1183 Err($err_struct_type)
1184 }
1185
1186 impl $struct_name {
1187 pub fn into_result(self) -> Result<$ok_struct_type, $err_struct_type> {
1188 match self {
1189 $struct_name::Ok(o) => Ok(o),
1190 $struct_name::Err(e) => Err(e),
1191 }
1192 }
1193 }
1194
1195 impl_result_inner!($ok_struct_type, $err_struct_type, $struct_name);
1196 );
1197 ($ok_struct_type:ident, $err_struct_type:ident, $struct_name:ident, copy = false, [$($derive:meta),* ]) => (
1198 $(#[derive($derive)])*
1199 #[repr(C, u8)]
1200 pub enum $struct_name {
1201 Ok($ok_struct_type),
1202 Err($err_struct_type)
1203 }
1204 impl $struct_name {
1205 pub fn into_result(&self) -> Result<$ok_struct_type, $err_struct_type> {
1206 match self {
1207 $struct_name::Ok(o) => Ok(o.clone()),
1208 $struct_name::Err(e) => Err(e.clone()),
1209 }
1210 }
1211 }
1212
1213 impl_result_inner!($ok_struct_type, $err_struct_type, $struct_name);
1214 );
1215 ($ok_struct_type:ident, $err_struct_type:ident, $struct_name:ident, [$($derive:meta),* ]) => (
1216 $(#[derive($derive)])*
1217 #[repr(C, u8)]
1218 pub enum $struct_name {
1219 Ok($ok_struct_type),
1220 Err($err_struct_type)
1221 }
1222
1223 impl $struct_name {
1224 pub fn into_result(&self) -> Result<$ok_struct_type, $err_struct_type> {
1225 match self {
1226 $struct_name::Ok(o) => Ok(*o),
1227 $struct_name::Err(e) => Err(*e),
1228 }
1229 }
1230 }
1231
1232 impl_result_inner!($ok_struct_type, $err_struct_type, $struct_name);
1233 );
1234}
1235
1236macro_rules! impl_color_value_fmt {
1237 ($struct_name:ty) => {
1238 impl FormatAsRustCode for $struct_name {
1239 fn format_as_rust_code(&self, _tabs: usize) -> String {
1240 format!(
1241 "{} {{ inner: {} }}",
1242 stringify!($struct_name),
1243 format_color_value(&self.inner)
1244 )
1245 }
1246 }
1247 };
1248}
1249
1250macro_rules! impl_enum_fmt {($enum_name:ident, $($enum_type:ident),+) => (
1251 impl crate::codegen::format::FormatAsRustCode for $enum_name {
1252 fn format_as_rust_code(&self, _tabs: usize) -> String {
1253 match self {
1254 $(
1255 $enum_name::$enum_type => {
1256 String::from(
1257 concat!(stringify!($enum_name), "::", stringify!($enum_type))
1258 )
1259 },
1260 )+
1261 }
1262 }
1263 }
1264)}