1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
use crate::ast;
use proc_macro2::{Span, TokenStream};
use quote::quote;
pub(super) fn generate_interning_tables(schema: &ast::DatabaseSchema) -> TokenStream {
let mut fields = TokenStream::new();
let mut conversions = TokenStream::new();
let mut longest = 2;
for ast::InterningTable {
ref name,
ref key,
ref value,
} in &schema.interning_tables
{
let key_type = &key.name;
let field = quote! {
pub #name: InterningTable<#key_type, #value>,
};
fields.extend(field);
if let syn::Type::Tuple(syn::TypeTuple { elems, .. }) = value {
if longest < elems.len() {
longest = elems.len();
}
}
}
let mut args = TokenStream::new();
let mut type_args = TokenStream::new();
let mut type_constraints = TokenStream::new();
for i in 0..longest {
let arg = syn::Ident::new(&format!("v{}", i), Span::call_site());
let type_arg = syn::Ident::new(&format!("V{}", i), Span::call_site());
args.extend(quote! {#arg,});
type_args.extend(quote! {#type_arg,});
type_constraints.extend(quote! {
#type_arg: crate::data_structures::InterningTableValue,
});
conversions.extend(quote! {
impl<K, #type_args> Into<Vec<(K, #type_args)>> for InterningTable<K, (#type_args)>
where
K: crate::data_structures::InterningTableKey,
#type_constraints
{
fn into(self) -> Vec<(K, #type_args)> {
self.contents.into_iter().enumerate().map(|(i, (#args))| {
(i.into(), #args)
}).collect()
}
}
});
}
quote! {
use crate::data_structures::InterningTable;
#[derive(Default, Deserialize, Serialize)]
pub struct InterningTables {
#fields
}
#conversions
}
}