Skip to main content

ct_regex_internal/codegen/create_type/
class.rs

1#![allow(non_snake_case)]
2
3use proc_macro2::TokenStream;
4use quote::{ToTokens, quote};
5use syn::Ident;
6
7use crate::{codegen::{self, CodegenItem, ExprMetadata}, matcher::ClassEntry};
8
9impl<I: CodegenItem> ToTokens for ClassEntry<I> {
10    fn to_tokens(&self, tokens: &mut TokenStream) {
11        let ClassEntry = {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "ct_regex");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "internal");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "matcher");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "ClassEntry");
    _s
}quote!(::ct_regex::internal::matcher::ClassEntry);
12
13        let ClassEntry { value, is_upper_bound } = self;
14        tokens.extend({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&ClassEntry, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "value");
            ::quote::__private::push_colon(&mut _s);
            ::quote::ToTokens::to_tokens(&value, &mut _s);
            ::quote::__private::push_comma(&mut _s);
            ::quote::__private::push_ident(&mut _s, "is_upper_bound");
            ::quote::__private::push_colon(&mut _s);
            ::quote::ToTokens::to_tokens(&is_upper_bound, &mut _s);
            ::quote::__private::push_comma(&mut _s);
            _s
        });
    _s
}quote! {
15            #ClassEntry {
16                value: #value,
17                is_upper_bound: #is_upper_bound,
18            }
19        });
20    }
21}
22
23pub(crate) fn impl_classes<I: CodegenItem>(metadata: &ExprMetadata<I>) -> TokenStream {
24    metadata.classes.iter()
25        .enumerate()
26        .map(|(index, entries)| impl_class(&metadata.name, index, entries))
27        .collect()
28}
29
30pub(crate) fn impl_class<I: CodegenItem>(name: &Ident, index: usize, entries: &[ClassEntry<I>]) -> TokenStream {
31    let ClassTrait = {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "ct_regex");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "internal");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "matcher");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Class");
    _s
}quote!(::ct_regex::internal::matcher::Class);
32    let ClassEntry = {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "ct_regex");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "internal");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "matcher");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "ClassEntry");
    _s
}quote!(::ct_regex::internal::matcher::ClassEntry);
33
34    let ItemTy = codegen::type_ident::<I>();
35
36    let name = codegen::create_class_id::<I>(name, index);
37    let entries = entries.iter().map(|entry| {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&entry, &mut _s);
    _s
}quote!(#entry));
38
39    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_pound(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "derive");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "Default");
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Clone");
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Copy");
                    _s
                });
            _s
        });
    ::quote::__private::push_ident(&mut _s, "pub");
    ::quote::__private::push_ident(&mut _s, "struct");
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    ::quote::__private::push_semi(&mut _s);
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::ToTokens::to_tokens(&ClassTrait, &mut _s);
    ::quote::__private::push_lt(&mut _s);
    ::quote::ToTokens::to_tokens(&ItemTy, &mut _s);
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_ident(&mut _s, "for");
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "const");
            ::quote::__private::push_ident(&mut _s, "ENTRIES");
            ::quote::__private::push_colon(&mut _s);
            ::quote::__private::push_and(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Bracket,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::ToTokens::to_tokens(&ClassEntry, &mut _s);
                    ::quote::__private::push_lt(&mut _s);
                    ::quote::ToTokens::to_tokens(&ItemTy, &mut _s);
                    ::quote::__private::push_gt(&mut _s);
                    _s
                });
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::push_and(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Bracket,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    {
                        use ::quote::__private::ext::*;
                        let mut _first = true;
                        let has_iter = ::quote::__private::HasIterator::<false>;
                        #[allow(unused_mut)]
                        let (mut entries, i) = entries.quote_into_iter();
                        let has_iter = has_iter | i;
                        <_ as
                                ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                        while true {
                            let entries =
                                match entries.next() {
                                    Some(_x) => ::quote::__private::RepInterp(_x),
                                    None => break,
                                };
                            if !_first { ::quote::__private::push_comma(&mut _s); }
                            _first = false;
                            ::quote::ToTokens::to_tokens(&entries, &mut _s);
                        }
                    }
                    _s
                });
            ::quote::__private::push_semi(&mut _s);
            _s
        });
    _s
}quote! {
40        #[derive(Default, Clone, Copy)]
41        pub struct #name;
42
43        impl #ClassTrait<#ItemTy> for #name {
44            const ENTRIES: &[#ClassEntry<#ItemTy>] = &[#(#entries),*];
45        }
46    }
47}