1extern crate proc_macro;
2
3use proc_macro::TokenStream;
4use quote::quote;
5use syn::{parse_macro_input, Attribute, DeriveInput};
6
7#[proc_macro_derive(Columnar, attributes(columnar))]
8pub fn derive(input: TokenStream) -> TokenStream {
9
10 let ast = parse_macro_input!(input as DeriveInput);
11 let name = &ast.ident;
12
13 let attr = extract_attr(&ast.attrs);
14
15 match ast.data {
16 syn::Data::Struct(data_struct) => {
17 match data_struct.fields {
18 syn::Fields::Unit => derive_unit_struct(name, &ast.generics, ast.vis, attr),
19 _ => derive_struct(name, &ast.generics, data_struct, ast.vis, attr),
20 }
21 }
22 syn::Data::Enum(data_enum) => {
23 derive_enum(name, &ast.generics, data_enum, ast.vis, attr)
24 }
25 syn::Data::Union(_) => unimplemented!("Unions are unsupported by Columnar"),
26 }
27}
28
29fn extract_attr(attrs: &[Attribute]) -> Option<proc_macro2::TokenStream> {
30 for attr in attrs {
31 if attr.path().is_ident("columnar") {
32 return Some(attr.parse_args().unwrap());
33 }
34 }
35 None
36}
37
38fn derive_struct(name: &syn::Ident, generics: &syn::Generics, data_struct: syn::DataStruct, vis: syn::Visibility, attr: Option<proc_macro2::TokenStream>) -> proc_macro::TokenStream {
39
40 let c_name = format!("{}Container", name);
41 let c_ident = syn::Ident::new(&c_name, name.span());
42
43 let r_name = format!("{}Reference", name);
44 let r_ident = syn::Ident::new(&r_name, name.span());
45
46 let named = match &data_struct.fields {
47 syn::Fields::Named(_) => true,
48 syn::Fields::Unnamed(_) => false,
49 _ => unimplemented!(),
50 };
51
52 let names: &Vec<_> = &match &data_struct.fields {
53 syn::Fields::Named(fields) => fields.named.iter().map(|field| field.ident.clone().unwrap()).collect(),
54 syn::Fields::Unnamed(fields) => (0 .. fields.unnamed.len()).map(|index| syn::Ident::new(&format!("f{}", index), name.span())).collect(),
55 _ => unimplemented!(),
56 };
57
58 let types: &Vec<_> = &match &data_struct.fields {
59 syn::Fields::Named(fields) => fields.named.iter().map(|field| &field.ty).collect(),
60 syn::Fields::Unnamed(fields) => fields.unnamed.iter().map(|field| &field.ty).collect(),
61 _ => unimplemented!(),
62 };
63
64 let container_types = &names.iter().enumerate().map(|(index, name)| {
66 let new_name = format!("C{}", index);
67 syn::Ident::new(&new_name, name.span())
68 }).collect::<Vec<_>>();
69
70 #[cfg(feature = "serde")]
72 let derive = quote! { #[derive(Copy, Clone, Debug, Default, serde::Serialize, serde::Deserialize)] };
73 #[cfg(not(feature = "serde"))]
74 let derive = quote! { #[derive(Copy, Clone, Debug, Default)] };
75
76 let container_struct = {
77 quote! {
78 #derive
80 #vis struct #c_ident < #(#container_types),* >{
81 #(
82 pub #names : #container_types,
84 )*
85 }
86 }
87 };
88
89 let reference_struct = {
90
91 let reference_types = &names.iter().enumerate().map(|(index, name)| {
92 let new_name = format!("R{}", index);
93 syn::Ident::new(&new_name, name.span())
94 }).collect::<Vec<_>>();
95
96 let ty_gen = quote! { < #(#reference_types),* > };
97
98 let attr = if let Some(attr) = attr {
99 quote! { #[#attr] }
100 } else {
101 quote! {}
102 };
103
104 quote! {
105 #[derive(Copy, Clone, Debug)]
107 #attr
108 #vis struct #r_ident #ty_gen {
109 #(
110 pub #names : #reference_types,
112 )*
113 }
114 }
115 };
116
117 let partial_eq = {
118
119 let reference_types = &names.iter().enumerate().map(|(index, name)| {
120 let new_name = format!("R{}", index);
121 syn::Ident::new(&new_name, name.span())
122 }).collect::<Vec<_>>();
123
124 let (_impl_gen, ty_gen, _where_clause) = generics.split_for_impl();
125
126 let struct_generics = generics.params.iter();
127 let impl_gen = quote! { < #(#struct_generics,)* #(#reference_types),* > };
128
129 let where_clause = quote! { where #(#reference_types: PartialEq<#types>),* };
130
131 let destructure_self =
133 if named { quote! { let #name { #(#names),* } = other; } }
134 else { quote! { let #name ( #(#names),* ) = other; } };
135
136 quote! {
137 impl #impl_gen PartialEq<#name #ty_gen> for #r_ident < #(#reference_types),* > #where_clause {
138 #[inline(always)]
139 fn eq(&self, other: &#name #ty_gen) -> bool {
140 #destructure_self
141 #(self.#names == *#names) &&*
142 }
143 }
144 }
145
146 };
147
148 let push_own = {
149 let (_impl_gen, ty_gen, _where_clause) = generics.split_for_impl();
150 let push = names.iter().map(|name| { quote! { self.#name.push(#name); } });
151
152 let struct_generics = generics.params.iter();
153 let impl_gen = quote! { < #(#struct_generics,)* #(#container_types),* > };
154
155 let where_clause2 = quote! { where #(#container_types: ::columnar::Push<#types>),* };
156
157 let destructure_self =
159 if named { quote! { let #name { #(#names),* } = item; } }
160 else { quote! { let #name ( #(#names),* ) = item; } };
161
162 quote! {
163 impl #impl_gen ::columnar::Push<#name #ty_gen> for #c_ident < #(#container_types),* > #where_clause2 {
164 #[inline]
165 fn push(&mut self, item: #name #ty_gen) {
166 #destructure_self
167 #(#push)*
168 }
169 }
170 }
171 };
172
173 let push_ref = {
174 let (_impl_gen, ty_gen, _where_clause) = generics.split_for_impl();
175 let push = names.iter().map(|name| { quote! { self.#name.push(#name); } });
176
177 let struct_generics = generics.params.iter();
178 let impl_gen = quote! { < 'columnar, #(#struct_generics,)* #(#container_types),* > };
179
180 let where_clause2 = quote! { where #(#container_types: ::columnar::Push<&'columnar #types>),* };
181
182 let destructure_self =
183 if named { quote! { let #name { #(#names),* } = item; } }
184 else { quote! { let #name ( #(#names),* ) = item; } };
185
186 quote! {
187 impl #impl_gen ::columnar::Push<&'columnar #name #ty_gen> for #c_ident < #(#container_types),* > #where_clause2 {
188 #[inline]
189 fn push(&mut self, item: &'columnar #name #ty_gen) {
190 #destructure_self
191 #(#push)*
192 }
193 }
194 }
195 };
196
197 let push_new = {
199
200 let reference_types = &names.iter().enumerate().map(|(index, name)| {
201 let new_name = format!("R{}", index);
202 syn::Ident::new(&new_name, name.span())
203 }).collect::<Vec<_>>();
204
205 let push = names.iter().map(|name| { quote! { self.#name.push(#name); } });
206
207 let impl_gen = quote! { < #(#container_types,)* #(#reference_types),* > };
208
209 let where_clause = quote! { where #(#container_types: ::columnar::Push<#reference_types>),* };
210
211 let index_type = quote! { #r_ident < #(#reference_types,)* > };
212 let destructure_self = quote! { let #r_ident { #(#names),* } = item; };
213
214 quote! {
215 impl #impl_gen ::columnar::Push<#index_type> for #c_ident < #(#container_types),* > #where_clause {
216 #[inline]
217 fn push(&mut self, item: #index_type) {
218 #destructure_self
219 #(#push)*
220 }
221 }
222 }
223 };
224
225 let index_own = {
226 let impl_gen = quote! { < #(#container_types),* > };
227 let ty_gen = quote! { < #(#container_types),* > };
228 let where_clause = quote! { where #(#container_types: ::columnar::Index),* };
229
230 let index_type = quote! { #r_ident < #(<#container_types as ::columnar::Index>::Ref,)* > };
231
232 quote! {
233 impl #impl_gen ::columnar::Index for #c_ident #ty_gen #where_clause {
234 type Ref = #index_type;
235 #[inline(always)]
236 fn get(&self, index: usize) -> Self::Ref {
237 #r_ident { #(#names: self.#names.get(index),)* }
238 }
239 }
240 }
241 };
242
243 let index_ref = {
244 let impl_gen = quote! { < 'columnar, #(#container_types),* > };
245 let ty_gen = quote! { < #(#container_types),* > };
246 let where_clause = quote! { where #(&'columnar #container_types: ::columnar::Index),* };
247
248 let index_type = quote! { #r_ident < #(<&'columnar #container_types as ::columnar::Index>::Ref,)* > };
249
250 quote! {
251 impl #impl_gen ::columnar::Index for &'columnar #c_ident #ty_gen #where_clause {
252 type Ref = #index_type;
253 #[inline(always)]
254 fn get(&self, index: usize) -> Self::Ref {
255 #r_ident { #(#names: (&self.#names).get(index),)* }
256 }
257 }
258 }
259 };
260
261 let clear = {
262
263 let impl_gen = quote! { < #(#container_types),* > };
264 let ty_gen = quote! { < #(#container_types),* > };
265 let where_clause = quote! { where #(#container_types: ::columnar::Clear),* };
266
267 quote! {
268 impl #impl_gen ::columnar::Clear for #c_ident #ty_gen #where_clause {
269 #[inline(always)]
270 fn clear(&mut self) { #(self.#names.clear());* }
271 }
272 }
273 };
274
275 let length = {
276
277 let impl_gen = quote! { < #(#container_types),* > };
278 let ty_gen = quote! { < #(#container_types),* > };
279 let where_clause = quote! { where #(#container_types: ::columnar::Len),* };
280
281 let first_name = &names[0];
282
283 quote! {
284 impl #impl_gen ::columnar::Len for #c_ident #ty_gen #where_clause {
285 #[inline(always)]
286 fn len(&self) -> usize {
287 self.#first_name.len()
288 }
289 }
290 }
291 };
292
293 let as_bytes = {
294
295 let impl_gen = quote! { <'a, #(#container_types),* > };
296 let ty_gen = quote! { < #(#container_types),* > };
297 let where_clause = quote! { where #(#container_types: ::columnar::AsBytes<'a>),* };
298
299 quote! {
300 impl #impl_gen ::columnar::AsBytes<'a> for #c_ident #ty_gen #where_clause {
301 #[inline(always)]
303 fn as_bytes(&self) -> impl Iterator<Item=(u64, &'a [u8])> {
304 let iter = None.into_iter();
305 #( let iter = ::columnar::chain(iter, self.#names.as_bytes()); )*
306 iter
307 }
308 }
309 }
310 };
311
312 let from_bytes = {
313
314 let impl_gen = quote! { < 'columnar, #(#container_types),* > };
315 let ty_gen = quote! { < #(#container_types),* > };
316 let where_clause = quote! { where #(#container_types: ::columnar::FromBytes<'columnar>),* };
317
318 quote! {
319 impl #impl_gen ::columnar::FromBytes<'columnar> for #c_ident #ty_gen #where_clause {
320 #[inline(always)]
321 fn from_bytes(bytes: &mut impl Iterator<Item=&'columnar [u8]>) -> Self {
322 Self { #(#names: ::columnar::FromBytes::from_bytes(bytes),)* }
323 }
324 }
325 }
326 };
327
328 let columnar_impl = {
329
330 let (impl_gen, ty_gen, where_clause) = generics.split_for_impl();
331
332 let where_clause2 = if let Some(struct_where) = where_clause {
333 let params = struct_where.predicates.iter();
334 quote! { where #(#types : ::columnar::Columnar,)* #(#params),* }
335 }
336 else {
337 quote! { where #(#types : ::columnar::Columnar,)* }
338 };
339
340 let destructure_self =
342 if named { quote! { let #name { #(#names),* } = self; } }
343 else { quote! { let #name ( #(#names),* ) = self; } };
344
345 let into_self =
347 if named { quote! { #name { #(#names: ::columnar::Columnar::into_owned(other.#names)),* } } }
348 else { quote! { #name ( #(::columnar::Columnar::into_owned(other.#names)),* ) } };
349
350 quote! {
351 impl #impl_gen ::columnar::Columnar for #name #ty_gen #where_clause2 {
352 #[inline(always)]
353 fn copy_from<'a>(&mut self, other: ::columnar::Ref<'a, Self>) {
354 #destructure_self
355 #( ::columnar::Columnar::copy_from(#names, other.#names); )*
356 }
357 #[inline(always)]
358 fn into_owned<'a>(other: ::columnar::Ref<'a, Self>) -> Self {
359 #into_self
360 }
361 type Container = #c_ident < #(<#types as ::columnar::Columnar>::Container ),* >;
362 }
363
364 impl < #( #container_types: ::columnar::Borrow ),* > ::columnar::Borrow for #c_ident < #( #container_types ),* > {
365 type Ref<'a> = #r_ident < #(<#container_types as ::columnar::Borrow>::Ref<'a>,)* > where #(#container_types: 'a,)*;
366 type Borrowed<'a> = #c_ident < #(<#container_types as ::columnar::Borrow>::Borrowed<'a> ),* > where #(#container_types: 'a,)*;
367 #[inline(always)]
368 fn borrow<'a>(&'a self) -> Self::Borrowed<'a> {
369 #c_ident {
370 #( #names: <#container_types as ::columnar::Borrow>::borrow(&self.#names), )*
371 }
372 }
373 #[inline(always)]
374 fn reborrow<'b, 'a: 'b>(thing: Self::Borrowed<'a>) -> Self::Borrowed<'b> {
375 #c_ident {
376 #( #names: <#container_types as ::columnar::Borrow>::reborrow(thing.#names), )*
377 }
378 }
379 #[inline(always)]
380 fn reborrow_ref<'b, 'a: 'b>(thing: Self::Ref<'a>) -> Self::Ref<'b> {
381 #r_ident {
382 #( #names: <#container_types as ::columnar::Borrow>::reborrow_ref(thing.#names), )*
383 }
384 }
385 }
386
387 impl < #( #container_types: ::columnar::Container ),* > ::columnar::Container for #c_ident < #( #container_types ),* > {
388 #[inline(always)]
389 fn extend_from_self(&mut self, other: Self::Borrowed<'_>, range: std::ops::Range<usize>) {
390 #( self.#names.extend_from_self(other.#names, range.clone()); )*
391 }
392
393 fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
394 #( self.#names.reserve_for(selves.clone().map(|x| x.#names)); )*
395 }
396 }
397 }
398 };
399
400
401 quote! {
402
403 #container_struct
404 #reference_struct
405
406 #partial_eq
407
408 #push_own
409 #push_ref
410 #push_new
411
412 #index_own
413 #index_ref
414 #length
415 #clear
416
417 #as_bytes
418 #from_bytes
419
420 #columnar_impl
421
422 }.into()
423}
424
425fn derive_unit_struct(name: &syn::Ident, _generics: &syn::Generics, vis: syn::Visibility, attr: Option<proc_macro2::TokenStream>) -> proc_macro::TokenStream {
427
428 let c_name = format!("{}Container", name);
429 let c_ident = syn::Ident::new(&c_name, name.span());
430
431 if attr.is_some() {
432 panic!("Unit structs do not support attributes");
433 }
434
435 #[cfg(feature = "serde")]
436 let derive = quote! { #[derive(Copy, Clone, Debug, Default, serde::Serialize, serde::Deserialize)] };
437 #[cfg(not(feature = "serde"))]
438 let derive = quote! { #[derive(Copy, Clone, Debug, Default)] };
439
440 quote! {
441
442 #derive
444 #vis struct #c_ident<CW = u64> {
445 pub count: CW,
447 }
448
449 impl ::columnar::Push<#name> for #c_ident {
450 #[inline]
451 fn push(&mut self, _item: #name) {
452 self.count += 1;
453 }
454 }
455
456 impl<'columnar> ::columnar::Push<&'columnar #name> for #c_ident {
457 #[inline]
458 fn push(&mut self, _item: &'columnar #name) {
459 self.count += 1;
460 }
461 }
462
463 impl<CW> ::columnar::Index for #c_ident<CW> {
464 type Ref = #name;
465 #[inline(always)]
466 fn get(&self, index: usize) -> Self::Ref {
467 #name
468 }
469 }
470
471 impl<'columnar, CW> ::columnar::Index for &'columnar #c_ident<CW> {
472 type Ref = #name;
473 #[inline(always)]
474 fn get(&self, index: usize) -> Self::Ref {
475 #name
476 }
477 }
478
479 impl ::columnar::Clear for #c_ident {
480 #[inline(always)]
481 fn clear(&mut self) {
482 self.count = 0;
483 }
484 }
485
486 impl<CW: Copy+::columnar::common::index::CopyAs<u64>> ::columnar::Len for #c_ident<CW> {
487 #[inline(always)]
488 fn len(&self) -> usize {
489 use ::columnar::common::index::CopyAs;
490 self.count.copy_as() as usize
491 }
492 }
493
494 impl<'a> ::columnar::AsBytes<'a> for #c_ident <&'a u64> {
495 #[inline(always)]
497 fn as_bytes(&self) -> impl Iterator<Item=(u64, &'a [u8])> {
498 std::iter::once((8, ::columnar::bytemuck::cast_slice(std::slice::from_ref(self.count))))
499 }
500 }
501
502 impl<'columnar> ::columnar::FromBytes<'columnar> for #c_ident <&'columnar u64> {
503 #[inline(always)]
504 fn from_bytes(bytes: &mut impl Iterator<Item=&'columnar [u8]>) -> Self {
505 Self { count: &::columnar::bytemuck::try_cast_slice(bytes.next().unwrap()).unwrap()[0] }
506 }
507 }
508
509 impl ::columnar::Columnar for #name {
510 #[inline(always)]
511 fn copy_from<'a>(&mut self, other: ::columnar::Ref<'a, Self>) { *self = other; }
512 #[inline(always)]
513 fn into_owned<'a>(other: ::columnar::Ref<'a, Self>) -> Self { other }
514 type Container = #c_ident;
515 }
516
517 impl ::columnar::Borrow for #c_ident {
518 type Ref<'a> = #name;
519 type Borrowed<'a> = #c_ident < &'a u64 >;
520 #[inline(always)]
521 fn borrow<'a>(&'a self) -> Self::Borrowed<'a> {
522 #c_ident { count: &self.count }
523 }
524 #[inline(always)]
525 fn reborrow<'b, 'a: 'b>(thing: Self::Borrowed<'a>) -> Self::Borrowed<'b> {
526 #c_ident { count: thing.count }
527 }
528 #[inline(always)]
529 fn reborrow_ref<'b, 'a: 'b>(thing: Self::Ref<'a>) -> Self::Ref<'b> { thing }
530 }
531
532 impl ::columnar::Container for #c_ident {
533 #[inline(always)]
534 fn extend_from_self(&mut self, _other: Self::Borrowed<'_>, range: std::ops::Range<usize>) {
535 self.count += range.len() as u64;
536 }
537
538 fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone { }
539 }
540
541 }.into()
542}
543
544#[allow(unused)]
547fn derive_enum(name: &syn::Ident, generics: &syn:: Generics, data_enum: syn::DataEnum, vis: syn::Visibility, attr: Option<proc_macro2::TokenStream>) -> proc_macro::TokenStream {
548
549 if data_enum.variants.iter().all(|variant| variant.fields.is_empty()) {
550 return derive_tags(name, generics, data_enum, vis);
551 }
552
553 let c_name = format!("{}Container", name);
554 let c_ident = syn::Ident::new(&c_name, name.span());
555
556 let r_name = format!("{}Reference", name);
557 let r_ident = syn::Ident::new(&r_name, name.span());
558
559 let variants: Vec<(&syn::Ident, Vec<_>)> =
562 data_enum
563 .variants
564 .iter()
565 .map(|variant| (
566 &variant.ident,
567 variant.fields.iter().map(|field| &field.ty).collect()
568 ))
569 .collect();
570
571 assert!(variants.len() <= 256, "Too many variants for enum");
573
574 let names = &variants.iter().map(|(ident, _)| ident).collect::<Vec<_>>();
575
576 let container_types = &names.iter().enumerate().map(|(index, name)| {
578 let new_name = format!("C{}", index);
579 syn::Ident::new(&new_name, name.span())
580 }).collect::<Vec<_>>();
581
582 #[cfg(feature = "serde")]
583 let derive = quote! { #[derive(Copy, Clone, Debug, Default, serde::Serialize, serde::Deserialize)] };
584 #[cfg(not(feature = "serde"))]
585 let derive = quote! { #[derive(Copy, Clone, Debug, Default)] };
586
587 let container_struct = {
588 quote! {
589 #derive
591 #[allow(non_snake_case)]
592 #vis struct #c_ident < #(#container_types,)* CVar = Vec<u8>, COff = Vec<u64>, >{
593 #(
594 pub #names : #container_types,
596 )*
597 pub variant: CVar,
599 pub offset: COff,
601 }
602 }
603 };
604
605 let reference_struct = {
606
607 let reference_types = &names.iter().enumerate().map(|(index, name)| {
608 let new_name = format!("R{}", index);
609 syn::Ident::new(&new_name, name.span())
610 }).collect::<Vec<_>>();
611
612 let ty_gen = quote! { < #(#reference_types),* > };
613
614 let attr = if let Some(attr) = attr {
615 quote! { #[#attr] }
616 } else {
617 quote! {}
618 };
619
620
621 quote! {
622 #[derive(Copy, Clone, Debug)]
624 #attr
625 #vis enum #r_ident #ty_gen {
626 #(
627 #names(#reference_types),
629 )*
630 }
631 }
632 };
633
634 let push_own = {
635
636 let (_impl_gen, ty_gen, _where_clause) = generics.split_for_impl();
637
638 let push = variants.iter().enumerate().map(|(index, (variant, types))| {
639
640 match data_enum.variants[index].fields {
641 syn::Fields::Unit => {
642 quote! {
643 #name::#variant => {
644 self.offset.push(self.#variant.len() as u64);
645 self.#variant.push(());
646 self.variant.push(#index as u8);
647 }
648 }
649 }
650 syn::Fields::Unnamed(_) => {
651 let temp_names = &types.iter().enumerate().map(|(index, _)| {
652 let new_name = format!("t{}", index);
653 syn::Ident::new(&new_name, variant.span())
654 }).collect::<Vec<_>>();
655
656 quote! {
657 #name::#variant( #(#temp_names),* ) => {
658 self.offset.push(self.#variant.len() as u64);
659 self.#variant.push((#(#temp_names),*));
660 self.variant.push(#index as u8);
661 },
662 }
663 }
664 syn::Fields::Named(_) => {
665 unimplemented!("Named fields in enum variants are not supported by Columnar");
666 }
667 }
668 });
669
670 let struct_generics = generics.params.iter();
671 let impl_gen = quote! { < #(#struct_generics,)* #(#container_types),* > };
672
673 let push_types = variants.iter().map(|(_, types)| quote! { (#(#types),*) });
674
675 let where_clause = quote! { where #(#container_types: ::columnar::Len + ::columnar::Push<#push_types>),* };
676
677 quote! {
678 impl #impl_gen ::columnar::Push<#name #ty_gen> for #c_ident < #(#container_types),* > #where_clause {
679 #[inline]
680 fn push(&mut self, item: #name #ty_gen) {
681 match item {
682 #( #push )*
683 }
684 }
685 }
686 }
687 };
688
689 let push_ref = {
690
691 let (_impl_gen, ty_gen, _where_clause) = generics.split_for_impl();
692
693 let push = variants.iter().enumerate().map(|(index, (variant, types))| {
694
695 match data_enum.variants[index].fields {
696 syn::Fields::Unit => {
697 quote! {
698 #name::#variant => {
699 self.offset.push(self.#variant.len() as u64);
700 self.#variant.push(());
701 self.variant.push(#index as u8);
702 }
703 }
704 }
705 syn::Fields::Unnamed(_) => {
706 let temp_names = &types.iter().enumerate().map(|(index, _)| {
707 let new_name = format!("t{}", index);
708 syn::Ident::new(&new_name, variant.span())
709 }).collect::<Vec<_>>();
710
711 quote! {
712 #name::#variant( #(#temp_names),* ) => {
713 self.offset.push(self.#variant.len() as u64);
714 self.#variant.push((#(#temp_names),*));
715 self.variant.push(#index as u8);
716 },
717 }
718 }
719 syn::Fields::Named(_) => {
720 unimplemented!("Named fields in enum variants are not supported by Columnar");
721 }
722 }
723 });
724
725 let struct_generics = generics.params.iter();
726 let impl_gen = quote! { < 'columnar, #(#struct_generics,)* #(#container_types),* > };
727
728 let push_types = variants.iter().map(|(_, types)| quote! { (#(&'columnar #types),*) });
729
730 let where_clause = quote! { where #(#container_types: ::columnar::Len + ::columnar::Push<#push_types>),* };
731
732 quote! {
733 impl #impl_gen ::columnar::Push<&'columnar #name #ty_gen> for #c_ident < #(#container_types),* > #where_clause {
734 #[inline]
735 fn push(&mut self, item: &'columnar #name #ty_gen) {
736 match item {
737 #( #push )*
738 }
739 }
740 }
741 }
742 };
743
744 let push_new = {
746
747 let reference_types = &names.iter().enumerate().map(|(index, name)| {
748 let new_name = format!("R{}", index);
749 syn::Ident::new(&new_name, name.span())
750 }).collect::<Vec<_>>();
751
752 let impl_gen = quote! { < #(#container_types,)* #(#reference_types),* > };
753
754 let where_clause = quote! { where #(#container_types: ::columnar::Len + ::columnar::Push<#reference_types>),* };
755
756 let index_type = quote! { #r_ident < #(#reference_types,)* > };
757 let numbers = (0 .. variants.len());
758
759 quote! {
760 impl #impl_gen ::columnar::Push<#index_type> for #c_ident < #(#container_types),* > #where_clause {
761 #[inline]
762 fn push(&mut self, item: #index_type) {
763 match item {
764 #(
765 #r_ident::#names(x) => {
766 self.offset.push(self.#names.len() as u64);
767 self.#names.push(x);
768 self.variant.push(#numbers as u8);
769 },
770 )*
771 }
772 }
773 }
774 }
775 };
776
777 let index_own = {
778 let impl_gen = quote! { < #(#container_types,)* CVal, COff> };
779 let ty_gen = quote! { < #(#container_types,)* CVal, COff> };
780 let where_clause = quote! { where #(#container_types: ::columnar::Index,)* CVal: ::columnar::Len + ::columnar::IndexAs<u8>, COff: ::columnar::Len + ::columnar::IndexAs<u64> };
781
782 let index_type = quote! { #r_ident < #(<#container_types as ::columnar::Index>::Ref,)* > };
783
784 let numbers = (0 .. variants.len());
786
787 quote! {
788 impl #impl_gen ::columnar::Index for #c_ident #ty_gen #where_clause {
789 type Ref = #index_type;
790 #[inline(always)]
791 fn get(&self, index: usize) -> Self::Ref {
792 match self.variant.index_as(index) as usize {
793 #( #numbers => #r_ident::#names(self.#names.get(self.offset.index_as(index) as usize)), )*
794 x => panic!("Unacceptable discriminant found: {:?}", x),
795 }
796 }
797 }
798 }
799 };
800
801 let index_ref = {
802 let impl_gen = quote! { < 'columnar, #(#container_types,)* CVal, COff> };
803 let ty_gen = quote! { < #(#container_types,)* CVal, COff> };
804 let where_clause = quote! { where #(&'columnar #container_types: ::columnar::Index,)* CVal: ::columnar::Len + ::columnar::IndexAs<u8>, COff: ::columnar::Len + ::columnar::IndexAs<u64> };
805
806 let index_type = quote! { #r_ident < #(<&'columnar #container_types as ::columnar::Index>::Ref,)* > };
807
808 let numbers = (0 .. variants.len());
810
811 quote! {
812 impl #impl_gen ::columnar::Index for &'columnar #c_ident #ty_gen #where_clause {
813 type Ref = #index_type;
814 #[inline(always)]
815 fn get(&self, index: usize) -> Self::Ref {
816 match self.variant.index_as(index) as usize {
817 #( #numbers => #r_ident::#names((&self.#names).get(self.offset.index_as(index) as usize)), )*
818 x => panic!("Unacceptable discriminant found: {:?}", x),
819 }
820 }
821 }
822 }
823 };
824
825 let clear = {
826
827 let impl_gen = quote! { < #(#container_types),* > };
828 let ty_gen = quote! { < #(#container_types),* > };
829 let where_clause = quote! { where #(#container_types: ::columnar::Clear),* };
830
831 quote! {
832 impl #impl_gen ::columnar::Clear for #c_ident #ty_gen #where_clause {
833 #[inline(always)]
834 fn clear(&mut self) {
835 #(self.#names.clear();)*
836 self.variant.clear();
837 self.offset.clear();
838 }
839 }
840 }
841 };
842
843 let length = {
844
845 let impl_gen = quote! { < #(#container_types,)* CVar, COff> };
846 let ty_gen = quote! { < #(#container_types,)* CVar, COff > };
847
848 quote! {
849 impl #impl_gen ::columnar::Len for #c_ident #ty_gen where CVar: ::columnar::Len {
850 #[inline(always)]
851 fn len(&self) -> usize {
852 self.variant.len()
853 }
854 }
855 }
856 };
857
858 let as_bytes = {
859
860 let impl_gen = quote! { < 'a, #(#container_types,)* CVar, COff> };
861 let ty_gen = quote! { < #(#container_types,)* CVar, COff > };
862 let where_clause = quote! { where #(#container_types: ::columnar::AsBytes<'a>,)* CVar: ::columnar::AsBytes<'a>, COff: ::columnar::AsBytes<'a> };
863
864 quote! {
865 impl #impl_gen ::columnar::AsBytes<'a> for #c_ident #ty_gen #where_clause {
866 #[inline(always)]
867 fn as_bytes(&self) -> impl Iterator<Item=(u64, &'a [u8])> {
868 let iter = None.into_iter();
869 #( let iter = ::columnar::chain(iter,self.#names.as_bytes()); )*
870 let iter = ::columnar::chain(iter, self.variant.as_bytes());
871 let iter = ::columnar::chain(iter, self.offset.as_bytes());
872 iter
873 }
874 }
875 }
876 };
877
878 let from_bytes = {
879
880 let impl_gen = quote! { < 'columnar, #(#container_types,)* CVar, COff> };
881 let ty_gen = quote! { < #(#container_types,)* CVar, COff > };
882 let where_clause = quote! { where #(#container_types: ::columnar::FromBytes<'columnar>,)* CVar: ::columnar::FromBytes<'columnar>, COff: ::columnar::FromBytes<'columnar> };
883
884 quote! {
885 #[allow(non_snake_case)]
886 impl #impl_gen ::columnar::FromBytes<'columnar> for #c_ident #ty_gen #where_clause {
887 #[inline(always)]
888 fn from_bytes(bytes: &mut impl Iterator<Item=&'columnar [u8]>) -> Self {
889 Self {
890 #(#names: ::columnar::FromBytes::from_bytes(bytes),)*
891 variant: ::columnar::FromBytes::from_bytes(bytes),
892 offset: ::columnar::FromBytes::from_bytes(bytes),
893 }
894 }
895 }
896 }
897 };
898
899 let columnar_impl = {
900
901 let (impl_gen, ty_gen, where_clause) = generics.split_for_impl();
902
903 let types = &variants.iter().flat_map(|(_, types)| types).collect::<Vec<_>>();
904
905 let where_clause2 = if let Some(enum_where) = where_clause {
906 let params = enum_where.predicates.iter();
907 quote! { where #(#types : ::columnar::Columnar,)* #(#params),* }
908 }
909 else {
910 quote! { where #(#types : ::columnar::Columnar,)* }
911 };
912
913
914 let variant_types = &variants.iter().map(|(_, types)| quote! { (#(#types),*) }).collect::<Vec<_>>();
915
916 let container_types = &variants.iter().map(|(_, types)| quote! { <(#(#types),*) as ::columnar::Columnar>::Container }).collect::<Vec<_>>();
917 let container_names = &names.iter().enumerate().map(|(index, name)| {
919 let new_name = format!("C{}", index);
920 syn::Ident::new(&new_name, name.span())
921 }).collect::<Vec<_>>();
922
923 let reference_args = variants.iter().map(|(_, types)| quote! { <(#(#types),*) as ::columnar::Columnar>::Ref<'a> });
924 let reference_args2 = reference_args.clone();
925
926 let copy_from = variants.iter().enumerate().map(|(index, (variant, types))| {
928
929 if data_enum.variants[index].fields == syn::Fields::Unit {
930 quote! {
931 (#name::#variant, #r_ident::#variant(_)) => { }
932 (_, #r_ident::#variant(_)) => { *self = #name::#variant; }
933 }
934 }
935 else {
936 let temp_names1 = &types.iter().enumerate().map(|(index, _)| {
937 let new_name = format!("s{}", index);
938 syn::Ident::new(&new_name, variant.span())
939 }).collect::<Vec<_>>();
940 let temp_names2 = &types.iter().enumerate().map(|(index, _)| {
941 let new_name = format!("t{}", index);
942 syn::Ident::new(&new_name, variant.span())
943 }).collect::<Vec<_>>();
944
945 quote! {
946 (#name::#variant( #( #temp_names1 ),* ), #r_ident::#variant( ( #( #temp_names2 ),* ) )) => {
947 #( ::columnar::Columnar::copy_from(#temp_names1, #temp_names2); )*
948 }
949 }
950 }
951 }).collect::<Vec<_>>();
952
953 let into_owned = variants.iter().enumerate().map(|(index, (variant, types))| {
955
956 if data_enum.variants[index].fields == syn::Fields::Unit {
957 quote! { #r_ident::#variant(_) => #name::#variant, }
958 }
959 else {
960 let temp_names = &types.iter().enumerate().map(|(index, _)| {
961 let new_name = format!("t{}", index);
962 syn::Ident::new(&new_name, variant.span())
963 }).collect::<Vec<_>>();
964
965 quote! {
966 #r_ident::#variant(( #( #temp_names ),* )) => {
967 #name::#variant( #( ::columnar::Columnar::into_owned(#temp_names) ),* )
968 },
969 }
970 }
971 }).collect::<Vec<_>>();
972
973 let reborrow_ref = variants.iter().enumerate().zip(container_names.iter()).map(|((index, (variant, types)), cname)| {
975 quote! {
976 #r_ident::#variant(( potato )) => {
977 #r_ident::#variant(( < (#cname) as ::columnar::Borrow >::reborrow_ref::<'b, 'a>( potato ) ))
978 },
979 }
980 }).collect::<Vec<_>>();
981
982 quote! {
983 impl #impl_gen ::columnar::Columnar for #name #ty_gen #where_clause2 {
984 #[inline(always)]
985 fn copy_from<'a>(&mut self, other: ::columnar::Ref<'a, Self>) {
986 match (&mut *self, other) {
987 #( #copy_from )*
988 (_, other) => { *self = Self::into_owned(other); }
989 }
990 }
991 #[inline(always)]
992 fn into_owned<'a>(other: ::columnar::Ref<'a, Self>) -> Self {
993 match other {
994 #( #into_owned )*
995 }
996 }
997 type Container = #c_ident < #(#container_types),* >;
998 }
999
1000 impl < #(#container_names : ::columnar::Borrow ),* > ::columnar::Borrow for #c_ident < #(#container_names),* > {
1001 type Ref<'a> = #r_ident < #( <#container_names as ::columnar::Borrow>::Ref<'a> ,)* > where Self: 'a, #(#container_names: 'a,)*;
1002 type Borrowed<'a> = #c_ident < #( < #container_names as ::columnar::Borrow >::Borrowed<'a>, )* &'a [u8], &'a [u64] > where #(#container_names: 'a,)*;
1003 #[inline(always)]
1004 fn borrow<'a>(&'a self) -> Self::Borrowed<'a> {
1005 #c_ident {
1006 #(#names: self.#names.borrow(),)*
1007 variant: self.variant.borrow(),
1008 offset: self.offset.borrow(),
1009 }
1010 }
1011 #[inline(always)]
1012 fn reborrow<'b, 'a: 'b>(thing: Self::Borrowed<'a>) -> Self::Borrowed<'b> {
1013 #c_ident {
1014 #(#names: <#container_names as ::columnar::Borrow>::reborrow(thing.#names),)*
1015 variant: <Vec<u8> as ::columnar::Borrow>::reborrow(thing.variant),
1016 offset: <Vec<u64> as ::columnar::Borrow>::reborrow(thing.offset),
1017 }
1018 }
1019 #[inline(always)]
1020 fn reborrow_ref<'b, 'a: 'b>(thing: Self::Ref<'a>) -> Self::Ref<'b> {
1021 match thing {
1022 #( #reborrow_ref )*
1023 }
1024 }
1025 }
1026
1027 impl < #(#container_names : ::columnar::Container ),* > ::columnar::Container for #c_ident < #(#container_names),* > {
1028 fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
1031 #( self.#names.reserve_for(selves.clone().map(|x| x.#names)); )*
1032 self.variant.reserve_for(selves.clone().map(|x| x.variant));
1033 self.offset.reserve_for(selves.map(|x| x.offset));
1034 }
1035 }
1036 }
1037 };
1038
1039 quote! {
1040
1041 #container_struct
1042 #reference_struct
1043
1044 #push_own
1045 #push_ref
1046 #push_new
1047
1048 #index_own
1049 #index_ref
1050 #length
1051 #clear
1052
1053 #as_bytes
1054 #from_bytes
1055
1056 #columnar_impl
1057
1058 }.into()
1059}
1060
1061#[allow(unused)]
1063fn derive_tags(name: &syn::Ident, _generics: &syn:: Generics, data_enum: syn::DataEnum, vis: syn::Visibility) -> proc_macro::TokenStream {
1064
1065 let c_name = format!("{}Container", name);
1066 let c_ident = syn::Ident::new(&c_name, name.span());
1067
1068 let names: Vec<&syn::Ident> =
1069 data_enum
1070 .variants
1071 .iter()
1072 .map(|variant| &variant.ident)
1073 .collect();
1074
1075 let indices: &Vec<u8> = &(0 .. names.len()).map(|x| x as u8).collect();
1076
1077 assert!(names.len() <= 256, "Too many variants for enum");
1079
1080 #[cfg(feature = "serde")]
1081 let derive = quote! { #[derive(Copy, Clone, Debug, Default, serde::Serialize, serde::Deserialize)] };
1082 #[cfg(not(feature = "serde"))]
1083 let derive = quote! { #[derive(Copy, Clone, Debug, Default)] };
1084
1085 quote! {
1086 #derive
1088 #vis struct #c_ident <CVar = Vec<u8>> {
1089 pub variant: CVar,
1091 }
1092
1093 impl<CV: ::columnar::common::PushIndexAs<u8>> ::columnar::Push<#name> for #c_ident<CV> {
1094 #[inline]
1095 fn push(&mut self, item: #name) {
1096 match item {
1097 #( #name::#names => self.variant.push(&#indices), )*
1098 }
1099 }
1100 }
1101
1102 impl<'columnar> ::columnar::Push<&'columnar #name> for #c_ident {
1103 #[inline]
1104 fn push(&mut self, item: &'columnar #name) {
1105 match *item {
1106 #( #name::#names => self.variant.push(#indices), )*
1107 }
1108 }
1109 }
1110
1111 impl<CVar: ::columnar::Len + ::columnar::IndexAs<u8>> ::columnar::Index for #c_ident <CVar> {
1112 type Ref = #name;
1113 #[inline(always)]
1114 fn get(&self, index: usize) -> Self::Ref {
1115 match self.variant.index_as(index) {
1116 #( #indices => #name::#names, )*
1117 x => panic!("Unacceptable discriminant found: {:?}", x),
1118 }
1119 }
1120 }
1121
1122 impl<'columnar, CVar: ::columnar::Len + ::columnar::IndexAs<u8>> ::columnar::Index for &'columnar #c_ident <CVar> {
1123 type Ref = #name;
1124 #[inline(always)]
1125 fn get(&self, index: usize) -> Self::Ref {
1126 match self.variant.index_as(index) {
1127 #( #indices => #name::#names, )*
1128 x => panic!("Unacceptable discriminant found: {:?}", x),
1129 }
1130 }
1131 }
1132
1133 impl<CVar: ::columnar::Clear> ::columnar::Clear for #c_ident <CVar> {
1134 #[inline(always)]
1135 fn clear(&mut self) {
1136 self.variant.clear();
1137 }
1138 }
1139
1140 impl<CVar: ::columnar::Len> ::columnar::Len for #c_ident <CVar> {
1141 #[inline(always)]
1142 fn len(&self) -> usize {
1143 self.variant.len()
1144 }
1145 }
1146
1147 impl<'a, CVar: ::columnar::AsBytes<'a>> ::columnar::AsBytes<'a> for #c_ident <CVar> {
1148 #[inline(always)]
1150 fn as_bytes(&self) -> impl Iterator<Item=(u64, &'a [u8])> {
1151 self.variant.as_bytes()
1152 }
1153 }
1154
1155 impl<'columnar, CVar: ::columnar::FromBytes<'columnar>> ::columnar::FromBytes<'columnar> for #c_ident <CVar> {
1156 #[inline(always)]
1157 fn from_bytes(bytes: &mut impl Iterator<Item=&'columnar [u8]>) -> Self {
1158 Self { variant: ::columnar::FromBytes::from_bytes(bytes) }
1159 }
1160 }
1161
1162 impl ::columnar::Columnar for #name {
1163 #[inline(always)]
1164 fn copy_from<'a>(&mut self, other: ::columnar::Ref<'a, Self>) { *self = other; }
1165 #[inline(always)]
1166 fn into_owned<'a>(other: ::columnar::Ref<'a, Self>) -> Self { other }
1167 type Container = #c_ident;
1168 }
1169
1170 impl<CV: ::columnar::common::BorrowIndexAs<u8>> ::columnar::Borrow for #c_ident <CV> {
1171 type Ref<'a> = #name;
1172 type Borrowed<'a> = #c_ident < CV::Borrowed<'a> > where CV: 'a;
1173 #[inline(always)]
1174 fn borrow<'a>(&'a self) -> Self::Borrowed<'a> {
1175 #c_ident {
1176 variant: self.variant.borrow()
1177 }
1178 }
1179 #[inline(always)]
1180 fn reborrow<'b, 'a: 'b>(thing: Self::Borrowed<'a>) -> Self::Borrowed<'b> {
1181 #c_ident {
1182 variant: <CV as ::columnar::Borrow>::reborrow(thing.variant),
1183 }
1184 }
1185 #[inline(always)]
1186 fn reborrow_ref<'b, 'a: 'b>(thing: Self::Ref<'a>) -> Self::Ref<'b> { thing }
1187 }
1188
1189 impl<CV: ::columnar::common::PushIndexAs<u8>> ::columnar::Container for #c_ident <CV> {
1190 fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
1193 self.variant.reserve_for(selves.map(|x| x.variant));
1194 }
1195 }
1196 }.into()
1197}