1use std::{rc::Rc, sync::Arc};
4
5use futures::future::BoxFuture;
6
7use crate::{
8 Arguments as FieldArguments, ExecutionResult, Executor, GraphQLValue, Nullable, ScalarValue,
9};
10
11pub type Type = &'static str;
20
21pub type Types = &'static [Type];
25
26pub trait BaseType<S> {
39 const NAME: Type;
45}
46
47impl<'a, S, T: BaseType<S> + ?Sized> BaseType<S> for &'a T {
48 const NAME: Type = T::NAME;
49}
50
51impl<'ctx, S, T> BaseType<S> for (&'ctx T::Context, T)
52where
53 S: ScalarValue,
54 T: BaseType<S> + GraphQLValue<S>,
55{
56 const NAME: Type = T::NAME;
57}
58
59impl<S, T: BaseType<S>> BaseType<S> for Option<T> {
60 const NAME: Type = T::NAME;
61}
62
63impl<S, T: BaseType<S>> BaseType<S> for Nullable<T> {
64 const NAME: Type = T::NAME;
65}
66
67impl<S, T: BaseType<S>, E> BaseType<S> for Result<T, E> {
68 const NAME: Type = T::NAME;
69}
70
71impl<S, T: BaseType<S>> BaseType<S> for Vec<T> {
72 const NAME: Type = T::NAME;
73}
74
75impl<S, T: BaseType<S>> BaseType<S> for [T] {
76 const NAME: Type = T::NAME;
77}
78
79impl<S, T: BaseType<S>, const N: usize> BaseType<S> for [T; N] {
80 const NAME: Type = T::NAME;
81}
82
83impl<S, T: BaseType<S> + ?Sized> BaseType<S> for Box<T> {
84 const NAME: Type = T::NAME;
85}
86
87impl<S, T: BaseType<S> + ?Sized> BaseType<S> for Arc<T> {
88 const NAME: Type = T::NAME;
89}
90
91impl<S, T: BaseType<S> + ?Sized> BaseType<S> for Rc<T> {
92 const NAME: Type = T::NAME;
93}
94
95pub trait BaseSubTypes<S> {
102 const NAMES: Types;
106}
107
108impl<'a, S, T: BaseSubTypes<S> + ?Sized> BaseSubTypes<S> for &'a T {
109 const NAMES: Types = T::NAMES;
110}
111
112impl<'ctx, S, T> BaseSubTypes<S> for (&'ctx T::Context, T)
113where
114 S: ScalarValue,
115 T: BaseSubTypes<S> + GraphQLValue<S>,
116{
117 const NAMES: Types = T::NAMES;
118}
119
120impl<S, T: BaseSubTypes<S>> BaseSubTypes<S> for Option<T> {
121 const NAMES: Types = T::NAMES;
122}
123
124impl<S, T: BaseSubTypes<S>> BaseSubTypes<S> for Nullable<T> {
125 const NAMES: Types = T::NAMES;
126}
127
128impl<S, T: BaseSubTypes<S>, E> BaseSubTypes<S> for Result<T, E> {
129 const NAMES: Types = T::NAMES;
130}
131
132impl<S, T: BaseSubTypes<S>> BaseSubTypes<S> for Vec<T> {
133 const NAMES: Types = T::NAMES;
134}
135
136impl<S, T: BaseSubTypes<S>> BaseSubTypes<S> for [T] {
137 const NAMES: Types = T::NAMES;
138}
139
140impl<S, T: BaseSubTypes<S>, const N: usize> BaseSubTypes<S> for [T; N] {
141 const NAMES: Types = T::NAMES;
142}
143
144impl<S, T: BaseSubTypes<S> + ?Sized> BaseSubTypes<S> for Box<T> {
145 const NAMES: Types = T::NAMES;
146}
147
148impl<S, T: BaseSubTypes<S> + ?Sized> BaseSubTypes<S> for Arc<T> {
149 const NAMES: Types = T::NAMES;
150}
151
152impl<S, T: BaseSubTypes<S> + ?Sized> BaseSubTypes<S> for Rc<T> {
153 const NAMES: Types = T::NAMES;
154}
155
156pub type WrappedValue = u128;
158
159pub trait WrappedType<S> {
204 const VALUE: WrappedValue;
206}
207
208impl<'ctx, S, T: WrappedType<S>> WrappedType<S> for (&'ctx T::Context, T)
209where
210 S: ScalarValue,
211 T: GraphQLValue<S>,
212{
213 const VALUE: u128 = T::VALUE;
214}
215
216impl<S, T: WrappedType<S>> WrappedType<S> for Option<T> {
217 const VALUE: u128 = T::VALUE * 10 + 2;
218}
219
220impl<S, T: WrappedType<S>> WrappedType<S> for Nullable<T> {
221 const VALUE: u128 = T::VALUE * 10 + 2;
222}
223
224impl<S, T: WrappedType<S>, E> WrappedType<S> for Result<T, E> {
225 const VALUE: u128 = T::VALUE;
226}
227
228impl<S, T: WrappedType<S>> WrappedType<S> for Vec<T> {
229 const VALUE: u128 = T::VALUE * 10 + 3;
230}
231
232impl<S, T: WrappedType<S>> WrappedType<S> for [T] {
233 const VALUE: u128 = T::VALUE * 10 + 3;
234}
235
236impl<S, T: WrappedType<S>, const N: usize> WrappedType<S> for [T; N] {
237 const VALUE: u128 = T::VALUE * 10 + 3;
238}
239
240impl<'a, S, T: WrappedType<S> + ?Sized> WrappedType<S> for &'a T {
241 const VALUE: u128 = T::VALUE;
242}
243
244impl<S, T: WrappedType<S> + ?Sized> WrappedType<S> for Box<T> {
245 const VALUE: u128 = T::VALUE;
246}
247
248impl<S, T: WrappedType<S> + ?Sized> WrappedType<S> for Arc<T> {
249 const VALUE: u128 = T::VALUE;
250}
251
252impl<S, T: WrappedType<S> + ?Sized> WrappedType<S> for Rc<T> {
253 const VALUE: u128 = T::VALUE;
254}
255
256pub type Name = &'static str;
264
265pub type Names = &'static [Name];
269
270pub type Argument = (Name, Type, WrappedValue);
274
275pub type Arguments = &'static [(Name, Type, WrappedValue)];
280
281pub type FieldName = u128;
283
284pub trait Fields<S> {
290 const NAMES: Names;
297}
298
299pub trait Implements<S> {
303 const NAMES: Types;
307}
308
309pub trait FieldMeta<S, const N: FieldName> {
322 type Context;
326
327 type TypeInfo;
331
332 const TYPE: Type;
336
337 const SUB_TYPES: Types;
342
343 const WRAPPED_VALUE: WrappedValue;
347
348 const ARGUMENTS: Arguments;
352}
353
354pub trait Field<S, const N: FieldName>: FieldMeta<S, N> {
359 fn call(
369 &self,
370 info: &Self::TypeInfo,
371 args: &FieldArguments<S>,
372 executor: &Executor<Self::Context, S>,
373 ) -> ExecutionResult<S>;
374}
375
376pub trait AsyncField<S, const N: FieldName>: FieldMeta<S, N> {
381 fn call<'b>(
390 &'b self,
391 info: &'b Self::TypeInfo,
392 args: &'b FieldArguments<S>,
393 executor: &'b Executor<Self::Context, S>,
394 ) -> BoxFuture<'b, ExecutionResult<S>>;
395}
396
397#[must_use]
402pub const fn fnv1a128(str: Name) -> u128 {
403 const FNV_OFFSET_BASIS: u128 = 0x6c62272e07bb014262b821756295c58d;
404 const FNV_PRIME: u128 = 0x0000000001000000000000000000013b;
405
406 let bytes = str.as_bytes();
407 let mut hash = FNV_OFFSET_BASIS;
408 let mut i = 0;
409 while i < bytes.len() {
410 hash ^= bytes[i] as u128;
411 hash = hash.wrapping_mul(FNV_PRIME);
412 i += 1;
413 }
414 hash
415}
416
417#[must_use]
419pub const fn type_len_with_wrapped_val(ty: Type, val: WrappedValue) -> usize {
420 let mut len = ty.as_bytes().len() + "!".as_bytes().len(); let mut curr = val;
423 while curr % 10 != 0 {
424 match curr % 10 {
425 2 => len -= "!".as_bytes().len(), 3 => len += "[]!".as_bytes().len(), _ => {}
428 }
429 curr /= 10;
430 }
431
432 len
433}
434
435#[must_use]
443pub const fn can_be_subtype(ty: WrappedValue, subtype: WrappedValue) -> bool {
444 let ty_curr = ty % 10;
445 let sub_curr = subtype % 10;
446
447 if ty_curr == sub_curr {
448 if ty_curr == 1 {
449 true
450 } else {
451 can_be_subtype(ty / 10, subtype / 10)
452 }
453 } else if ty_curr == 2 {
454 can_be_subtype(ty / 10, subtype)
455 } else {
456 false
457 }
458}
459
460#[must_use]
462pub const fn str_exists_in_arr(val: &str, arr: &[&str]) -> bool {
463 let mut i = 0;
464 while i < arr.len() {
465 if str_eq(val, arr[i]) {
466 return true;
467 }
468 i += 1;
469 }
470 false
471}
472
473pub const fn str_eq(l: &str, r: &str) -> bool {
481 let (l, r) = (l.as_bytes(), r.as_bytes());
482
483 if l.len() != r.len() {
484 return false;
485 }
486
487 let mut i = 0;
488 while i < l.len() {
489 if l[i] != r[i] {
490 return false;
491 }
492 i += 1;
493 }
494
495 true
496}
497
498#[macro_export]
503macro_rules! assert_implemented_for {
504 ($scalar: ty, $implementor: ty $(, $interfaces: ty)* $(,)?) => {
505 const _: () = {
506 $({
507 let is_present = $crate::macros::reflect::str_exists_in_arr(
508 <$implementor as ::juniper::macros::reflect::BaseType<$scalar>>::NAME,
509 <$interfaces as ::juniper::macros::reflect::BaseSubTypes<$scalar>>::NAMES,
510 );
511 if !is_present {
512 const MSG: &str = $crate::const_concat!(
513 "Failed to implement interface `",
514 <$interfaces as $crate::macros::reflect::BaseType<$scalar>>::NAME,
515 "` on `",
516 <$implementor as $crate::macros::reflect::BaseType<$scalar>>::NAME,
517 "`: missing implementer reference in interface's `for` attribute.",
518 );
519 ::std::panic!("{}", MSG);
520 }
521 })*
522 };
523 };
524}
525
526#[macro_export]
531macro_rules! assert_interfaces_impls {
532 ($scalar: ty, $interface: ty $(, $implementers: ty)* $(,)?) => {
533 const _: () = {
534 $({
535 let is_present = $crate::macros::reflect::str_exists_in_arr(
536 <$interface as ::juniper::macros::reflect::BaseType<$scalar>>::NAME,
537 <$implementers as ::juniper::macros::reflect::Implements<$scalar>>::NAMES,
538 );
539 if !is_present {
540 const MSG: &str = $crate::const_concat!(
541 "Failed to implement interface `",
542 <$interface as $crate::macros::reflect::BaseType<$scalar>>::NAME,
543 "` on `",
544 <$implementers as $crate::macros::reflect::BaseType<$scalar>>::NAME,
545 "`: missing interface reference in implementer's `impl` attribute.",
546 );
547 ::std::panic!("{}", MSG);
548 }
549 })*
550 };
551 };
552}
553
554#[macro_export]
559macro_rules! assert_transitive_impls {
560 ($scalar: ty, $interface: ty, $implementor: ty $(, $transitive: ty)* $(,)?) => {
561 const _: () = {
562 $({
563 let is_present = $crate::macros::reflect::str_exists_in_arr(
564 <$implementor as ::juniper::macros::reflect::BaseType<$scalar>>::NAME,
565 <$transitive as ::juniper::macros::reflect::BaseSubTypes<$scalar>>::NAMES,
566 );
567 if !is_present {
568 const MSG: &str = $crate::const_concat!(
569 "Failed to implement interface `",
570 <$interface as $crate::macros::reflect::BaseType<$scalar>>::NAME,
571 "` on `",
572 <$implementor as $crate::macros::reflect::BaseType<$scalar>>::NAME,
573 "`: missing `impl = ` for transitive interface `",
574 <$transitive as $crate::macros::reflect::BaseType<$scalar>>::NAME,
575 "` on `",
576 <$implementor as $crate::macros::reflect::BaseType<$scalar>>::NAME,
577 "`."
578 );
579 ::std::panic!("{}", MSG);
580 }
581 })*
582 };
583 };
584}
585
586#[macro_export]
595macro_rules! assert_field {
596 (
597 $base_ty: ty,
598 $impl_ty: ty,
599 $scalar: ty,
600 $field_name: expr $(,)?
601 ) => {
602 $crate::assert_field_args!($base_ty, $impl_ty, $scalar, $field_name);
603 $crate::assert_subtype!($base_ty, $impl_ty, $scalar, $field_name);
604 };
605}
606
607#[macro_export]
613macro_rules! assert_subtype {
614 (
615 $base_ty: ty,
616 $impl_ty: ty,
617 $scalar: ty,
618 $field_name: expr $(,)?
619 ) => {
620 const _: () = {
621 const BASE_TY: $crate::macros::reflect::Type =
622 <$base_ty as $crate::macros::reflect::BaseType<$scalar>>::NAME;
623 const IMPL_TY: $crate::macros::reflect::Type =
624 <$impl_ty as $crate::macros::reflect::BaseType<$scalar>>::NAME;
625 const ERR_PREFIX: &str = $crate::const_concat!(
626 "Failed to implement interface `",
627 BASE_TY,
628 "` on `",
629 IMPL_TY,
630 "`: ",
631 );
632
633 const FIELD_NAME: $crate::macros::reflect::Name =
634 $field_name;
635
636 const BASE_RETURN_WRAPPED_VAL: $crate::macros::reflect::WrappedValue =
637 <$base_ty as $crate::macros::reflect::FieldMeta<
638 $scalar,
639 { $crate::checked_hash!(FIELD_NAME, $base_ty, $scalar, ERR_PREFIX) },
640 >>::WRAPPED_VALUE;
641 const IMPL_RETURN_WRAPPED_VAL: $crate::macros::reflect::WrappedValue =
642 <$impl_ty as $crate::macros::reflect::FieldMeta<
643 $scalar,
644 { $crate::checked_hash!(FIELD_NAME, $impl_ty, $scalar, ERR_PREFIX) },
645 >>::WRAPPED_VALUE;
646
647 const BASE_RETURN_TY: $crate::macros::reflect::Type =
648 <$base_ty as $crate::macros::reflect::FieldMeta<
649 $scalar,
650 { $crate::checked_hash!(FIELD_NAME, $base_ty, $scalar, ERR_PREFIX) },
651 >>::TYPE;
652 const IMPL_RETURN_TY: $crate::macros::reflect::Type =
653 <$impl_ty as $crate::macros::reflect::FieldMeta<
654 $scalar,
655 { $crate::checked_hash!(FIELD_NAME, $impl_ty, $scalar, ERR_PREFIX) },
656 >>::TYPE;
657
658 const BASE_RETURN_SUB_TYPES: $crate::macros::reflect::Types =
659 <$base_ty as $crate::macros::reflect::FieldMeta<
660 $scalar,
661 { $crate::checked_hash!(FIELD_NAME, $base_ty, $scalar, ERR_PREFIX) },
662 >>::SUB_TYPES;
663
664 let is_subtype = $crate::macros::reflect::str_exists_in_arr(IMPL_RETURN_TY, BASE_RETURN_SUB_TYPES)
665 && $crate::macros::reflect::can_be_subtype(BASE_RETURN_WRAPPED_VAL, IMPL_RETURN_WRAPPED_VAL);
666 if !is_subtype {
667 const MSG: &str = $crate::const_concat!(
668 ERR_PREFIX,
669 "Field `",
670 FIELD_NAME,
671 "`: implementor is expected to return a subtype of interface's return object: `",
672 $crate::format_type!(IMPL_RETURN_TY, IMPL_RETURN_WRAPPED_VAL),
673 "` is not a subtype of `",
674 $crate::format_type!(BASE_RETURN_TY, BASE_RETURN_WRAPPED_VAL),
675 "`.",
676 );
677 ::std::panic!("{}", MSG);
678 }
679 };
680 };
681}
682
683#[macro_export]
688macro_rules! assert_field_args {
689 (
690 $base_ty: ty,
691 $impl_ty: ty,
692 $scalar: ty,
693 $field_name: expr $(,)?
694 ) => {
695 const _: () = {
696 const BASE_NAME: &str = <$base_ty as $crate::macros::reflect::BaseType<$scalar>>::NAME;
697 const IMPL_NAME: &str = <$impl_ty as $crate::macros::reflect::BaseType<$scalar>>::NAME;
698 const ERR_PREFIX: &str = $crate::const_concat!(
699 "Failed to implement interface `",
700 BASE_NAME,
701 "` on `",
702 IMPL_NAME,
703 "`: ",
704 );
705
706 const FIELD_NAME: &str = $field_name;
707
708 const BASE_ARGS: ::juniper::macros::reflect::Arguments =
709 <$base_ty as $crate::macros::reflect::FieldMeta<
710 $scalar,
711 { $crate::checked_hash!(FIELD_NAME, $base_ty, $scalar, ERR_PREFIX) },
712 >>::ARGUMENTS;
713 const IMPL_ARGS: ::juniper::macros::reflect::Arguments =
714 <$impl_ty as $crate::macros::reflect::FieldMeta<
715 $scalar,
716 { $crate::checked_hash!(FIELD_NAME, $impl_ty, $scalar, ERR_PREFIX) },
717 >>::ARGUMENTS;
718
719 struct Error {
720 cause: Cause,
721 base: ::juniper::macros::reflect::Argument,
722 implementation: ::juniper::macros::reflect::Argument,
723 }
724
725 enum Cause {
726 RequiredField,
727 AdditionalNonNullableField,
728 TypeMismatch,
729 }
730
731 const fn unwrap_error(v: ::std::result::Result<(), Error>) -> Error {
732 match v {
733 Ok(()) => Error {
736 cause: Cause::RequiredField,
737 base: ("unreachable", "unreachable", 1),
738 implementation: ("unreachable", "unreachable", 1),
739 },
740 Err(err) => err,
741 }
742 }
743
744 const fn check() -> Result<(), Error> {
745 let mut base_i = 0;
746 while base_i < BASE_ARGS.len() {
747 let (base_name, base_type, base_wrap_val) = BASE_ARGS[base_i];
748
749 let mut impl_i = 0;
750 let mut was_found = false;
751 while impl_i < IMPL_ARGS.len() {
752 let (impl_name, impl_type, impl_wrap_val) = IMPL_ARGS[impl_i];
753
754 if $crate::macros::reflect::str_eq(base_name, impl_name) {
755 if $crate::macros::reflect::str_eq(base_type, impl_type)
756 && base_wrap_val == impl_wrap_val
757 {
758 was_found = true;
759 break;
760 } else {
761 return Err(Error {
762 cause: Cause::TypeMismatch,
763 base: (base_name, base_type, base_wrap_val),
764 implementation: (impl_name, impl_type, impl_wrap_val),
765 });
766 }
767 }
768
769 impl_i += 1;
770 }
771
772 if !was_found {
773 return Err(Error {
774 cause: Cause::RequiredField,
775 base: (base_name, base_type, base_wrap_val),
776 implementation: (base_name, base_type, base_wrap_val),
777 });
778 }
779
780 base_i += 1;
781 }
782
783 let mut impl_i = 0;
784 while impl_i < IMPL_ARGS.len() {
785 let (impl_name, impl_type, impl_wrapped_val) = IMPL_ARGS[impl_i];
786 impl_i += 1;
787
788 if impl_wrapped_val % 10 == 2 {
789 continue;
790 }
791
792 let mut base_i = 0;
793 let mut was_found = false;
794 while base_i < BASE_ARGS.len() {
795 let (base_name, _, _) = BASE_ARGS[base_i];
796 if $crate::macros::reflect::str_eq(base_name, impl_name) {
797 was_found = true;
798 break;
799 }
800 base_i += 1;
801 }
802 if !was_found {
803 return Err(Error {
804 cause: Cause::AdditionalNonNullableField,
805 base: (impl_name, impl_type, impl_wrapped_val),
806 implementation: (impl_name, impl_type, impl_wrapped_val),
807 });
808 }
809 }
810
811 Ok(())
812 }
813
814 const RES: ::std::result::Result<(), Error> = check();
815 if RES.is_err() {
816 const ERROR: Error = unwrap_error(RES);
817
818 const BASE_ARG_NAME: &str = ERROR.base.0;
819 const IMPL_ARG_NAME: &str = ERROR.implementation.0;
820
821 const BASE_TYPE_FORMATTED: &str = $crate::format_type!(ERROR.base.1, ERROR.base.2);
822 const IMPL_TYPE_FORMATTED: &str =
823 $crate::format_type!(ERROR.implementation.1, ERROR.implementation.2);
824
825 const MSG: &str = match ERROR.cause {
826 Cause::TypeMismatch => {
827 $crate::const_concat!(
828 "Argument `",
829 BASE_ARG_NAME,
830 "`: expected type `",
831 BASE_TYPE_FORMATTED,
832 "`, found: `",
833 IMPL_TYPE_FORMATTED,
834 "`.",
835 )
836 }
837 Cause::RequiredField => {
838 $crate::const_concat!(
839 "Argument `",
840 BASE_ARG_NAME,
841 "` of type `",
842 BASE_TYPE_FORMATTED,
843 "` was expected, but not found."
844 )
845 }
846 Cause::AdditionalNonNullableField => {
847 $crate::const_concat!(
848 "Argument `",
849 IMPL_ARG_NAME,
850 "` of type `",
851 IMPL_TYPE_FORMATTED,
852 "` isn't present on the interface and so has to be nullable."
853 )
854 }
855 };
856 const ERROR_MSG: &str =
857 $crate::const_concat!(ERR_PREFIX, "Field `", FIELD_NAME, "`: ", MSG);
858 ::std::panic!("{}", ERROR_MSG);
859 }
860 };
861 };
862}
863
864#[macro_export]
866macro_rules! const_concat {
867 ($($s:expr),* $(,)?) => {{
868 const LEN: usize = 0 $(+ $s.as_bytes().len())*;
869 const CNT: usize = [$($s),*].len();
870 const fn concat(input: [&str; CNT]) -> [u8; LEN] {
871 let mut bytes = [0; LEN];
872 let (mut i, mut byte) = (0, 0);
873 while i < CNT {
874 let mut b = 0;
875 while b < input[i].len() {
876 bytes[byte] = input[i].as_bytes()[b];
877 byte += 1;
878 b += 1;
879 }
880 i += 1;
881 }
882 bytes
883 }
884 const CON: [u8; LEN] = concat([$($s),*]);
885
886 match ::std::str::from_utf8(&CON) {
888 ::std::result::Result::Ok(s) => s,
889 _ => unreachable!(),
890 }
891 }};
892}
893
894#[macro_export]
897macro_rules! checked_hash {
898 ($field_name: expr, $impl_ty: ty, $scalar: ty $(, $prefix: expr)? $(,)?) => {{
899 let exists = $crate::macros::reflect::str_exists_in_arr(
900 $field_name,
901 <$impl_ty as $crate::macros::reflect::Fields<$scalar>>::NAMES,
902 );
903 if exists {
904 $crate::macros::reflect::fnv1a128(FIELD_NAME)
905 } else {
906 const MSG: &str = $crate::const_concat!(
907 $($prefix,)?
908 "Field `",
909 $field_name,
910 "` isn't implemented on `",
911 <$impl_ty as $crate::macros::reflect::BaseType<$scalar>>::NAME,
912 "`."
913 );
914 ::std::panic!("{}", MSG)
915 }
916 }};
917}
918
919#[macro_export]
931macro_rules! format_type {
932 ($ty: expr, $wrapped_value: expr $(,)?) => {{
933 const TYPE: (
934 $crate::macros::reflect::Type,
935 $crate::macros::reflect::WrappedValue,
936 ) = ($ty, $wrapped_value);
937 const RES_LEN: usize = $crate::macros::reflect::type_len_with_wrapped_val(TYPE.0, TYPE.1);
938
939 const OPENING_BRACKET: &str = "[";
940 const CLOSING_BRACKET: &str = "]";
941 const BANG: &str = "!";
942
943 const fn format_type_arr() -> [u8; RES_LEN] {
944 let (ty, wrap_val) = TYPE;
945 let mut type_arr: [u8; RES_LEN] = [0; RES_LEN];
946
947 let mut current_start = 0;
948 let mut current_end = RES_LEN - 1;
949 let mut current_wrap_val = wrap_val;
950 let mut is_null = false;
951 while current_wrap_val % 10 != 0 {
952 match current_wrap_val % 10 {
953 2 => is_null = true, 3 => {
955 let mut i = 0;
957 while i < OPENING_BRACKET.as_bytes().len() {
958 type_arr[current_start + i] = OPENING_BRACKET.as_bytes()[i];
959 i += 1;
960 }
961 current_start += i;
962 if !is_null {
963 i = 0;
965 while i < BANG.as_bytes().len() {
966 type_arr[current_end - BANG.as_bytes().len() + i + 1] =
967 BANG.as_bytes()[i];
968 i += 1;
969 }
970 current_end -= i;
971 }
972 i = 0;
974 while i < CLOSING_BRACKET.as_bytes().len() {
975 type_arr[current_end - CLOSING_BRACKET.as_bytes().len() + i + 1] =
976 CLOSING_BRACKET.as_bytes()[i];
977 i += 1;
978 }
979 current_end -= i;
980 is_null = false;
981 }
982 _ => {}
983 }
984
985 current_wrap_val /= 10;
986 }
987
988 let mut i = 0;
990 while i < ty.as_bytes().len() {
991 type_arr[current_start + i] = ty.as_bytes()[i];
992 i += 1;
993 }
994 i = 0;
995 if !is_null {
996 while i < BANG.as_bytes().len() {
998 type_arr[current_end - BANG.as_bytes().len() + i + 1] = BANG.as_bytes()[i];
999 i += 1;
1000 }
1001 }
1002
1003 type_arr
1004 }
1005
1006 const TYPE_ARR: [u8; RES_LEN] = format_type_arr();
1007
1008 const TYPE_FORMATTED: &str = match ::std::str::from_utf8(TYPE_ARR.as_slice()) {
1010 ::std::result::Result::Ok(s) => s,
1011 _ => unreachable!(),
1012 };
1013
1014 TYPE_FORMATTED
1015 }};
1016}