Skip to main content

columnar_derive/
lib.rs

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    // Generic type parameters for the containers for the struct fields.
65    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    // The container struct is a tuple of containers, named to correspond with fields.
71    #[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            /// Derived columnar container for a struct.
79            #derive
80            #vis struct #c_ident < #(#container_types),* >{
81                #(
82                    /// Container for #names.
83                    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            /// Derived columnar reference for a struct.
106            #[derive(Copy, Clone, Debug)]
107            #attr
108            #vis struct #r_ident #ty_gen {
109                #(
110                    /// Field for #names.
111                    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        // Either use curly braces or parentheses to destructure the item.
132        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        // Either use curly braces or parentheses to destructure the item.
158        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    // Implementation of `Push<#r_ident>`
198    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                // type Borrowed<'columnar> = #c_ident < #(<#container_types as ::columnar::AsBytes>::Borrowed<'columnar>,)*>;
302                #[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                const SLICE_COUNT: usize = 0 #(+ <#container_types>::SLICE_COUNT)*;
321                #[inline(always)]
322                fn from_bytes(bytes: &mut impl Iterator<Item=&'columnar [u8]>) -> Self {
323                    Self { #(#names: ::columnar::FromBytes::from_bytes(bytes),)* }
324                }
325                #[inline(always)]
326                fn from_store(store: &::columnar::bytes::indexed::DecodedStore<'columnar>, offset: &mut usize) -> Self {
327                    Self { #(#names: ::columnar::FromBytes::from_store(store, offset),)* }
328                }
329                fn element_sizes(sizes: &mut Vec<usize>) -> ::core::result::Result<(), String> {
330                    #(<#container_types>::element_sizes(sizes)?;)*
331                    Ok(())
332                }
333            }
334        }
335    };
336
337    let columnar_impl = {
338
339        let (impl_gen, ty_gen, where_clause) = generics.split_for_impl();
340
341        let where_clause2 = if let Some(struct_where) = where_clause {
342            let params = struct_where.predicates.iter();
343            quote! {  where #(#types : ::columnar::Columnar,)* #(#params),* }
344        }
345        else {
346            quote! { where #(#types : ::columnar::Columnar,)* }
347        };
348
349        // Either use curly braces or parentheses to destructure the item.
350        let destructure_self =
351        if named { quote! { let #name { #(#names),* } = self; } }
352        else     { quote! { let #name ( #(#names),* ) = self; } };
353
354        // Either use curly braces or parentheses to destructure the item.
355        let into_self =
356        if named { quote! { #name { #(#names: ::columnar::Columnar::into_owned(other.#names)),* } } }
357        else     { quote! { #name ( #(::columnar::Columnar::into_owned(other.#names)),* ) } };
358
359        quote! {
360            impl #impl_gen ::columnar::Columnar for #name #ty_gen #where_clause2 {
361                #[inline(always)]
362                fn copy_from<'a>(&mut self, other: ::columnar::Ref<'a, Self>) {
363                    #destructure_self
364                    #( ::columnar::Columnar::copy_from(#names, other.#names); )*
365                }
366                #[inline(always)]
367                fn into_owned<'a>(other: ::columnar::Ref<'a, Self>) -> Self {
368                    #into_self
369                }
370                type Container = #c_ident < #(<#types as ::columnar::Columnar>::Container ),* >;
371            }
372
373            impl < #( #container_types: ::columnar::Borrow ),* > ::columnar::Borrow for #c_ident < #( #container_types ),* > {
374                type Ref<'a> = #r_ident < #(<#container_types as ::columnar::Borrow>::Ref<'a>,)* > where #(#container_types: 'a,)*;
375                type Borrowed<'a> = #c_ident < #(<#container_types as ::columnar::Borrow>::Borrowed<'a> ),* > where #(#container_types: 'a,)*;
376                #[inline(always)]
377                fn borrow<'a>(&'a self) -> Self::Borrowed<'a> {
378                    #c_ident {
379                        #( #names: <#container_types as ::columnar::Borrow>::borrow(&self.#names), )*
380                    }
381                }
382                #[inline(always)]
383                fn reborrow<'b, 'a: 'b>(thing: Self::Borrowed<'a>) -> Self::Borrowed<'b> {
384                    #c_ident {
385                        #( #names: <#container_types as ::columnar::Borrow>::reborrow(thing.#names), )*
386                    }
387                }
388                #[inline(always)]
389                fn reborrow_ref<'b, 'a: 'b>(thing: Self::Ref<'a>) -> Self::Ref<'b> {
390                    #r_ident {
391                        #( #names: <#container_types as ::columnar::Borrow>::reborrow_ref(thing.#names), )*
392                    }
393                }
394            }
395
396            impl < #( #container_types: ::columnar::Container ),* > ::columnar::Container for #c_ident < #( #container_types ),* > {
397                #[inline(always)]
398                fn extend_from_self(&mut self, other: Self::Borrowed<'_>, range: std::ops::Range<usize>) {
399                    #( self.#names.extend_from_self(other.#names, range.clone()); )*
400                }
401
402                fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
403                    #( self.#names.reserve_for(selves.clone().map(|x| x.#names)); )*
404                }
405            }
406        }
407    };
408
409
410    quote! {
411
412        #container_struct
413        #reference_struct
414
415        #partial_eq
416
417        #push_own
418        #push_ref
419        #push_new
420
421        #index_own
422        #index_ref
423        #length
424        #clear
425
426        #as_bytes
427        #from_bytes
428
429        #columnar_impl
430
431    }.into()
432}
433
434// TODO: Do we need to use the generics?
435fn derive_unit_struct(name: &syn::Ident, _generics: &syn::Generics, vis: syn::Visibility, attr: Option<proc_macro2::TokenStream>) -> proc_macro::TokenStream {
436
437    let c_name = format!("{}Container", name);
438    let c_ident = syn::Ident::new(&c_name, name.span());
439
440    if attr.is_some() {
441        panic!("Unit structs do not support attributes");
442    }
443
444    #[cfg(feature = "serde")]
445    let derive = quote! { #[derive(Copy, Clone, Debug, Default, serde::Serialize, serde::Deserialize)] };
446    #[cfg(not(feature = "serde"))]
447    let derive = quote! { #[derive(Copy, Clone, Debug, Default)] };
448
449    quote! {
450
451        /// Derived columnar container for a unit struct.
452        #derive
453        #vis struct #c_ident<CW = u64> {
454            /// Count of the number of contained records.
455            pub count: CW,
456        }
457
458        impl ::columnar::Push<#name> for #c_ident {
459            #[inline]
460            fn push(&mut self, _item: #name) {
461                self.count += 1;
462            }
463        }
464
465        impl<'columnar> ::columnar::Push<&'columnar #name> for #c_ident {
466            #[inline]
467            fn push(&mut self, _item: &'columnar #name) {
468                self.count += 1;
469            }
470        }
471
472        impl<CW> ::columnar::Index for #c_ident<CW> {
473            type Ref = #name;
474            #[inline(always)]
475            fn get(&self, index: usize) -> Self::Ref {
476                #name
477            }
478        }
479
480        impl<'columnar, CW> ::columnar::Index for &'columnar #c_ident<CW> {
481            type Ref = #name;
482            #[inline(always)]
483            fn get(&self, index: usize) -> Self::Ref {
484                #name
485            }
486        }
487
488        impl ::columnar::Clear for #c_ident {
489            #[inline(always)]
490            fn clear(&mut self) {
491                self.count = 0;
492            }
493        }
494
495        impl<CW: Copy+::columnar::common::index::CopyAs<u64>> ::columnar::Len for #c_ident<CW> {
496            #[inline(always)]
497            fn len(&self) -> usize {
498                use ::columnar::common::index::CopyAs;
499                self.count.copy_as() as usize
500            }
501        }
502
503        impl<'a> ::columnar::AsBytes<'a> for #c_ident <&'a u64> {
504            // type Borrowed<'columnar> = #c_ident;
505            #[inline(always)]
506            fn as_bytes(&self) -> impl Iterator<Item=(u64, &'a [u8])> {
507                ::core::iter::once((8, ::columnar::bytemuck::cast_slice(::core::slice::from_ref(self.count))))
508            }
509        }
510
511        impl<'columnar> ::columnar::FromBytes<'columnar> for #c_ident <&'columnar u64> {
512            const SLICE_COUNT: usize = 1;
513            #[inline(always)]
514            fn from_bytes(bytes: &mut impl Iterator<Item=&'columnar [u8]>) -> Self {
515                Self { count: &::columnar::bytemuck::try_cast_slice(bytes.next().unwrap()).unwrap()[0] }
516            }
517            #[inline(always)]
518            fn from_store(store: &::columnar::bytes::indexed::DecodedStore<'columnar>, offset: &mut usize) -> Self {
519                let (w, _tail) = store.get(*offset);
520                *offset += 1;
521                Self { count: w.first().unwrap_or(&0) }
522            }
523            fn element_sizes(sizes: &mut Vec<usize>) -> ::core::result::Result<(), String> {
524                sizes.push(8);
525                Ok(())
526            }
527        }
528
529        impl ::columnar::Columnar for #name {
530            #[inline(always)]
531            fn copy_from<'a>(&mut self, other: ::columnar::Ref<'a, Self>) { *self = other; }
532            #[inline(always)]
533            fn into_owned<'a>(other: ::columnar::Ref<'a, Self>) -> Self { other }
534            type Container = #c_ident;
535        }
536
537        impl ::columnar::Borrow for #c_ident {
538            type Ref<'a> = #name;
539            type Borrowed<'a> = #c_ident < &'a u64 >;
540            #[inline(always)]
541            fn borrow<'a>(&'a self) -> Self::Borrowed<'a> {
542                #c_ident { count: &self.count }
543            }
544            #[inline(always)]
545            fn reborrow<'b, 'a: 'b>(thing: Self::Borrowed<'a>) -> Self::Borrowed<'b> {
546                #c_ident { count: thing.count }
547            }
548            #[inline(always)]
549            fn reborrow_ref<'b, 'a: 'b>(thing: Self::Ref<'a>) -> Self::Ref<'b> { thing }
550        }
551
552        impl ::columnar::Container for #c_ident {
553            #[inline(always)]
554            fn extend_from_self(&mut self, _other: Self::Borrowed<'_>, range: std::ops::Range<usize>) {
555                self.count += range.len() as u64;
556            }
557
558            fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone { }
559        }
560
561    }.into()
562}
563
564/// The derived container for an `enum` type will be a struct with containers for each field of each variant, plus an offset container and a discriminant container.
565/// Its index `Ref` type will be an enum with parallel variants, each containing the index `Ref` types of the corresponding variant containers.
566#[allow(unused)]
567fn derive_enum(name: &syn::Ident, generics: &syn:: Generics, data_enum: syn::DataEnum, vis: syn::Visibility, attr: Option<proc_macro2::TokenStream>) -> proc_macro::TokenStream {
568
569    if data_enum.variants.iter().all(|variant| variant.fields.is_empty()) {
570        return derive_tags(name, generics, data_enum, vis);
571    }
572
573    let c_name = format!("{}Container", name);
574    let c_ident = syn::Ident::new(&c_name, name.span());
575
576    let r_name = format!("{}Reference", name);
577    let r_ident = syn::Ident::new(&r_name, name.span());
578
579    // Record everything we know about the variants.
580    let variants: Vec<(&syn::Ident, Vec<_>)> =
581    data_enum
582        .variants
583        .iter()
584        .map(|variant| (
585            &variant.ident,
586            variant.fields.iter().map(|field| &field.ty).collect()
587        ))
588        .collect();
589
590    // Bit silly, but to help us fit in a byte and reign in bloat.
591    assert!(variants.len() <= 256, "Too many variants for enum");
592
593    let names = &variants.iter().map(|(ident, _)| ident).collect::<Vec<_>>();
594
595    // Generic type parameters for the containers for the struct fields.
596    let container_types = &names.iter().enumerate().map(|(index, name)| {
597        let new_name = format!("C{}", index);
598        syn::Ident::new(&new_name, name.span())
599    }).collect::<Vec<_>>();
600
601    #[cfg(feature = "serde")]
602    let derive = quote! { #[derive(Copy, Clone, Debug, Default, serde::Serialize, serde::Deserialize)] };
603    #[cfg(not(feature = "serde"))]
604    let derive = quote! { #[derive(Copy, Clone, Debug, Default)] };
605
606    let container_struct = {
607        quote! {
608            /// Derived columnar container for an enum.
609            #derive
610            #[allow(non_snake_case)]
611            #vis struct #c_ident < #(#container_types,)* CVar = Vec<u8>, COff = Vec<u64>, >{
612                #(
613                    /// Container for #names.
614                    pub #names : #container_types,
615                )*
616                /// Discriminant tracking for variants.
617                pub indexes: ::columnar::Discriminant<CVar, COff>,
618            }
619        }
620    };
621
622    let reference_struct = {
623
624        let reference_types = &names.iter().enumerate().map(|(index, name)| {
625            let new_name = format!("R{}", index);
626            syn::Ident::new(&new_name, name.span())
627        }).collect::<Vec<_>>();
628
629        let ty_gen = quote! { < #(#reference_types),* > };
630
631        let attr = if let Some(attr) = attr {
632            quote! { #[#attr] }
633        } else {
634            quote! {}
635        };
636
637
638        quote! {
639            /// Reference for an enum.
640            #[derive(Copy, Clone, Debug)]
641            #attr
642            #vis enum #r_ident #ty_gen {
643                #(
644                    /// Enum variant for #names.
645                    #names(#reference_types),
646                )*
647            }
648        }
649    };
650
651    let push_own = {
652
653        let (_impl_gen, ty_gen, _where_clause) = generics.split_for_impl();
654
655        let push = variants.iter().enumerate().map(|(index, (variant, types))| {
656
657            match &data_enum.variants[index].fields {
658                syn::Fields::Unit => {
659                    quote! {
660                        #name::#variant => {
661                            self.indexes.push(#index as u8, self.#variant.len() as u64);
662                            self.#variant.push(());
663                        }
664                    }
665                }
666                syn::Fields::Unnamed(_) => {
667                    let temp_names = &types.iter().enumerate().map(|(index, _)| {
668                        let new_name = format!("t{}", index);
669                        syn::Ident::new(&new_name, variant.span())
670                    }).collect::<Vec<_>>();
671
672                    quote! {
673                        #name::#variant( #(#temp_names),* ) => {
674                            self.indexes.push(#index as u8, self.#variant.len() as u64);
675                            self.#variant.push((#(#temp_names),*));
676                        },
677                    }
678                }
679                syn::Fields::Named(fields) => {
680                    let field_names = &fields.named.iter().map(|f| f.ident.as_ref().unwrap()).collect::<Vec<_>>();
681
682                    quote! {
683                        #name::#variant { #(#field_names),* } => {
684                            self.indexes.push(#index as u8, self.#variant.len() as u64);
685                            self.#variant.push((#(#field_names),*));
686                        },
687                    }
688                }
689            }
690        });
691
692        let struct_generics = generics.params.iter();
693        let impl_gen = quote! { < #(#struct_generics,)* #(#container_types),* > };
694
695        let push_types = variants.iter().map(|(_, types)| quote! { (#(#types),*) });
696
697        let where_clause = quote! { where #(#container_types: ::columnar::Len + ::columnar::Push<#push_types>),* };
698
699        quote! {
700            impl #impl_gen ::columnar::Push<#name #ty_gen> for #c_ident < #(#container_types),* > #where_clause {
701                #[inline]
702                fn push(&mut self, item: #name #ty_gen) {
703                    match item {
704                        #( #push )*
705                    }
706                }
707            }
708        }
709    };
710
711    let push_ref = {
712
713        let (_impl_gen, ty_gen, _where_clause) = generics.split_for_impl();
714
715        let push = variants.iter().enumerate().map(|(index, (variant, types))| {
716
717            match &data_enum.variants[index].fields {
718                syn::Fields::Unit => {
719                    quote! {
720                        #name::#variant => {
721                            self.indexes.push(#index as u8, self.#variant.len() as u64);
722                            self.#variant.push(());
723                        }
724                    }
725                }
726                syn::Fields::Unnamed(_) => {
727                    let temp_names = &types.iter().enumerate().map(|(index, _)| {
728                        let new_name = format!("t{}", index);
729                        syn::Ident::new(&new_name, variant.span())
730                    }).collect::<Vec<_>>();
731
732                    quote! {
733                        #name::#variant( #(#temp_names),* ) => {
734                            self.indexes.push(#index as u8, self.#variant.len() as u64);
735                            self.#variant.push((#(#temp_names),*));
736                        },
737                    }
738                }
739                syn::Fields::Named(fields) => {
740                    let field_names = &fields.named.iter().map(|f| f.ident.as_ref().unwrap()).collect::<Vec<_>>();
741
742                    quote! {
743                        #name::#variant { #(#field_names),* } => {
744                            self.indexes.push(#index as u8, self.#variant.len() as u64);
745                            self.#variant.push((#(#field_names),*));
746                        },
747                    }
748                }
749            }
750        });
751
752        let struct_generics = generics.params.iter();
753        let impl_gen = quote! { < 'columnar, #(#struct_generics,)* #(#container_types),* > };
754
755        let push_types = variants.iter().map(|(_, types)| quote! { (#(&'columnar #types),*) });
756
757        let where_clause = quote! { where #(#container_types: ::columnar::Len + ::columnar::Push<#push_types>),* };
758
759        quote! {
760            impl #impl_gen ::columnar::Push<&'columnar #name #ty_gen> for #c_ident < #(#container_types),* > #where_clause {
761                #[inline]
762                fn push(&mut self, item: &'columnar #name #ty_gen) {
763                    match item {
764                        #( #push )*
765                    }
766                }
767            }
768        }
769    };
770
771    // Implementation of `Push<#r_ident>`
772    let push_new = {
773
774        let reference_types = &names.iter().enumerate().map(|(index, name)| {
775            let new_name = format!("R{}", index);
776            syn::Ident::new(&new_name, name.span())
777        }).collect::<Vec<_>>();
778
779        let impl_gen = quote! { < #(#container_types,)* #(#reference_types),* > };
780
781        let where_clause = quote! { where #(#container_types: ::columnar::Len + ::columnar::Push<#reference_types>),* };
782
783        let index_type = quote! { #r_ident < #(#reference_types,)* > };
784        let numbers = (0 .. variants.len());
785
786        quote! {
787            impl #impl_gen ::columnar::Push<#index_type> for #c_ident < #(#container_types),* > #where_clause {
788                #[inline]
789                fn push(&mut self, item: #index_type) {
790                    match item {
791                        #(
792                            #r_ident::#names(x) => {
793                                self.indexes.push(#numbers as u8, self.#names.len() as u64);
794                                self.#names.push(x);
795                            },
796                        )*
797                    }
798                }
799            }
800        }
801    };
802
803    let index_own = {
804        let impl_gen = quote! { < #(#container_types,)* CVar, COff> };
805        let ty_gen = quote! { < #(#container_types,)* CVar, COff> };
806        let where_clause = quote! { where #(#container_types: ::columnar::Index,)* CVar: ::columnar::Len + ::columnar::IndexAs<u8>, COff: ::columnar::Len + ::columnar::IndexAs<u64>  };
807
808        let index_type = quote! { #r_ident < #(<#container_types as ::columnar::Index>::Ref,)* > };
809
810        // These numbers must match those in the `Push` implementations.
811        let numbers = (0 .. variants.len());
812
813        quote! {
814            impl #impl_gen ::columnar::Index for #c_ident #ty_gen #where_clause {
815                type Ref = #index_type;
816                #[inline(always)]
817                fn get(&self, index: usize) -> Self::Ref {
818                    let (variant, offset) = self.indexes.get(index);
819                    match variant as usize {
820                        #( #numbers => #r_ident::#names(self.#names.get(offset as usize)), )*
821                        x => panic!("Unacceptable discriminant found: {:?}", x),
822                    }
823                }
824            }
825        }
826    };
827
828    let index_ref = {
829        let impl_gen = quote! { < 'columnar, #(#container_types,)* CVar, COff> };
830        let ty_gen = quote! { < #(#container_types,)* CVar, COff> };
831        let where_clause = quote! { where #(&'columnar #container_types: ::columnar::Index,)* CVar: ::columnar::Len + ::columnar::IndexAs<u8>, COff: ::columnar::Len + ::columnar::IndexAs<u64>  };
832
833        let index_type = quote! { #r_ident < #(<&'columnar #container_types as ::columnar::Index>::Ref,)* > };
834
835        // These numbers must match those in the `Push` implementations.
836        let numbers = (0 .. variants.len());
837
838        quote! {
839            impl #impl_gen ::columnar::Index for &'columnar #c_ident #ty_gen #where_clause {
840                type Ref = #index_type;
841                #[inline(always)]
842                fn get(&self, index: usize) -> Self::Ref {
843                    let (variant, offset) = self.indexes.get(index);
844                    match variant as usize {
845                        #( #numbers => #r_ident::#names((&self.#names).get(offset as usize)), )*
846                        x => panic!("Unacceptable discriminant found: {:?}", x),
847                    }
848                }
849            }
850        }
851    };
852
853    let clear = {
854
855        let impl_gen = quote! { < #(#container_types),* > };
856        let ty_gen = quote! { < #(#container_types),* > };
857        let where_clause = quote! { where #(#container_types: ::columnar::Clear),* };
858
859        quote! {
860            impl #impl_gen ::columnar::Clear for #c_ident #ty_gen #where_clause {
861                #[inline(always)]
862                fn clear(&mut self) {
863                    #(self.#names.clear();)*
864                    self.indexes.clear();
865                }
866            }
867        }
868    };
869
870    let length = {
871
872        let impl_gen = quote! { < #(#container_types,)* CVar, COff> };
873        let ty_gen = quote! { < #(#container_types,)* CVar, COff > };
874
875        quote! {
876            impl #impl_gen ::columnar::Len for #c_ident #ty_gen where CVar: ::columnar::Len, COff: ::columnar::Len + ::columnar::IndexAs<u64> {
877                #[inline(always)]
878                fn len(&self) -> usize {
879                    self.indexes.len()
880                }
881            }
882        }
883    };
884
885    let as_bytes = {
886
887        let impl_gen = quote! { < 'a, #(#container_types,)* CVar, COff> };
888        let ty_gen = quote! { < #(#container_types,)* CVar, COff > };
889        let where_clause = quote! { where #(#container_types: ::columnar::AsBytes<'a>,)* ::columnar::Discriminant<CVar, COff>: ::columnar::AsBytes<'a> };
890
891        quote! {
892            impl #impl_gen ::columnar::AsBytes<'a> for #c_ident #ty_gen #where_clause {
893                #[inline(always)]
894                fn as_bytes(&self) -> impl Iterator<Item=(u64, &'a [u8])> {
895                    let iter = None.into_iter();
896                    #( let iter = ::columnar::chain(iter,self.#names.as_bytes()); )*
897                    let iter = ::columnar::chain(iter, self.indexes.as_bytes());
898                    iter
899                }
900            }
901        }
902    };
903
904    let from_bytes = {
905
906        let impl_gen = quote! { < 'columnar, #(#container_types,)* CVar, COff> };
907        let ty_gen = quote! { < #(#container_types,)* CVar, COff > };
908        let where_clause = quote! { where #(#container_types: ::columnar::FromBytes<'columnar>,)* ::columnar::Discriminant<CVar, COff>: ::columnar::FromBytes<'columnar> };
909
910        quote! {
911            #[allow(non_snake_case)]
912            impl #impl_gen ::columnar::FromBytes<'columnar> for #c_ident #ty_gen #where_clause {
913                const SLICE_COUNT: usize = 0 #(+ <#container_types>::SLICE_COUNT)* + <::columnar::Discriminant<CVar, COff>>::SLICE_COUNT;
914                #[inline(always)]
915                fn from_bytes(bytes: &mut impl Iterator<Item=&'columnar [u8]>) -> Self {
916                    Self {
917                        #(#names: ::columnar::FromBytes::from_bytes(bytes),)*
918                        indexes: ::columnar::FromBytes::from_bytes(bytes),
919                    }
920                }
921                #[inline(always)]
922                fn from_store(store: &::columnar::bytes::indexed::DecodedStore<'columnar>, offset: &mut usize) -> Self {
923                    Self {
924                        #(#names: ::columnar::FromBytes::from_store(store, offset),)*
925                        indexes: ::columnar::FromBytes::from_store(store, offset),
926                    }
927                }
928                fn element_sizes(sizes: &mut Vec<usize>) -> ::core::result::Result<(), String> {
929                    #(<#container_types>::element_sizes(sizes)?;)*
930                    <::columnar::Discriminant<CVar, COff>>::element_sizes(sizes)?;
931                    Ok(())
932                }
933            }
934        }
935    };
936
937    let columnar_impl = {
938
939        let (impl_gen, ty_gen, where_clause) = generics.split_for_impl();
940
941        let types = &variants.iter().flat_map(|(_, types)| types).collect::<Vec<_>>();
942
943        let where_clause2 = if let Some(enum_where) = where_clause {
944            let params = enum_where.predicates.iter();
945            quote! {  where #(#types : ::columnar::Columnar,)* #(#params),* }
946        }
947        else {
948            quote! { where #(#types : ::columnar::Columnar,)* }
949        };
950
951
952        let variant_types = &variants.iter().map(|(_, types)| quote! { (#(#types),*) }).collect::<Vec<_>>();
953
954        let container_types = &variants.iter().map(|(_, types)| quote! { <(#(#types),*) as ::columnar::Columnar>::Container }).collect::<Vec<_>>();
955        // Generic type parameters for the containers for the struct fields.
956        let container_names = &names.iter().enumerate().map(|(index, name)| {
957            let new_name = format!("C{}", index);
958            syn::Ident::new(&new_name, name.span())
959        }).collect::<Vec<_>>();
960
961        let reference_args = variants.iter().map(|(_, types)| quote! { <(#(#types),*) as ::columnar::Columnar>::Ref<'a> });
962        let reference_args2 = reference_args.clone();
963
964        // For each variant of `other`, the matching and non-matching variant cases.
965        let copy_from = variants.iter().enumerate().map(|(index, (variant, types))| {
966
967            if data_enum.variants[index].fields == syn::Fields::Unit {
968                quote! {
969                    (#name::#variant, #r_ident::#variant(_)) => { }
970                    (_, #r_ident::#variant(_)) => { *self = #name::#variant; }
971                }
972            }
973            else {
974                let temp_names1 = &types.iter().enumerate().map(|(index, _)| {
975                    let new_name = format!("s{}", index);
976                    syn::Ident::new(&new_name, variant.span())
977                }).collect::<Vec<_>>();
978                let temp_names2 = &types.iter().enumerate().map(|(index, _)| {
979                    let new_name = format!("t{}", index);
980                    syn::Ident::new(&new_name, variant.span())
981                }).collect::<Vec<_>>();
982
983                let destructure = match &data_enum.variants[index].fields {
984                    syn::Fields::Named(fields) => {
985                        let field_names: Vec<_> = fields.named.iter().map(|f| f.ident.as_ref().unwrap()).collect();
986                        quote! { #name::#variant { #(#field_names: #temp_names1),* } }
987                    }
988                    _ => quote! { #name::#variant( #(#temp_names1),* ) }
989                };
990
991                quote! {
992                    (#destructure, #r_ident::#variant( ( #( #temp_names2 ),* ) )) => {
993                        #( ::columnar::Columnar::copy_from(#temp_names1, #temp_names2); )*
994                    }
995                }
996            }
997        }).collect::<Vec<_>>();
998
999        // For each variant of `other`, the matching and non-matching variant cases.
1000        let into_owned = variants.iter().enumerate().map(|(index, (variant, types))| {
1001
1002            if data_enum.variants[index].fields == syn::Fields::Unit {
1003                quote! { #r_ident::#variant(_) => #name::#variant, }
1004            }
1005            else {
1006                let temp_names = &types.iter().enumerate().map(|(index, _)| {
1007                    let new_name = format!("t{}", index);
1008                    syn::Ident::new(&new_name, variant.span())
1009                }).collect::<Vec<_>>();
1010
1011                let reconstruct = match &data_enum.variants[index].fields {
1012                    syn::Fields::Named(fields) => {
1013                        let field_names: Vec<_> = fields.named.iter().map(|f| f.ident.as_ref().unwrap()).collect();
1014                        quote! { #name::#variant { #(#field_names: ::columnar::Columnar::into_owned(#temp_names)),* } }
1015                    }
1016                    _ => quote! { #name::#variant( #( ::columnar::Columnar::into_owned(#temp_names) ),* ) }
1017                };
1018
1019                quote! {
1020                    #r_ident::#variant(( #( #temp_names ),* )) => {
1021                        #reconstruct
1022                    },
1023                }
1024            }
1025        }).collect::<Vec<_>>();
1026
1027        // For each variant, the reborrow case.
1028        let reborrow_ref = variants.iter().enumerate().zip(container_names.iter()).map(|((index, (variant, types)), cname)| {
1029            quote! {
1030                #r_ident::#variant(( potato )) => {
1031                    #r_ident::#variant((  < (#cname) as ::columnar::Borrow >::reborrow_ref::<'b, 'a>( potato ) ))
1032                },
1033            }
1034        }).collect::<Vec<_>>();
1035
1036        // Helper identifiers for `extend_from_self` local variables.
1037        let len_idents = &names.iter().map(|n| syn::Ident::new(&format!("len_{}", n.to_string().to_lowercase()), n.span())).collect::<Vec<_>>();
1038        let count_idents = &names.iter().map(|n| syn::Ident::new(&format!("count_{}", n.to_string().to_lowercase()), n.span())).collect::<Vec<_>>();
1039        let start_idents = &names.iter().map(|n| syn::Ident::new(&format!("start_{}", n.to_string().to_lowercase()), n.span())).collect::<Vec<_>>();
1040        let variant_indices = &(0..variants.len()).map(|i| i as u8).collect::<Vec<_>>();
1041
1042        quote! {
1043            impl #impl_gen ::columnar::Columnar for #name #ty_gen #where_clause2 {
1044                #[inline(always)]
1045                fn copy_from<'a>(&mut self, other: ::columnar::Ref<'a, Self>) {
1046                    match (&mut *self, other) {
1047                        #( #copy_from )*
1048                        (_, other) => { *self = Self::into_owned(other); }
1049                    }
1050                }
1051                #[inline(always)]
1052                fn into_owned<'a>(other: ::columnar::Ref<'a, Self>) -> Self {
1053                    match other {
1054                        #( #into_owned )*
1055                    }
1056                }
1057                type Container = #c_ident < #(#container_types),* >;
1058            }
1059
1060            impl < #(#container_names : ::columnar::Borrow ),* > ::columnar::Borrow for #c_ident < #(#container_names),* > {
1061                type Ref<'a> = #r_ident < #( <#container_names as ::columnar::Borrow>::Ref<'a> ,)* > where Self: 'a, #(#container_names: 'a,)*;
1062                type Borrowed<'a> = #c_ident < #( < #container_names as ::columnar::Borrow >::Borrowed<'a>, )* &'a [u8], &'a [u64] > where #(#container_names: 'a,)*;
1063                #[inline(always)]
1064                fn borrow<'a>(&'a self) -> Self::Borrowed<'a> {
1065                    #c_ident {
1066                        #(#names: self.#names.borrow(),)*
1067                        indexes: self.indexes.borrow(),
1068                    }
1069                }
1070                #[inline(always)]
1071                fn reborrow<'b, 'a: 'b>(thing: Self::Borrowed<'a>) -> Self::Borrowed<'b> {
1072                    #c_ident {
1073                        #(#names: <#container_names as ::columnar::Borrow>::reborrow(thing.#names),)*
1074                        indexes: <::columnar::Discriminant as ::columnar::Borrow>::reborrow(thing.indexes),
1075                    }
1076                }
1077                #[inline(always)]
1078                fn reborrow_ref<'b, 'a: 'b>(thing: Self::Ref<'a>) -> Self::Ref<'b> {
1079                    match thing {
1080                        #( #reborrow_ref )*
1081                    }
1082                }
1083            }
1084
1085            impl < #(#container_names : ::columnar::Container + ::columnar::Len),* > ::columnar::Container for #c_ident < #(#container_names),* > {
1086                #[inline(always)]
1087                fn extend_from_self(&mut self, other: Self::Borrowed<'_>, range: std::ops::Range<usize>) {
1088                    if !range.is_empty() {
1089                        #( let #len_idents = ::columnar::Len::len(&self.#names); )*
1090                        #( let mut #count_idents = 0usize; )*
1091                        #( let mut #start_idents = 0u64; )*
1092                        for index in range.clone() {
1093                            let (variant, offset) = other.indexes.get(index);
1094                            match variant {
1095                                #(
1096                                    #variant_indices => {
1097                                        if #count_idents == 0 { #start_idents = offset; }
1098                                        self.indexes.push(#variant_indices, (#len_idents + #count_idents) as u64);
1099                                        #count_idents += 1;
1100                                    }
1101                                )*
1102                                _ => unreachable!(),
1103                            }
1104                        }
1105                        #(
1106                            if #count_idents > 0 {
1107                                self.#names.extend_from_self(other.#names, #start_idents as usize .. #start_idents as usize + #count_idents);
1108                            }
1109                        )*
1110                    }
1111                }
1112
1113                fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
1114                    #( self.#names.reserve_for(selves.clone().map(|x| x.#names)); )*
1115                    self.indexes.reserve_for(selves.map(|x| x.indexes));
1116                }
1117            }
1118        }
1119    };
1120
1121    let try_unwrap = {
1122        let impl_gen = quote! { < #(#container_types),* > };
1123        let ty_gen = quote! { < #(#container_types),* > };
1124
1125        let numbers = (0u8 ..);
1126        let methods = names.iter().zip(container_types.iter()).zip(numbers).map(|((name, ctype), index)| {
1127            let try_name = syn::Ident::new(&format!("try_unwrap_{}", name), name.span());
1128            quote! {
1129                /// Returns the #name container if all elements are #name.
1130                #[inline]
1131                pub fn #try_name(&self) -> Option<&#ctype> {
1132                    if self.indexes.homogeneous() == Some(#index) { Some(&self.#name) } else { None }
1133                }
1134            }
1135        });
1136
1137        quote! {
1138            #[allow(non_snake_case)]
1139            impl #impl_gen #c_ident #ty_gen {
1140                #( #methods )*
1141            }
1142        }
1143    };
1144
1145    quote! {
1146
1147        #container_struct
1148        #reference_struct
1149
1150        #push_own
1151        #push_ref
1152        #push_new
1153
1154        #index_own
1155        #index_ref
1156        #length
1157        #clear
1158
1159        #as_bytes
1160        #from_bytes
1161
1162        #columnar_impl
1163
1164        #try_unwrap
1165
1166    }.into()
1167}
1168
1169/// A derivation for an enum type with no fields in any of its variants.
1170#[allow(unused)]
1171fn derive_tags(name: &syn::Ident, _generics: &syn:: Generics, data_enum: syn::DataEnum, vis: syn::Visibility) -> proc_macro::TokenStream {
1172
1173    let c_name = format!("{}Container", name);
1174    let c_ident = syn::Ident::new(&c_name, name.span());
1175
1176    let names: Vec<&syn::Ident> =
1177    data_enum
1178        .variants
1179        .iter()
1180        .map(|variant| &variant.ident)
1181        .collect();
1182
1183    let indices: &Vec<u8> = &(0 .. names.len()).map(|x| x as u8).collect();
1184
1185    // Bit silly, but to help us fit in a byte and reign in bloat.
1186    assert!(names.len() <= 256, "Too many variants for enum");
1187
1188    #[cfg(feature = "serde")]
1189    let derive = quote! { #[derive(Copy, Clone, Debug, Default, serde::Serialize, serde::Deserialize)] };
1190    #[cfg(not(feature = "serde"))]
1191    let derive = quote! { #[derive(Copy, Clone, Debug, Default)] };
1192
1193    quote! {
1194        /// Derived columnar container for all-unit enum.
1195        #derive
1196        #vis struct #c_ident <CVar = Vec<u8>> {
1197            /// Container for variant.
1198            pub variant: CVar,
1199        }
1200
1201        impl<CV: ::columnar::common::PushIndexAs<u8>> ::columnar::Push<#name> for #c_ident<CV> {
1202            #[inline]
1203            fn push(&mut self, item: #name) {
1204                match item {
1205                    #( #name::#names => self.variant.push(&#indices), )*
1206                }
1207            }
1208        }
1209
1210        impl<'columnar> ::columnar::Push<&'columnar #name> for #c_ident {
1211            #[inline]
1212            fn push(&mut self, item: &'columnar #name) {
1213                match *item {
1214                    #( #name::#names => self.variant.push(#indices), )*
1215                }
1216            }
1217        }
1218
1219        impl<CVar: ::columnar::Len + ::columnar::IndexAs<u8>> ::columnar::Index for #c_ident <CVar> {
1220            type Ref = #name;
1221            #[inline(always)]
1222            fn get(&self, index: usize) -> Self::Ref {
1223                match self.variant.index_as(index) {
1224                    #( #indices => #name::#names, )*
1225                    x => panic!("Unacceptable discriminant found: {:?}", x),
1226                }
1227            }
1228        }
1229
1230        impl<'columnar, CVar: ::columnar::Len + ::columnar::IndexAs<u8>> ::columnar::Index for &'columnar #c_ident <CVar> {
1231            type Ref = #name;
1232            #[inline(always)]
1233            fn get(&self, index: usize) -> Self::Ref {
1234                match self.variant.index_as(index) {
1235                    #( #indices => #name::#names, )*
1236                    x => panic!("Unacceptable discriminant found: {:?}", x),
1237                }
1238            }
1239        }
1240
1241        impl<CVar: ::columnar::Clear> ::columnar::Clear for #c_ident <CVar> {
1242            #[inline(always)]
1243            fn clear(&mut self) {
1244                self.variant.clear();
1245            }
1246        }
1247
1248        impl<CVar: ::columnar::Len> ::columnar::Len for #c_ident <CVar> {
1249            #[inline(always)]
1250            fn len(&self) -> usize {
1251                self.variant.len()
1252            }
1253        }
1254
1255        impl<'a, CVar: ::columnar::AsBytes<'a>> ::columnar::AsBytes<'a> for #c_ident <CVar> {
1256            // type Borrowed<'columnar> = #c_ident < <CVar as ::columnar::AsBytes>::Borrowed<'columnar> >;
1257            #[inline(always)]
1258            fn as_bytes(&self) -> impl Iterator<Item=(u64, &'a [u8])> {
1259                self.variant.as_bytes()
1260            }
1261        }
1262
1263        impl<'columnar, CVar: ::columnar::FromBytes<'columnar>> ::columnar::FromBytes<'columnar> for #c_ident <CVar> {
1264            const SLICE_COUNT: usize = CVar::SLICE_COUNT;
1265            #[inline(always)]
1266            fn from_bytes(bytes: &mut impl Iterator<Item=&'columnar [u8]>) -> Self {
1267                Self { variant: ::columnar::FromBytes::from_bytes(bytes) }
1268            }
1269            #[inline(always)]
1270            fn from_store(store: &::columnar::bytes::indexed::DecodedStore<'columnar>, offset: &mut usize) -> Self {
1271                Self { variant: ::columnar::FromBytes::from_store(store, offset) }
1272            }
1273            fn element_sizes(sizes: &mut Vec<usize>) -> ::core::result::Result<(), String> {
1274                CVar::element_sizes(sizes)
1275            }
1276        }
1277
1278        impl ::columnar::Columnar for #name {
1279            #[inline(always)]
1280            fn copy_from<'a>(&mut self, other: ::columnar::Ref<'a, Self>) { *self = other; }
1281            #[inline(always)]
1282            fn into_owned<'a>(other: ::columnar::Ref<'a, Self>) -> Self { other }
1283            type Container = #c_ident;
1284        }
1285
1286        impl<CV: ::columnar::common::BorrowIndexAs<u8>> ::columnar::Borrow for #c_ident <CV> {
1287            type Ref<'a> = #name;
1288            type Borrowed<'a> = #c_ident < CV::Borrowed<'a> > where CV: 'a;
1289            #[inline(always)]
1290            fn borrow<'a>(&'a self) -> Self::Borrowed<'a> {
1291                #c_ident {
1292                    variant: self.variant.borrow()
1293                }
1294            }
1295            #[inline(always)]
1296            fn reborrow<'b, 'a: 'b>(thing: Self::Borrowed<'a>) -> Self::Borrowed<'b> {
1297                #c_ident {
1298                    variant: <CV as ::columnar::Borrow>::reborrow(thing.variant),
1299                }
1300            }
1301            #[inline(always)]
1302            fn reborrow_ref<'b, 'a: 'b>(thing: Self::Ref<'a>) -> Self::Ref<'b> { thing }
1303        }
1304
1305        impl<CV: ::columnar::common::PushIndexAs<u8>> ::columnar::Container for #c_ident <CV> {
1306            #[inline(always)]
1307            fn extend_from_self(&mut self, other: Self::Borrowed<'_>, range: std::ops::Range<usize>) {
1308                self.variant.extend_from_self(other.variant, range);
1309            }
1310
1311            fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
1312                self.variant.reserve_for(selves.map(|x| x.variant));
1313            }
1314        }
1315    }.into()
1316}