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