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}