Skip to main content

miniextendr_macros/
dataframe_derive.rs

1//! Derive macros for bidirectional row ↔ dataframe conversions.
2//!
3//! Supports both structs (direct field mapping) and enums (field-name union
4//! across variants with `Option<T>` fill for missing fields).
5
6use proc_macro2::{Span, TokenStream};
7use quote::{format_ident, quote, quote_spanned};
8use syn::{Data, DeriveInput, Fields};
9
10// region: Attribute parsing
11
12/// Parsed container-level `#[dataframe(...)]` attributes.
13pub(super) struct DataFrameAttrs {
14    /// Custom companion type name (default: `{TypeName}DataFrame`).
15    pub(super) name: Option<syn::Ident>,
16    /// Enum alignment mode — implicit for enums, accepted but not required.
17    pub(super) align: bool,
18    /// Tag column name for variant discriminator (also supported on structs).
19    pub(super) tag: Option<String>,
20    /// Conflict resolution mode for type collisions across enum variants.
21    /// Currently only "string" is supported: convert conflicting fields via `ToString`.
22    pub(super) conflicts: Option<String>,
23}
24
25/// Parse container-level `#[dataframe(...)]` attributes from the derive input.
26///
27/// Supported keys:
28/// - `name = "CustomName"` -- custom companion type name (default: `{TypeName}DataFrame`)
29/// - `align` -- enum alignment mode (field-name union across variants)
30/// - `tag = "col_name"` -- add a variant discriminator column (works on both structs and enums)
31/// - `conflicts = "string"` -- coerce type-conflicting columns to `String` via `ToString`
32///
33/// Returns `Err` for unknown keys or non-string-literal values.
34fn parse_dataframe_attrs(input: &DeriveInput) -> syn::Result<DataFrameAttrs> {
35    let mut attrs = DataFrameAttrs {
36        name: None,
37        align: false,
38        tag: None,
39        conflicts: None,
40    };
41
42    for attr in &input.attrs {
43        if !attr.path().is_ident("dataframe") {
44            continue;
45        }
46
47        let nested = attr.parse_args_with(
48            syn::punctuated::Punctuated::<syn::Meta, ::syn::token::Commasyn::Token![,]>::parse_terminated,
49        )?;
50
51        for meta in &nested {
52            match meta {
53                syn::Meta::NameValue(nv) if nv.path.is_ident("name") => {
54                    if let syn::Expr::Lit(syn::ExprLit {
55                        lit: syn::Lit::Str(lit_str),
56                        ..
57                    }) = &nv.value
58                    {
59                        attrs.name =
60                            Some(match ::quote::__private::IdentFragmentAdapter(&lit_str.value()) {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("{0}", arg))
                    }),
            ::quote::__private::Option::Some::<::quote::__private::Span>(lit_str.span())),
}format_ident!("{}", lit_str.value(), span = lit_str.span()));
61                    } else {
62                        return Err(syn::Error::new_spanned(
63                            &nv.value,
64                            "expected string literal for `name`",
65                        ));
66                    }
67                }
68                syn::Meta::NameValue(nv) if nv.path.is_ident("tag") => {
69                    if let syn::Expr::Lit(syn::ExprLit {
70                        lit: syn::Lit::Str(lit_str),
71                        ..
72                    }) = &nv.value
73                    {
74                        attrs.tag = Some(lit_str.value());
75                    } else {
76                        return Err(syn::Error::new_spanned(
77                            &nv.value,
78                            "expected string literal for `tag`",
79                        ));
80                    }
81                }
82                syn::Meta::NameValue(nv) if nv.path.is_ident("conflicts") => {
83                    if let syn::Expr::Lit(syn::ExprLit {
84                        lit: syn::Lit::Str(lit_str),
85                        ..
86                    }) = &nv.value
87                    {
88                        let value = lit_str.value();
89                        if value != "string" {
90                            return Err(syn::Error::new_spanned(
91                                lit_str,
92                                "unknown conflict resolution mode; only `\"string\"` is supported",
93                            ));
94                        }
95                        attrs.conflicts = Some(value);
96                    } else {
97                        return Err(syn::Error::new_spanned(
98                            &nv.value,
99                            "expected string literal for `conflicts`",
100                        ));
101                    }
102                }
103                syn::Meta::Path(path) if path.is_ident("align") => {
104                    attrs.align = true;
105                }
106                other => {
107                    return Err(syn::Error::new_spanned(
108                        other,
109                        "unknown dataframe attribute; expected `name`, `align`, `tag`, or `conflicts`",
110                    ));
111                }
112            }
113        }
114    }
115
116    Ok(attrs)
117}
118// endregion
119
120// region: Field-level attribute parsing
121
122/// Parsed field-level `#[dataframe(...)]` attributes.
123///
124/// These attributes control how individual struct/enum fields map to DataFrame columns.
125/// Mutually exclusive combinations (`as_list` + `expand`, `as_list` + `width`,
126/// `as_factor` + `as_list`, `as_factor` + `expand`, `as_factor` + `width`) are
127/// rejected during parsing.
128#[derive(#[automatically_derived]
impl ::core::default::Default for FieldAttrs {
    #[inline]
    fn default() -> Self {
        FieldAttrs {
            skip: ::core::default::Default::default(),
            rename: ::core::default::Default::default(),
            as_list: ::core::default::Default::default(),
            as_factor: ::core::default::Default::default(),
            expand: ::core::default::Default::default(),
            width: ::core::default::Default::default(),
        }
    }
}Default)]
129pub(super) struct FieldAttrs {
130    /// `#[dataframe(skip)]` -- omit this field from the DataFrame entirely.
131    pub(super) skip: bool,
132    /// `#[dataframe(rename = "col")]` -- use a custom column name instead of the field name.
133    pub(super) rename: Option<String>,
134    /// `#[dataframe(as_list)]` -- keep a collection field as a single R list column
135    /// (suppresses automatic expansion into suffixed columns).
136    pub(super) as_list: bool,
137    /// `#[dataframe(as_factor)]` -- treat a unit-only inner enum field as an R factor column.
138    /// Only valid on bare-ident enum types (no generic parameters). The inner enum must be
139    /// unit-only (`#[derive(DataFrameRow)]` emits `IntoR` and `IntoR for Vec<Option<Self>>`).
140    pub(super) as_factor: bool,
141    /// `#[dataframe(expand)]` or `#[dataframe(unnest)]` -- explicitly expand a
142    /// collection field into multiple suffixed columns.
143    expand: bool,
144    /// `#[dataframe(width = N)]` -- pin the expansion width for `Vec<T>`, `Box<[T]>`,
145    /// or `&[T]` fields. Rows shorter than `N` get `None` for missing positions.
146    pub(super) width: Option<usize>,
147}
148
149/// Parse field-level `#[dataframe(...)]` attributes from a `syn::Field`.
150///
151/// Recognizes: `skip`, `rename`, `as_list`, `as_factor`, `expand` (alias `unnest`), and `width`.
152/// Validates mutual exclusivity of conflicting options (`as_list` vs `expand`/`width`,
153/// `as_factor` vs `as_list`/`expand`/`width`).
154/// Returns `Err` for unknown keys, invalid width values, or conflicting options.
155pub(super) fn parse_field_attrs(field: &syn::Field) -> syn::Result<FieldAttrs> {
156    let mut attrs = FieldAttrs::default();
157
158    for attr in &field.attrs {
159        if !attr.path().is_ident("dataframe") {
160            continue;
161        }
162
163        attr.parse_nested_meta(|meta| {
164            if meta.path.is_ident("skip") {
165                attrs.skip = true;
166                Ok(())
167            } else if meta.path.is_ident("rename") {
168                let value = meta.value()?;
169                let lit: syn::LitStr = value.parse()?;
170                attrs.rename = Some(lit.value());
171                Ok(())
172            } else if meta.path.is_ident("as_list") {
173                attrs.as_list = true;
174                Ok(())
175            } else if meta.path.is_ident("as_factor") {
176                attrs.as_factor = true;
177                Ok(())
178            } else if meta.path.is_ident("expand") || meta.path.is_ident("unnest") {
179                attrs.expand = true;
180                Ok(())
181            } else if meta.path.is_ident("width") {
182                let value = meta.value()?;
183                let lit: syn::LitInt = value.parse()?;
184                let n: usize = lit.base10_parse()?;
185                if n == 0 {
186                    return Err(syn::Error::new(lit.span(), "`width` must be >= 1"));
187                }
188                attrs.width = Some(n);
189                Ok(())
190            } else {
191                Err(meta.error(
192                    "unknown field attribute; expected `skip`, `rename`, `as_list`, `as_factor`, `expand`, `unnest`, or `width`",
193                ))
194            }
195        })?;
196    }
197
198    let span = field.ident.as_ref().map_or(Span::call_site(), |i| i.span());
199
200    // Validation: conflicting options
201    if attrs.as_list && attrs.expand {
202        return Err(syn::Error::new(
203            span,
204            "`as_list` and `expand`/`unnest` are mutually exclusive",
205        ));
206    }
207    if attrs.as_list && attrs.width.is_some() {
208        return Err(syn::Error::new(
209            span,
210            "`as_list` and `width` are mutually exclusive",
211        ));
212    }
213    if attrs.as_factor && attrs.as_list {
214        return Err(syn::Error::new(
215            span,
216            "`as_factor` and `as_list` are mutually exclusive",
217        ));
218    }
219    if attrs.as_factor && attrs.expand {
220        return Err(syn::Error::new(
221            span,
222            "`as_factor` and `expand`/`unnest` are mutually exclusive",
223        ));
224    }
225    if attrs.as_factor && attrs.width.is_some() {
226        return Err(syn::Error::new(
227            span,
228            "`as_factor` and `width` are mutually exclusive",
229        ));
230    }
231
232    Ok(attrs)
233}
234// endregion
235
236// region: Type classification
237
238/// Classification of a field type for DataFrame column expansion.
239///
240/// Used to decide whether a field maps to a single column or should be
241/// expanded into multiple suffixed columns (e.g., `coords_1`, `coords_2`).
242pub(super) enum FieldTypeKind<'a> {
243    /// Single column (most types). No expansion.
244    Scalar,
245    /// `[T; N]` -- fixed-size array, expands to `N` columns at compile time.
246    /// Contains the element type and array length.
247    FixedArray(&'a syn::Type, usize),
248    /// `Vec<T>` -- variable length, needs `width` attribute or `expand` for expansion.
249    /// Contains the element type.
250    VariableVec(&'a syn::Type),
251    /// `Box<[T]>` -- owned slice, treated like `Vec<T>` for expansion purposes.
252    /// Contains the element type.
253    BoxedSlice(&'a syn::Type),
254    /// `&[T]` -- borrowed slice, treated like `Vec<T>` for expansion purposes.
255    /// Contains the element type.
256    BorrowedSlice(&'a syn::Type),
257    /// `HashMap<K, V>` or `BTreeMap<K, V>`. The two derive paths treat maps
258    /// differently:
259    /// - *enum path*: expands to two parallel list-columns `<field>_keys` /
260    ///   `<field>_values` (see `enum_expansion.rs`).
261    /// - *struct path*: resolves to a `Single` opaque list-of-named-lists
262    ///   column (`Vec<map>: IntoR`); reader-capable for `String` keys +
263    ///   reader-scalar values (#764, see `SingleFieldData::map_reader`).
264    ///
265    /// Key order follows the map's own iteration order: `BTreeMap` yields
266    /// sorted keys, `HashMap` yields non-deterministic order.
267    Map {
268        key_ty: &'a syn::Type,
269        val_ty: &'a syn::Type,
270    },
271    /// `Option<scalar>` (`Option<f64>`, `Option<String>`, …): one NA-able
272    /// column. The companion stores the full `Vec<Option<T>>`, whose `IntoR`
273    /// writes `None` as the typed `NA` and whose `TryFromSexp` reads `NA` back
274    /// as `None`; the inner type is never needed separately.
275    ///
276    /// Only the **struct** path accepts this shape. Enum variant fields are
277    /// already wrapped in `Option` (absent for other variants), so an
278    /// `Option<scalar>` field there would need `Vec<Option<Option<T>>>`, which
279    /// has no conversion; `enum_expansion.rs` rejects it with a pointer to the
280    /// bare scalar. Non-scalar `Option<…>` payloads (maps, structs, collections)
281    /// are still rejected in `classify_field_type` (#484).
282    OptionScalar,
283    /// A struct-typed field whose inner type implements `DataFrameRow`.
284    ///
285    /// Flattened into `<field>_<inner_col>` prefixed columns by default.
286    /// A compile-time assertion against `::miniextendr_api::markers::DataFrameRow`
287    /// is emitted so rustc gives a clear error when the inner type is missing the
288    /// derive.
289    ///
290    /// Suppressed by `#[dataframe(as_list)]` — with as_list the field becomes
291    /// a `Scalar` and uses the ordinary single-column codegen path.
292    Struct {
293        /// The full field type (used for the compile-time DataFrameRow assertion).
294        inner_ty: &'a syn::Type,
295    },
296}
297
298/// Classify a field type for DataFrame column expansion.
299///
300/// Inspects the type AST to detect:
301/// - `[T; N]` or `&[T; N]` -> `FixedArray`
302/// - `&[T]` -> `BorrowedSlice`
303/// - `Vec<T>` -> `VariableVec`
304/// - `Box<[T]>` -> `BoxedSlice`
305/// - `HashMap<K, V>` / `BTreeMap<K, V>` -> `Map`
306/// - Any non-scalar bare path type (single- or multi-segment, e.g. `Point` or
307///   `crate::geom::Point`) -> `Struct`
308/// - Everything else (known scalars, generic types with args, `::abs::Paths`) -> `Scalar`
309///
310/// Returns `Err` for shapes the macro cannot classify and that would silently
311/// become opaque list-columns: `Option<T>`, `Cow<T>`, `Rc<T>`, `Arc<T>`,
312/// `RefCell<T>`, `Cell<T>`, `Mutex<T>`, `RwLock<T>`.  Use
313/// `#[dataframe(as_list)]` to opt into list-column treatment explicitly.
314pub(super) fn classify_field_type(ty: &syn::Type) -> syn::Result<FieldTypeKind<'_>> {
315    // Check for [T; N]
316    if let syn::Type::Array(arr) = ty
317        && let syn::Expr::Lit(syn::ExprLit {
318            lit: syn::Lit::Int(lit_int),
319            ..
320        }) = &arr.len
321        && let Ok(n) = lit_int.base10_parse::<usize>()
322    {
323        return Ok(FieldTypeKind::FixedArray(&arr.elem, n));
324    }
325
326    // Check for &[T] and &[T; N]
327    if let syn::Type::Reference(ref_ty) = ty {
328        // &[T] → BorrowedSlice
329        if let syn::Type::Slice(slice) = &*ref_ty.elem {
330            return Ok(FieldTypeKind::BorrowedSlice(&slice.elem));
331        }
332        // &[T; N] → FixedArray (same as owned)
333        if let syn::Type::Array(arr) = &*ref_ty.elem
334            && let syn::Expr::Lit(syn::ExprLit {
335                lit: syn::Lit::Int(lit_int),
336                ..
337            }) = &arr.len
338            && let Ok(n) = lit_int.base10_parse::<usize>()
339        {
340            return Ok(FieldTypeKind::FixedArray(&arr.elem, n));
341        }
342    }
343
344    if let syn::Type::Path(type_path) = ty
345        && let Some(seg) = type_path.path.segments.last()
346        && let syn::PathArguments::AngleBracketed(args) = &seg.arguments
347    {
348        // Reject wrapper types that would silently fall through to Scalar /
349        // Struct and produce a confusing opaque list-column or a downstream
350        // DataFrameRow assertion error.  These are the common smart-pointer
351        // and interior-mutability types that wrap a meaningful inner type but
352        // that DataFrameRow does not know how to expand.
353        //
354        // The macro has no way to resolve through the wrapper without type-
355        // checking (which is unavailable in proc macros). The user must either
356        // unwrap to the inner type, or annotate with `#[dataframe(as_list)]`
357        // to opt into an explicit opaque list-column.
358        //
359        // IMPORTANT: The rejection fires on *path identity alone*, before we
360        // inspect generic args.  `Cow<'a, T>` has a lifetime as its first
361        // generic argument, not a type; inspecting `args.args.first()` as a
362        // `GenericArgument::Type` would silently skip `Cow`.  Checking ident
363        // before args makes the rejection robust to any generic shape.
364        const REJECTED_WRAPPERS: &[&str] = &[
365            "Option", "Cow", "Rc", "Arc", "RefCell", "Cell", "Mutex", "RwLock",
366        ];
367        let name = seg.ident.to_string();
368        // `Option<scalar>` is the NA contract (`None` ⇄ `NA`), not a wrapper to
369        // see through: `Vec<Option<T>>` has `IntoR` / `TryFromSexp` for every
370        // name in `OPTION_SCALAR_NAMES`, so it is a plain single column (#1437).
371        if name == "Option"
372            && let Some(syn::GenericArgument::Type(inner)) = args.args.first()
373        {
374            if is_known_scalar_ty(inner, &["u8"]) {
375                return Err(syn::Error::new_spanned(
376                    ty,
377                    "DataFrameRow cannot represent `Option<u8>` as a column: R raw vectors \
378                     have no NA value. Use `u8` for a non-missing raw column, or \
379                     `Option<u16>` / `Option<i32>` for a nullable integer column.",
380                ));
381            }
382            if is_option_scalar_inner(inner) {
383                return Ok(FieldTypeKind::OptionScalar);
384            }
385        }
386        if REJECTED_WRAPPERS.contains(&name.as_str()) {
387            let hint = if name == "Option" {
388                "`Option<…>` is supported only around a scalar (`Option<f64>`, \
389                 `Option<String>`, …), where it is the NA-able column contract. "
390            } else {
391                ""
392            };
393            return Err(syn::Error::new_spanned(
394                ty,
395                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("DataFrameRow does not support `{0}<…>` directly as a field type. {1}Use `#[dataframe(as_list)]` to opt into an explicit opaque list-column, or unwrap to the inner type (e.g. store the inner value directly, using a sentinel / empty collection for the absent case).",
                name, hint))
    })format!(
396                    "DataFrameRow does not support `{name}<…>` directly as a field type. {hint}\
397                     Use `#[dataframe(as_list)]` to opt into an explicit opaque list-column, \
398                     or unwrap to the inner type (e.g. store the inner value directly, using \
399                     a sentinel / empty collection for the absent case)."
400                ),
401            ));
402        }
403
404        // For the collection types below we need the first *type* argument.
405        // Skip any leading lifetime or const arguments (e.g. `Cow<'a, B>`
406        // has a lifetime first, but `Cow` is already rejected above so we
407        // only reach here for other angle-bracketed types).
408        let first_type_arg = args.args.iter().find_map(|arg| {
409            if let syn::GenericArgument::Type(t) = arg {
410                Some(t)
411            } else {
412                None
413            }
414        });
415
416        if let Some(inner) = first_type_arg {
417            // Check for Vec<T>
418            if seg.ident == "Vec" {
419                return Ok(FieldTypeKind::VariableVec(inner));
420            }
421
422            // Check for Box<[T]>
423            if seg.ident == "Box"
424                && let syn::Type::Slice(slice) = inner
425            {
426                return Ok(FieldTypeKind::BoxedSlice(&slice.elem));
427            }
428
429            // Check for HashMap<K, V> and BTreeMap<K, V>
430            if (seg.ident == "HashMap" || seg.ident == "BTreeMap")
431                && let Some(syn::GenericArgument::Type(val_ty)) = args.args.iter().nth(1)
432            {
433                return Ok(FieldTypeKind::Map {
434                    key_ty: inner,
435                    val_ty,
436                });
437            }
438        }
439    }
440
441    // Any remaining path type whose LAST segment is a bare ident (no generic args)
442    // that is NOT a known scalar is treated as a user-defined struct whose
443    // `DataFrameRow` derive should be called.  The compile-time assertion
444    // `_assert_inner_is_dataframe_row::<Inner>()` in the generated code surfaces a
445    // clear error if the inner type doesn't have the derive.
446    //
447    // Known scalars (i32, f64, String, bool, …) are kept as `Scalar` so that existing
448    // enum variants with primitive fields (e.g. `Click { id: i64, x: f64 }`) are not
449    // misclassified as struct fields.
450    //
451    // Multi-segment paths (e.g. `crate::geom::Point`, `geom::Point`) are now correctly
452    // classified here — the previous `segs.len() == 1` guard was overly restrictive.
453    // Paths with a leading `::` (absolute paths like `::std::ffi::CString`) still fall
454    // through to `Scalar`; use `#[dataframe(as_list)]` or an unqualified import if
455    // you need a custom treatment.
456    //
457    // RISK: a user type whose last path segment is named after a known-scalar
458    // (e.g. `mymod::String`) still correctly falls through to `Scalar` because of the
459    // KNOWN_SCALARS check. A type named `mymod::Option` / `mymod::Vec` would shadow
460    // the detection above — accepted per Rust naming convention (canonical names are
461    // rarely shadowed). `#[dataframe(as_list)]` is the documented escape hatch.
462    if let syn::Type::Path(type_path) = ty {
463        let segs = &type_path.path.segments;
464        // No leading colon (rules out `::std::…` absolute paths) and no self-type.
465        if type_path.qself.is_none() && type_path.path.leading_colon.is_none() {
466            let seg = segs.last().unwrap();
467            if #[allow(non_exhaustive_omitted_patterns)] match seg.arguments {
    syn::PathArguments::None => true,
    _ => false,
}matches!(seg.arguments, syn::PathArguments::None) {
468                let name = seg.ident.to_string();
469                // Known scalar type names — keep as Scalar so they do not trigger the
470                // struct-flatten path and the DataFrameRow compile-time assertion.
471                const KNOWN_SCALARS: &[&str] = &[
472                    "bool", "char", "str", "f32", "f64", "i8", "i16", "i32", "i64", "i128",
473                    "isize", "u8", "u16", "u32", "u64", "u128", "usize", "String",
474                ];
475                if !KNOWN_SCALARS.contains(&name.as_str()) {
476                    return Ok(FieldTypeKind::Struct { inner_ty: ty });
477                }
478            }
479        }
480    }
481
482    Ok(FieldTypeKind::Scalar)
483}
484
485/// Scalar element types whose `Vec<T>` (and `Vec<Option<T>>`) round-trips through
486/// `TryFromSexp` — the supported field types for the parallel from-R reader
487/// (`try_from_dataframe_par`). This is intentionally narrower than
488/// `FieldTypeKind::Scalar`: set/opaque collection types (`HashSet<…>`,
489/// `BTreeSet<…>`) also classify as `Scalar` but do NOT implement `Vec<_>:
490/// TryFromSexp`, so they must be excluded from the reader path.
491///
492/// `pub(super)` so `enum_expansion.rs` (in the `dataframe_derive` module dir)
493/// can reuse the same allow-list without duplication.
494pub(super) const READER_SCALAR_NAMES: &[&str] = &[
495    "bool", "f32", "f64", "i8", "i16", "i32", "i64", "u8", "u16", "u32", "String",
496];
497
498/// Scalar types accepted inside `Option<…>` as a struct-path field (#1437):
499/// every `T` here has `IntoR for Vec<Option<T>>` (typed `NA` for `None`) in
500/// `miniextendr-api::into_r`. The reader side is gated separately by
501/// [`is_reader_scalar_ty`], so `Option<u64>` / `Option<usize>` fields are
502/// write-only, like their bare counterparts.
503pub(super) const OPTION_SCALAR_NAMES: &[&str] = &[
504    "bool", "f32", "f64", "i8", "i16", "i32", "i64", "u16", "u32", "u64", "isize", "usize",
505    "String",
506];
507
508/// Match the final scalar name, as field classification does. Absolute and
509/// relative paths have the same conversion support; associated types and
510/// generic payloads still need their own classification.
511fn is_known_scalar_ty(ty: &syn::Type, names: &[&str]) -> bool {
512    if let syn::Type::Path(tp) = ty
513        && tp.qself.is_none()
514        && let Some(seg) = tp.path.segments.last()
515        && #[allow(non_exhaustive_omitted_patterns)] match seg.arguments {
    syn::PathArguments::None => true,
    _ => false,
}matches!(seg.arguments, syn::PathArguments::None)
516    {
517        return names.contains(&seg.ident.to_string().as_str());
518    }
519    false
520}
521
522/// True if `ty` is `u8`, bare or qualified. R stores it in a raw vector, which
523/// has no NA, so a `u8` column cannot pad or omit cells (`Vec<Option<u8>>` has
524/// no `IntoR`).
525pub(super) fn is_raw_scalar_ty(ty: &syn::Type) -> bool {
526    is_known_scalar_ty(ty, &["u8"])
527}
528
529/// The payload of `Option<T>` (possibly qualified), if `ty` is one.
530pub(super) fn option_payload(ty: &syn::Type) -> Option<&syn::Type> {
531    if let syn::Type::Path(tp) = ty
532        && tp.qself.is_none()
533        && let Some(seg) = tp.path.segments.last()
534        && seg.ident == "Option"
535        && let syn::PathArguments::AngleBracketed(args) = &seg.arguments
536        && let Some(syn::GenericArgument::Type(inner)) = args.args.first()
537    {
538        return Some(inner);
539    }
540    None
541}
542
543/// A `u8` in a column whose cells can be NA. `why` names the source of the NA
544/// cells and `fix` the alternative, so the error points at the field instead of
545/// the missing `IntoR` impl inside the generated code (#2025).
546pub(super) fn raw_na_column_error(ty: &syn::Type, why: &str, fix: &str) -> syn::Error {
547    syn::Error::new_spanned(
548        ty,
549        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("DataFrameRow cannot store `u8` here: {0}, and R raw vectors have no NA value. {1}",
                why, fix))
    })format!(
550            "DataFrameRow cannot store `u8` here: {why}, and R raw vectors have no NA \
551             value. {fix}"
552        ),
553    )
554}
555
556/// True if `ty` names a type from [`OPTION_SCALAR_NAMES`] (possibly qualified,
557/// without generic args), a valid payload for a single NA-able column.
558pub(super) fn is_option_scalar_inner(ty: &syn::Type) -> bool {
559    is_known_scalar_ty(ty, OPTION_SCALAR_NAMES)
560}
561
562/// True if `ty` names a known scalar, qualified or bare (no `Option` or generics).
563///
564/// These are the element types whose `Vec<Option<ty>>` round-trips through
565/// `TryFromSexp` — required for the *column-expansion* readers, which read each
566/// expanded slot as `Vec<Option<elem>>` (the write side wraps every slot in
567/// `Option`). Allowing `Option<scalar>` here would ask for `Vec<Option<Option<…>>>`,
568/// which has no `TryFromSexp` impl.
569///
570/// `pub(super)` so `enum_expansion.rs` can reuse it.
571pub(super) fn is_bare_reader_scalar_ty(ty: &syn::Type) -> bool {
572    is_known_scalar_ty(ty, READER_SCALAR_NAMES)
573}
574
575/// True if `ty` is a known scalar path, or `Option<known-scalar>`.
576///
577/// These are exactly the field types for which the from-R reader can pull a
578/// column out as `Vec<ty>` via `TryFromSexp` (scalar `Single` fields and
579/// `[T; N]` fixed-array elements, neither of which adds an `Option` wrapper).
580///
581/// `pub(super)` so `enum_expansion.rs` can reuse it.
582pub(super) fn is_reader_scalar_ty(ty: &syn::Type) -> bool {
583    if is_bare_reader_scalar_ty(ty) {
584        return true;
585    }
586    // Option<scalar>
587    if let syn::Type::Path(tp) = ty
588        && let Some(seg) = tp.path.segments.last()
589        && seg.ident == "Option"
590        && let syn::PathArguments::AngleBracketed(args) = &seg.arguments
591        && let Some(syn::GenericArgument::Type(inner)) = args.args.first()
592    {
593        return is_bare_reader_scalar_ty(inner);
594    }
595    false
596}
597
598/// True if `ty`'s last path segment is the bare ident `String` (path-identity
599/// check, same convention as `classify_field_type`).
600fn is_string_ty(ty: &syn::Type) -> bool {
601    if let syn::Type::Path(tp) = ty
602        && let Some(seg) = tp.path.segments.last()
603        && #[allow(non_exhaustive_omitted_patterns)] match seg.arguments {
    syn::PathArguments::None => true,
    _ => false,
}matches!(seg.arguments, syn::PathArguments::None)
604    {
605        return seg.ident == "String";
606    }
607    false
608}
609
610/// Number of *type* arguments on `ty`'s last path segment (0 when not
611/// angle-bracketed). Rejects `HashMap<K, V, S>` custom-hasher maps from the
612/// reader path — the `Vec<HashMap<String, V>>: TryFromSexp` impl only covers
613/// the default hasher.
614fn generic_type_arg_count(ty: &syn::Type) -> usize {
615    if let syn::Type::Path(tp) = ty
616        && let Some(seg) = tp.path.segments.last()
617        && let syn::PathArguments::AngleBracketed(args) = &seg.arguments
618    {
619        return args
620            .args
621            .iter()
622            .filter(|a| #[allow(non_exhaustive_omitted_patterns)] match a {
    syn::GenericArgument::Type(_) => true,
    _ => false,
}matches!(a, syn::GenericArgument::Type(_)))
623            .count();
624    }
625    0
626}
627
628/// True if a resolved struct field can be read back out of an R `data.frame`.
629///
630/// Determines whether the struct gets a generated `try_from_dataframe` reader.
631/// Each shape's reader is the inverse of its column-expansion write rule:
632/// - `Single` scalar: one column read as `Vec<ty>` (excludes `as_list` and
633///   opaque set/collection columns — those classify as `Single` but lack
634///   `Vec<_>: TryFromSexp`).
635/// - `Single` factor: `FactorVec<ty>` validates levels and reads owned variants.
636/// - `Single` map column (`HashMap<String, V>` / `BTreeMap<String, V>`): one
637///   VECSXP list-of-named-lists column read whole via `Vec<map>: TryFromSexp`
638///   — the exact inverse of the `Vec<map>: IntoR` write shape (#764). Gated
639///   to `String` keys + reader-scalar values at resolve time (`map_reader`).
640/// - `Single` owned list-column: `Vec<scalar>` / `Box<[scalar]>` stored as a
641///   VECSXP list-column; the reader deserialises each row's element via
642///   `Vec<elem>: TryFromSexp` and `.into()`-converts to the field type (#809).
643/// - `ExpandedFixed` (`[T; N]`): `N` columns regrouped into the array.
644/// - `ExpandedVec` / `AutoExpandVec` (`Vec<T>`): suffixed `Option` columns
645///   flattened back per row (bare-scalar elements only).
646/// - `Struct` (nested `DataFrameRow`): always eligible — the reader routes the
647///   un-prefixed sub-frame through the inner type's `DataFrameRowConvert`, which
648///   degrades to a clear runtime error if the inner shape itself has no reader.
649///
650/// Borrowed expansion origins (`&[T]` / `&[T; N]`) are not readable (owned R data
651/// can't produce a borrow) — flagged via `readable` at resolve time.
652fn field_reader_capable(rf: &ResolvedField) -> bool {
653    match rf {
654        ResolvedField::Single(d) => {
655            !d.needs_into_list
656                && (d.is_factor
657                    || is_reader_scalar_ty(&d.ty)
658                    || d.map_reader
659                    || d.list_elem_ty
660                        .as_ref()
661                        .is_some_and(is_bare_reader_scalar_ty))
662        }
663        ResolvedField::ExpandedFixed(d) => d.readable && is_reader_scalar_ty(&d.elem_ty),
664        ResolvedField::ExpandedVec(d) => d.readable && is_bare_reader_scalar_ty(&d.elem_ty),
665        ResolvedField::AutoExpandVec(d) => d.readable && is_bare_reader_scalar_ty(&d.elem_ty),
666        ResolvedField::Struct(_) => true,
667        ResolvedField::Map(d) => {
668            is_bare_reader_scalar_ty(&d.key_ty) && is_bare_reader_scalar_ty(&d.val_ty)
669        }
670    }
671}
672
673/// True if `ty` is a borrowed reference (`&[T]`, `&[T; N]`, `&str`, …). Such
674/// expansion fields can't be reconstructed by value in the R→Rust reader.
675pub(super) fn field_is_borrowed_ref(ty: &syn::Type) -> bool {
676    #[allow(non_exhaustive_omitted_patterns)] match ty {
    syn::Type::Reference(_) => true,
    _ => false,
}matches!(ty, syn::Type::Reference(_))
677}
678// endregion
679
680// region: Resolved field model (struct path)
681
682/// A resolved struct field ready for codegen -- determines how this field maps
683/// to DataFrame companion struct columns.
684///
685/// Each variant represents a different expansion strategy:
686/// - `Single`: one field -> one `Vec<T>` column
687/// - `ExpandedFixed`: `[T; N]` -> N columns (`name_1..name_N`) at compile time
688/// - `ExpandedVec`: `Vec<T>` + `width = N` -> N `Vec<Option<T>>` columns
689/// - `AutoExpandVec`: `Vec<T>` + `expand` -> dynamic column count at runtime
690enum ResolvedField {
691    /// Single column: `name → Vec<ty>`.
692    Single(Box<SingleFieldData>),
693    /// Expanded fixed array: `name: [T; N]` → `name_1..name_N`.
694    ExpandedFixed(Box<ExpandedFixedData>),
695    /// Expanded variable vec with pinned width: `name: Vec<T>` + `width = N`.
696    ExpandedVec(Box<ExpandedVecData>),
697    /// Auto-expanded `Vec<T>`/`Box<[T]>`: column count determined at runtime from max row length.
698    AutoExpandVec(Box<AutoExpandVecData>),
699    /// Struct field whose inner type implements `DataFrameRow` (issue #485).
700    /// Companion holds `Vec<Inner>`; `into_data_frame` calls `Inner::to_dataframe`
701    /// and flattens columns under the `<base>_` prefix.
702    Struct(Box<StructFieldData>),
703    /// Non-String-keyed `HashMap<K,V>` / `BTreeMap<K,V>` field (#919).
704    /// Expands to two parallel list-columns `<base>_keys` / `<base>_values`,
705    /// each a `Vec<Vec<K>>` / `Vec<Vec<V>>` (VECSXP of typed vectors). The
706    /// reader zips `keys[i]` with `values[i]` back into the map type.
707    Map(Box<MapFieldData>),
708}
709
710/// Data for [`ResolvedField::Map`] (struct path, non-String-keyed maps, #919).
711struct MapFieldData {
712    /// Rust field name (for access on the row type).
713    rust_name: syn::Ident,
714    /// Column name base — keys col = `<base>_keys`, values col = `<base>_values`.
715    base_name: String,
716    /// Key type `K`.
717    key_ty: syn::Type,
718    /// Value type `V`.
719    val_ty: syn::Type,
720    /// Full map type `HashMap<K,V>` / `BTreeMap<K,V>` (used in reader zip).
721    map_ty: syn::Type,
722    /// Index in tuple struct (None for named).
723    tuple_index: Option<syn::Index>,
724}
725
726/// Data for [`ResolvedField::Single`].
727struct SingleFieldData {
728    /// Rust field name (for access).
729    rust_name: syn::Ident,
730    /// Column name in the DataFrame.
731    col_name: syn::Ident,
732    /// Column name string.
733    col_name_str: String,
734    /// Field type stored in the companion `Vec<#ty>`: the field's Rust type, also
735    /// for `#[dataframe(as_list)]` on a struct-typed field (see
736    /// `needs_into_list`), so the companion never holds R objects.
737    ty: syn::Type,
738    /// Index in tuple struct (None for named).
739    tuple_index: Option<syn::Index>,
740    /// `#[dataframe(as_list)]` on a struct-typed field (#485 workaround).
741    /// When `true`, the frame assembly builds the list-column with
742    /// `into_list_column`, which converts each value via `IntoList::into_list()`
743    /// straight into the rooted column (#1748).
744    needs_into_list: bool,
745    /// `Some(elem)` when this Single field is an un-annotated *owned* collection
746    /// (`Vec<scalar>` / `Box<[scalar]>`) stored as an opaque list-column (#809).
747    /// The reader deserialises the list-column back into the owned collection per
748    /// row via `Vec<elem>: TryFromSexp` then `.into()` to the field container type.
749    /// `None` for scalar Single, `as_list`, opaque `Map`/set columns, and borrowed
750    /// `&[T]` (not readable).
751    list_elem_ty: Option<syn::Type>,
752    /// `true` when this Single field is a reader-capable map column (#764):
753    /// `HashMap<String, V>` / `BTreeMap<String, V>` with a reader-scalar `V`
754    /// and no custom hasher. The column is read whole as `Vec<#ty>` via the
755    /// `Vec<map>: TryFromSexp` list-of-named-lists impl — the same `pull_col`
756    /// path scalar Singles use, so it only widens the capability gate.
757    map_reader: bool,
758    /// A unit-only enum stored as one factor column via `UnitEnumFactor`.
759    is_factor: bool,
760}
761
762/// Data for [`ResolvedField::ExpandedFixed`].
763struct ExpandedFixedData {
764    /// Rust field name.
765    rust_name: syn::Ident,
766    /// Base column name (before suffix).
767    base_name: String,
768    /// Element type T.
769    elem_ty: syn::Type,
770    /// Array length N.
771    len: usize,
772    /// Index in tuple struct.
773    tuple_index: Option<syn::Index>,
774    /// Whether the field can be reconstructed by value in the R→Rust reader.
775    /// `false` for a borrowed origin (`&[T; N]`) — owned R data can't produce a
776    /// borrow, so the struct gets no reader (see [`field_reader_capable`]).
777    readable: bool,
778    /// The field is `&[T; N]`: its elements are cloned out, not moved.
779    borrowed: bool,
780}
781
782/// Data for [`ResolvedField::ExpandedVec`].
783struct ExpandedVecData {
784    /// Rust field name.
785    rust_name: syn::Ident,
786    /// Base column name.
787    base_name: String,
788    /// Element type T.
789    elem_ty: syn::Type,
790    /// Pinned width.
791    width: usize,
792    /// Index in tuple struct.
793    tuple_index: Option<syn::Index>,
794    /// Whether the field can be reconstructed by value in the R→Rust reader.
795    /// `false` for a borrowed origin (`&[T]`); `Vec<T>` / `Box<[T]>` are readable
796    /// (the reader collects a `Vec<T>` and `.into()`-converts to the field type).
797    readable: bool,
798    /// The field is `&[T]`: its elements are cloned out, not moved.
799    borrowed: bool,
800}
801
802/// Data for [`ResolvedField::Struct`].
803///
804/// A struct field whose inner type implements `DataFrameRow`. The companion
805/// struct holds `Vec<Inner>` (the same type users already pass into
806/// `to_dataframe(vec![...])`). At `into_data_frame()` time the inner rows are
807/// converted via `Inner::to_dataframe` → `into_named_columns()`, prefixed with
808/// `<base_name>_`, and pushed into the parent data.frame.
809struct StructFieldData {
810    /// Rust field name (for access on the row type).
811    rust_name: syn::Ident,
812    /// Companion struct field name (ident).
813    col_name: syn::Ident,
814    /// Column name base used as the R-side prefix (`<base>_<inner_col>`).
815    col_name_str: String,
816    /// Inner struct type (used for `to_dataframe` dispatch + DataFrameRow assertion).
817    inner_ty: syn::Type,
818    /// Index in tuple struct (None for named).
819    tuple_index: Option<syn::Index>,
820}
821
822/// Data for [`ResolvedField::AutoExpandVec`].
823struct AutoExpandVecData {
824    /// Rust field name (for row access).
825    rust_name: syn::Ident,
826    /// Companion struct field name (ident).
827    col_name: syn::Ident,
828    /// Column name base string (for suffixed column names).
829    col_name_str: String,
830    /// Element type T.
831    elem_ty: syn::Type,
832    /// Container type for companion struct (`Vec<T>` or `Box<[T]>`).
833    container_ty: syn::Type,
834    /// Index in tuple struct.
835    tuple_index: Option<syn::Index>,
836    /// Whether the field can be reconstructed by value in the R→Rust reader.
837    /// `false` for a borrowed origin (`&[T]`); `Vec<T>` / `Box<[T]>` are readable.
838    readable: bool,
839    /// The field is `&[T]`: its elements are cloned out, not moved.
840    borrowed: bool,
841}
842
843/// The same `as_factor` shapes are accepted on struct and enum fields. The
844/// generated conversion checks `UnitEnumFactor` on the selected type.
845fn validate_factor_field_type(ty: &syn::Type) -> syn::Result<()> {
846    match classify_field_type(ty)? {
847        FieldTypeKind::Struct { .. } => Ok(()),
848        _ => Err(syn::Error::new_spanned(
849            ty,
850            "`as_factor` is only valid on bare-ident enum/struct types; \
851             use `as_list` for generic or complex types, or remove \
852             `as_factor` for scalar fields",
853        )),
854    }
855}
856
857/// Resolve a struct field into a [`ResolvedField`], applying field attributes.
858///
859/// Combines the field's `#[dataframe(...)]` attributes with its type classification
860/// to determine the codegen strategy:
861/// - `skip` -> returns `None`
862/// - `as_list` / `as_factor` -> `Single` (suppresses expansion)
863/// - `FixedArray` -> `ExpandedFixed` (compile-time expansion to N columns)
864/// - `VariableVec`/`BoxedSlice`/`BorrowedSlice` + `width` -> `ExpandedVec`
865/// - `VariableVec`/`BoxedSlice`/`BorrowedSlice` + `expand` -> `AutoExpandVec`
866/// - Everything else -> `Single`
867///
868/// Returns `Err` if `width` or `expand` is used on an incompatible type.
869fn resolve_struct_field(
870    field: &syn::Field,
871    index: usize,
872    is_tuple: bool,
873) -> syn::Result<Option<ResolvedField>> {
874    let field_attrs = parse_field_attrs(field)?;
875
876    if field_attrs.skip {
877        return Ok(None);
878    }
879
880    let rust_name = if is_tuple {
881        match ::quote::__private::IdentFragmentAdapter(&index) {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("_{0}", arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("_{}", index)
882    } else {
883        field.ident.as_ref().unwrap().clone()
884    };
885
886    let col_name_str = field_attrs
887        .rename
888        .clone()
889        .unwrap_or_else(|| crate::naming::ident_name(&rust_name));
890    let col_name = crate::naming::name_ident(&col_name_str);
891
892    let tuple_index = if is_tuple {
893        Some(syn::Index::from(index))
894    } else {
895        None
896    };
897
898    let ty = &field.ty;
899    // Propagate classification errors (e.g. Option<T>, Arc<T>) when as_list is
900    // not set.  The as_list branch below uses `.ok()` to suppress errors.
901    let kind = classify_field_type(ty);
902
903    if field_attrs.as_factor {
904        validate_factor_field_type(ty)?;
905        return Ok(Some(ResolvedField::Single(Box::new(SingleFieldData {
906            rust_name,
907            col_name,
908            col_name_str,
909            ty: ty.clone(),
910            tuple_index,
911            needs_into_list: false,
912            list_elem_ty: None,
913            map_reader: false,
914            is_factor: true,
915        }))));
916    }
917
918    // as_list suppresses expansion. For struct-typed fields (#485 opt-out), the
919    // companion stores the struct values and the frame assembly converts each
920    // one via `IntoList::into_list()` straight into the rooted list-column
921    // (`into_list_column`). For non-struct as_list fields, the existing
922    // behavior is preserved: the field type is serialized natively (this
923    // requires `Vec<#ty>: IntoR`).
924    if field_attrs.as_list {
925        // Use `.ok()` here: `as_list` is an explicit opt-in, so wrapper types
926        // like `Option<T>` / `Arc<T>` are allowed — they become opaque list-
927        // columns. Any classification error is suppressed and treated as non-Struct.
928        let needs_into_list = #[allow(non_exhaustive_omitted_patterns)] match classify_field_type(ty).ok() {
    Some(FieldTypeKind::Struct { .. }) => true,
    _ => false,
}matches!(
929            classify_field_type(ty).ok(),
930            Some(FieldTypeKind::Struct { .. })
931        );
932        return Ok(Some(ResolvedField::Single(Box::new(SingleFieldData {
933            rust_name,
934            col_name,
935            col_name_str,
936            ty: ty.clone(),
937            tuple_index,
938            needs_into_list,
939            list_elem_ty: None,
940            map_reader: false,
941            is_factor: false,
942        }))));
943    }
944
945    match kind? {
946        FieldTypeKind::FixedArray(elem_ty, len) => Ok(Some(ResolvedField::ExpandedFixed(
947            Box::new(ExpandedFixedData {
948                rust_name,
949                base_name: col_name_str,
950                elem_ty: elem_ty.clone(),
951                len,
952                tuple_index,
953                readable: !field_is_borrowed_ref(ty),
954                borrowed: field_is_borrowed_ref(ty),
955            }),
956        ))),
957        FieldTypeKind::VariableVec(elem_ty)
958        | FieldTypeKind::BoxedSlice(elem_ty)
959        | FieldTypeKind::BorrowedSlice(elem_ty) => {
960            if (field_attrs.width.is_some() || field_attrs.expand) && is_raw_scalar_ty(elem_ty) {
961                let attr = if field_attrs.width.is_some() {
962                    "width"
963                } else {
964                    "expand"
965                };
966                return Err(raw_na_column_error(
967                    elem_ty,
968                    &::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("`{0}` pads shorter rows with NA",
                attr))
    })format!("`{attr}` pads shorter rows with NA"),
969                    &::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("Use `u16` or `i32` elements for integer columns, or drop `{0}` to keep each value as one raw-vector cell of a list-column.",
                attr))
    })format!(
970                        "Use `u16` or `i32` elements for integer columns, or drop `{attr}` \
971                         to keep each value as one raw-vector cell of a list-column."
972                    ),
973                ));
974            }
975            if let Some(width) = field_attrs.width {
976                Ok(Some(ResolvedField::ExpandedVec(Box::new(
977                    ExpandedVecData {
978                        rust_name,
979                        base_name: col_name_str,
980                        elem_ty: elem_ty.clone(),
981                        width,
982                        tuple_index,
983                        readable: !field_is_borrowed_ref(ty),
984                        borrowed: field_is_borrowed_ref(ty),
985                    },
986                ))))
987            } else if field_attrs.expand {
988                Ok(Some(ResolvedField::AutoExpandVec(Box::new(
989                    AutoExpandVecData {
990                        rust_name,
991                        col_name,
992                        col_name_str,
993                        elem_ty: elem_ty.clone(),
994                        container_ty: ty.clone(),
995                        tuple_index,
996                        readable: !field_is_borrowed_ref(ty),
997                        borrowed: field_is_borrowed_ref(ty),
998                    },
999                ))))
1000            } else {
1001                // No expansion — keep as opaque single column (list-column on R side).
1002                // Readable owned collections (`Vec<scalar>` / `Box<[scalar]>`) record
1003                // the element type for the list-column reader (#809). Borrowed `&[T]`
1004                // is not readable (can't produce a borrow from owned R data).
1005                Ok(Some(ResolvedField::Single(Box::new(SingleFieldData {
1006                    rust_name,
1007                    col_name,
1008                    col_name_str,
1009                    ty: ty.clone(),
1010                    tuple_index,
1011                    needs_into_list: false,
1012                    list_elem_ty: if field_is_borrowed_ref(ty) {
1013                        None
1014                    } else {
1015                        Some((*elem_ty).clone())
1016                    },
1017                    map_reader: false,
1018                    is_factor: false,
1019                }))))
1020            }
1021        }
1022        // Struct-in-struct flattening (issue #485): inner type must implement
1023        // `DataFrameRow`. Flattening happens at `into_data_frame()` time; the
1024        // companion stores `Vec<Inner>`. `as_list` opts out (handled above).
1025        FieldTypeKind::Struct { inner_ty } => {
1026            if field_attrs.width.is_some() {
1027                return Err(syn::Error::new_spanned(
1028                    ty,
1029                    "`width` is only valid on `Vec<T>`, `Box<[T]>`, or `&[T]` fields",
1030                ));
1031            }
1032            if field_attrs.expand {
1033                return Err(syn::Error::new_spanned(
1034                    ty,
1035                    "`expand`/`unnest` is only valid on `[T; N]`, `Vec<T>`, `Box<[T]>`, or `&[T]` fields",
1036                ));
1037            }
1038            Ok(Some(ResolvedField::Struct(Box::new(StructFieldData {
1039                rust_name,
1040                col_name,
1041                col_name_str,
1042                inner_ty: inner_ty.clone(),
1043                tuple_index,
1044            }))))
1045        }
1046        kind
1047        @ (FieldTypeKind::Scalar | FieldTypeKind::OptionScalar | FieldTypeKind::Map { .. }) => {
1048            if field_attrs.width.is_some() {
1049                return Err(syn::Error::new_spanned(
1050                    ty,
1051                    "`width` is only valid on `Vec<T>`, `Box<[T]>`, or `&[T]` fields",
1052                ));
1053            }
1054            if field_attrs.expand {
1055                return Err(syn::Error::new_spanned(
1056                    ty,
1057                    "`expand`/`unnest` is only valid on `[T; N]`, `Vec<T>`, `Box<[T]>`, or `&[T]` fields",
1058                ));
1059            }
1060            // Struct-path map fields:
1061            //
1062            // - `String`-keyed + reader-scalar value + 2 type args (default hasher):
1063            //   write as one opaque list-of-named-lists column (`Vec<map>: IntoR`).
1064            //   Reader-capable via `Vec<map>: TryFromSexp` (#764). Falls through
1065            //   to `Single` with `map_reader: true` — unchanged.
1066            //
1067            // - Non-String bare-reader-scalar key + bare-reader-scalar value + 2 type args:
1068            //   expand to two parallel list-columns `<base>_keys` / `<base>_values` (#919).
1069            //   `Vec<Vec<K>>: IntoR` and `Vec<Vec<V>>: IntoR` work via the generic
1070            //   `Vec<Vec<T>>` impl (any `T` with `Vec<T>: IntoR`). Float keys (`f32`/`f64`)
1071            //   are also bare-reader-scalar but lack `Eq + Hash` / `Ord`, so reject them
1072            //   with a clear error.
1073            //
1074            // - Custom hasher (3+ type args): fall through to `Single` with no reader
1075            //   (keeps existing behaviour for `HashMap<K, V, S>`).
1076            //
1077            // - Non-scalar key or value: emit a clear error directing to `as_list`.
1078            if let FieldTypeKind::Map { key_ty, val_ty } = kind {
1079                let two_args = generic_type_arg_count(ty) == 2;
1080                if is_string_ty(key_ty) && is_reader_scalar_ty(val_ty) && two_args {
1081                    // String-keyed — existing path (#764).
1082                    return Ok(Some(ResolvedField::Single(Box::new(SingleFieldData {
1083                        rust_name,
1084                        col_name,
1085                        col_name_str,
1086                        ty: ty.clone(),
1087                        tuple_index,
1088                        needs_into_list: false,
1089                        list_elem_ty: None,
1090                        map_reader: true,
1091                        is_factor: false,
1092                    }))));
1093                }
1094                // Float key check: f32/f64 classify as bare_reader_scalar but are
1095                // neither Eq+Hash nor Ord, so they can't be a map key at all.
1096                let is_float_ty = |t: &syn::Type| -> bool {
1097                    if let syn::Type::Path(tp) = t
1098                        && let Some(seg) = tp.path.segments.last()
1099                        && #[allow(non_exhaustive_omitted_patterns)] match seg.arguments {
    syn::PathArguments::None => true,
    _ => false,
}matches!(seg.arguments, syn::PathArguments::None)
1100                    {
1101                        let n = seg.ident.to_string();
1102                        return n == "f32" || n == "f64";
1103                    }
1104                    false
1105                };
1106                if is_float_ty(key_ty) {
1107                    return Err(syn::Error::new_spanned(
1108                        ty,
1109                        "HashMap/BTreeMap with float keys is not supported \
1110                         (f32/f64 are not Eq+Hash/Ord); use a newtype wrapper \
1111                         or `#[dataframe(as_list)]`",
1112                    ));
1113                }
1114                if two_args && is_bare_reader_scalar_ty(key_ty) && is_bare_reader_scalar_ty(val_ty)
1115                {
1116                    // Non-String bare-scalar keyed — new parallel _keys/_values path (#919).
1117                    return Ok(Some(ResolvedField::Map(Box::new(MapFieldData {
1118                        rust_name,
1119                        base_name: col_name_str,
1120                        key_ty: key_ty.clone(),
1121                        val_ty: val_ty.clone(),
1122                        map_ty: ty.clone(),
1123                        tuple_index,
1124                    }))));
1125                }
1126                if two_args
1127                    && (!is_bare_reader_scalar_ty(key_ty) || !is_bare_reader_scalar_ty(val_ty))
1128                {
1129                    // Non-scalar key or value (and not String-keyed) — opaque, no reader.
1130                    // Fall through to Single below.
1131                }
1132                // 3+ type args (custom hasher) or non-scalar — Single with no reader.
1133            }
1134            let map_reader = false;
1135            Ok(Some(ResolvedField::Single(Box::new(SingleFieldData {
1136                rust_name,
1137                col_name,
1138                col_name_str,
1139                ty: ty.clone(),
1140                tuple_index,
1141                needs_into_list: false,
1142                list_elem_ty: None,
1143                map_reader,
1144                is_factor: false,
1145            }))))
1146        }
1147    }
1148}
1149// endregion
1150
1151// region: Top-level dispatch
1152
1153/// Derive `DataFrameRow`: generates a companion DataFrame type with collection fields.
1154///
1155/// # Requirements
1156///
1157/// For enums: all variants must have named fields. A struct row needs no other
1158/// trait; nothing generated converts a row to a list.
1159///
1160/// # Generated Items
1161///
1162/// For a struct `Measurement { time: f64, value: f64 }`:
1163/// - Struct `MeasurementDataFrame { time: Vec<f64>, value: Vec<f64> }`
1164/// - `impl IntoDataFrame for MeasurementDataFrame` (rows → R `data.frame`)
1165/// - `impl ColumnarFrame for MeasurementDataFrame` (rows ↔ the pure-Rust companion)
1166/// - `impl From<Vec<Measurement>> for MeasurementDataFrame`
1167/// - `impl IntoIterator for MeasurementDataFrame`
1168///
1169/// For an enum:
1170/// - Companion struct with `Vec<Option<T>>` columns (field-name union)
1171/// - Optional tag column for variant discrimination
1172/// - `impl From<Vec<Enum>> for EnumDataFrame`
1173/// - `impl IntoDataFrame for EnumDataFrame`
1174/// - `impl ColumnarFrame for EnumDataFrame`
1175/// - `impl DataFrameRowSplit for Enum` (the split representation behind
1176///   `IntoDataFrameSplit`)
1177///
1178/// # Public surface (which verbs to call)
1179///
1180/// - Rows → R `data.frame`: `rows.into_dataframe()?` (`/_par`) or
1181///   `rows.wrap_data_frame()`, from `IntoDataFrame` / `AsDataFrameExt`.
1182/// - R `data.frame` → rows: `Vec::<Row>::from_dataframe(&df)?` (`/_par`) from
1183///   `FromDataFrame`, or the one-call `Row::try_from_dataframe(sexp)` reader.
1184/// - Rows ↔ the pure-Rust columnar companion: the `ColumnarFrame` trait
1185///   (`<Row>DataFrame::from_rows` / `from_rows_par` / `into_rows`), or the `std`
1186///   `Vec<Row>: Into<companion>` / companion `IntoIterator`.
1187/// - Enums: `rows.into_dataframe_split()` (one `data.frame` per variant) from
1188///   `IntoDataFrameSplit`, implemented via the hidden `DataFrameRowSplit` bridge
1189///   on the enum type.
1190///
1191/// All the traits above are re-exported from `miniextendr_api::prelude`. The row
1192/// type also carries two `#[doc(hidden)]` helpers: `to_dataframe(rows) -> companion`,
1193/// retained only because the struct-flatten / nested-enum write paths build a
1194/// nested companion via `Inner::to_dataframe(..)` without naming its type, and
1195/// `to_dataframe_split(rows)`, the body holder behind the `DataFrameRowSplit` bridge.
1196///
1197/// # Attributes
1198///
1199/// - `#[dataframe(name = "CustomName")]` — Custom companion type name
1200/// - `#[dataframe(align)]` — Enum alignment mode (accepted but implicit)
1201/// - `#[dataframe(tag = "col")]` — Add variant discriminator column
1202pub fn derive_dataframe_row(input: DeriveInput) -> syn::Result<TokenStream> {
1203    let row_name = &input.ident;
1204
1205    // Allow lifetime parameters (needed for &[T] borrowed slice fields).
1206    // Allow type parameters on unit-only enums (all variants are unit) — the
1207    // companion struct has no field columns to type-parameterise, and the three
1208    // unit-enum impls (UnitEnumFactor, IntoR, IntoList) handle generics via the
1209    // split path in enum_expansion.rs.
1210    // Reject type and const parameters for everything else.
1211    let has_type_params = input.generics.type_params().next().is_some();
1212    let has_const_params = input.generics.const_params().next().is_some();
1213    if has_type_params || has_const_params {
1214        let is_unit_only_enum = #[allow(non_exhaustive_omitted_patterns)] match &input.data {
    Data::Enum(e) if
        e.variants.iter().all(|v|
                #[allow(non_exhaustive_omitted_patterns)] match v.fields {
                    Fields::Unit => true,
                    _ => false,
                }) => true,
    _ => false,
}matches!(&input.data, Data::Enum(e)
1215            if e.variants.iter().all(|v| matches!(v.fields, Fields::Unit)));
1216        if !is_unit_only_enum {
1217            return Err(syn::Error::new_spanned(
1218                &input.generics,
1219                "DataFrameRow does not support type or const generic parameters",
1220            ));
1221        }
1222    }
1223
1224    // Parse attributes
1225    let attrs = parse_dataframe_attrs(&input)?;
1226
1227    let df_name = attrs
1228        .name
1229        .clone()
1230        .unwrap_or_else(|| match ::quote::__private::IdentFragmentAdapter(&row_name) {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("{0}DataFrame", arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("{}DataFrame", row_name));
1231
1232    let base = match &input.data {
1233        Data::Struct(data) => {
1234            // `align` is a no-op on structs (only semantically meaningful for enums)
1235            derive_struct_dataframe(row_name, &input, data, &df_name, &attrs)
1236        }
1237        Data::Enum(data) => {
1238            // align is implicit for enums — accept but don't require
1239            derive_enum_dataframe(row_name, &input, data, &df_name, &attrs)
1240        }
1241        Data::Union(_) => Err(syn::Error::new_spanned(
1242            row_name,
1243            "DataFrameRow does not support unions",
1244        )),
1245    }?;
1246
1247    // Generate IntoR for the companion DataFrame type so it can be returned
1248    // directly from #[miniextendr] functions. This ensures both the standalone
1249    // #[derive(DataFrameRow)] path and the #[miniextendr(dataframe)] path
1250    // produce identical output.
1251    let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
1252    Ok({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&base, &mut _s);
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::ToTokens::to_tokens(&impl_generics, &mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "miniextendr_api");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "into_r");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "IntoR");
    ::quote::__private::push_ident(&mut _s, "for");
    ::quote::ToTokens::to_tokens(&df_name, &mut _s);
    ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
    ::quote::ToTokens::to_tokens(&where_clause, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "type");
            ::quote::__private::push_ident(&mut _s, "Error");
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "core");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "convert");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Infallible");
            ::quote::__private::push_semi(&mut _s);
            ::quote::__private::push_pound(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Bracket,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "inline");
                    _s
                });
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "try_into_sexp");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "self");
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "core");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "result");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Result");
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "SEXP");
            ::quote::__private::push_comma(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "core");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "convert");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Infallible");
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "core");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "result");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Result");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Ok");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "self");
                            ::quote::__private::push_dot(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "into_sexp");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                ::quote::__private::TokenStream::new());
                            _s
                        });
                    _s
                });
            ::quote::__private::push_pound(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Bracket,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "inline");
                    _s
                });
            ::quote::__private::push_ident(&mut _s, "unsafe");
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s,
                "try_into_sexp_unchecked");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "self");
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "core");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "result");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Result");
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "SEXP");
            ::quote::__private::push_comma(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "core");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "convert");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Infallible");
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "self");
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "try_into_sexp");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        ::quote::__private::TokenStream::new());
                    _s
                });
            ::quote::__private::push_pound(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Bracket,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "inline");
                    _s
                });
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "into_sexp");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "self");
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "SEXP");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "miniextendr_api");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "convert");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "ColumnSource");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "into_column_list");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "self");
                            _s
                        });
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "into_sexp");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        ::quote::__private::TokenStream::new());
                    _s
                });
            ::quote::__private::push_pound(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Bracket,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "inline");
                    _s
                });
            ::quote::__private::push_ident(&mut _s, "unsafe");
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "into_sexp_unchecked");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "self");
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "SEXP");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "miniextendr_api");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "convert");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "ColumnSource");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "into_column_list");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "self");
                            _s
                        });
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "into_sexp");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        ::quote::__private::TokenStream::new());
                    _s
                });
            _s
        });
    _s
}quote::quote! {
1253        #base
1254
1255        impl #impl_generics ::miniextendr_api::into_r::IntoR for #df_name #ty_generics #where_clause {
1256            type Error = ::core::convert::Infallible;
1257
1258            #[inline]
1259            fn try_into_sexp(self) -> ::core::result::Result<::miniextendr_api::SEXP, ::core::convert::Infallible> {
1260                ::core::result::Result::Ok(self.into_sexp())
1261            }
1262
1263            #[inline]
1264            unsafe fn try_into_sexp_unchecked(self) -> ::core::result::Result<::miniextendr_api::SEXP, ::core::convert::Infallible> {
1265                self.try_into_sexp()
1266            }
1267
1268            #[inline]
1269            fn into_sexp(self) -> ::miniextendr_api::SEXP {
1270                ::miniextendr_api::convert::ColumnSource::into_column_list(self).into_sexp()
1271            }
1272
1273            #[inline]
1274            unsafe fn into_sexp_unchecked(self) -> ::miniextendr_api::SEXP {
1275                ::miniextendr_api::convert::ColumnSource::into_column_list(self).into_sexp()
1276            }
1277        }
1278    })
1279}
1280// endregion
1281
1282// region: Field-type bounds (shared by the struct and enum paths)
1283//
1284// The derive asks of a field type only what turning that field into columns
1285// needs: a column's `IntoR`, `IntoList` for an `as_list` value, `DataFrameRow`
1286// for a flattened struct. Everything else it emits for a field type exists
1287// only where the type allows it: the companion's `Debug` / `Clone`, the rows
1288// iterator that rebuilds `skip` fields with `Default`, and the parallel fill
1289// behind `from_rows_par` carry conditional bounds
1290// (`crate::naming::conditional_bound_lifetime`) instead.
1291
1292/// `where` clause: `where_clause`'s predicates, then `for<'__mx_cond> ty: bound`
1293/// for each `(ty, bound)` pair.
1294pub(super) fn conditional_where(
1295    where_clause: Option<&syn::WhereClause>,
1296    bounds: &[(TokenStream, TokenStream)],
1297) -> TokenStream {
1298    let binder = crate::naming::conditional_bound_lifetime();
1299    let mut preds: Vec<TokenStream> = where_clause
1300        .into_iter()
1301        .flat_map(|wc| wc.predicates.iter())
1302        .map(|p| {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&p, &mut _s);
    _s
}quote! { #p })
1303        .collect();
1304    preds.extend(
1305        bounds
1306            .iter()
1307            .map(|(ty, bound)| {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "for");
    ::quote::__private::push_lt(&mut _s);
    ::quote::ToTokens::to_tokens(&binder, &mut _s);
    ::quote::__private::push_gt(&mut _s);
    ::quote::ToTokens::to_tokens(&ty, &mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::ToTokens::to_tokens(&bound, &mut _s);
    _s
}quote! { for<#binder> #ty: #bound }),
1308    );
1309    if preds.is_empty() {
1310        TokenStream::new()
1311    } else {
1312        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "where");
    {
        use ::quote::__private::ext::*;
        let mut _first = true;
        let has_iter = ::quote::__private::HasIterator::<false>;
        #[allow(unused_mut)]
        let (mut preds, i) = preds.quote_into_iter();
        let has_iter = has_iter | i;
        <_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
        while true {
            let preds =
                match preds.next() {
                    Some(_x) => ::quote::__private::RepInterp(_x),
                    None => break,
                };
            if !_first { ::quote::__private::push_comma(&mut _s); }
            _first = false;
            ::quote::ToTokens::to_tokens(&preds, &mut _s);
        }
    }
    _s
}quote! { where #(#preds),* }
1313    }
1314}
1315
1316/// Keep lifetimes erased by column expansion or skipped fields in the companion.
1317/// Columns that still borrow already carry their lifetimes; only missing ones
1318/// need a marker. This adds no data column or element-type trait requirements.
1319pub(super) fn companion_lifetime_marker(
1320    generics: &syn::Generics,
1321    fields: &mut Vec<(syn::Ident, TokenStream)>,
1322) -> (TokenStream, TokenStream) {
1323    use syn::visit_mut::VisitMut;
1324
1325    struct MissingLifetimes(Vec<syn::Lifetime>);
1326    impl VisitMut for MissingLifetimes {
1327        fn visit_lifetime_mut(&mut self, lifetime: &mut syn::Lifetime) {
1328            self.0.retain(|candidate| candidate.ident != lifetime.ident);
1329        }
1330    }
1331    let mut missing = MissingLifetimes(
1332        generics
1333            .lifetimes()
1334            .map(|param| param.lifetime.clone())
1335            .collect(),
1336    );
1337    for (_, ty) in fields.iter() {
1338        missing.visit_type_mut(&mut syn::parse2::<syn::Type>(ty.clone()).unwrap());
1339    }
1340    if missing.0.is_empty() {
1341        return (TokenStream::new(), TokenStream::new());
1342    }
1343    let lifetimes = missing.0;
1344    let mut name = ::quote::__private::mk_ident(&::alloc::__export::must_use({
                ::alloc::fmt::format(format_args!("__mx_lifetimes"))
            }), ::quote::__private::Option::None)format_ident!("__mx_lifetimes");
1345    while fields.iter().any(|(field, _)| field == &name) {
1346        name = match ::quote::__private::IdentFragmentAdapter(&name) {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("{0}_", arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("{}_", name);
1347    }
1348    let ty = {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "marker");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "PhantomData");
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            {
                use ::quote::__private::ext::*;
                let has_iter = ::quote::__private::HasIterator::<false>;
                #[allow(unused_mut)]
                let (mut lifetimes, i) = lifetimes.quote_into_iter();
                let has_iter = has_iter | i;
                <_ as
                        ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                while true {
                    let lifetimes =
                        match lifetimes.next() {
                            Some(_x) => ::quote::__private::RepInterp(_x),
                            None => break,
                        };
                    ::quote::__private::push_and(&mut _s);
                    ::quote::ToTokens::to_tokens(&lifetimes, &mut _s);
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        ::quote::__private::TokenStream::new());
                    ::quote::__private::push_comma(&mut _s);
                }
            }
            _s
        });
    ::quote::__private::push_gt(&mut _s);
    _s
}quote! { ::core::marker::PhantomData<(#(&#lifetimes (),)*)> };
1349    fields.push((name.clone(), ty.clone()));
1350    (
1351        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::ToTokens::to_tokens(&ty, &mut _s);
    ::quote::__private::push_comma(&mut _s);
    _s
}quote! { #name: #ty, },
1352        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "marker");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "PhantomData");
    ::quote::__private::push_comma(&mut _s);
    _s
}quote! { #name: ::core::marker::PhantomData, },
1353    )
1354}
1355
1356/// `Debug` and `Clone` for a companion, each implemented only when every field
1357/// type has it. `#[derive(Debug, Clone)]` would demand both of every column's
1358/// element type (#2013). `fields` are the companion's fields with their types.
1359pub(super) fn companion_debug_clone(
1360    df_name: &syn::Ident,
1361    generics: &syn::Generics,
1362    fields: &[(syn::Ident, TokenStream)],
1363) -> TokenStream {
1364    let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
1365    let bounds = |bound: TokenStream| -> Vec<(TokenStream, TokenStream)> {
1366        fields
1367            .iter()
1368            .map(|(_, ty)| (ty.clone(), bound.clone()))
1369            .collect()
1370    };
1371    let debug_where = conditional_where(where_clause, &bounds({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "fmt");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Debug");
    _s
}quote! { ::core::fmt::Debug }));
1372    let clone_where = conditional_where(where_clause, &bounds({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "clone");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Clone");
    _s
}quote! { ::core::clone::Clone }));
1373    let df_name_str = df_name.to_string();
1374    let idents: Vec<&syn::Ident> = fields.iter().map(|(ident, _)| ident).collect();
1375    let names: Vec<String> = idents
1376        .iter()
1377        .map(|ident| crate::naming::ident_name(ident))
1378        .collect();
1379    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_pound(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "automatically_derived");
            _s
        });
    ::quote::__private::push_pound(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "allow");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "unused_lifetimes");
                    _s
                });
            _s
        });
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::ToTokens::to_tokens(&impl_generics, &mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "fmt");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Debug");
    ::quote::__private::push_ident(&mut _s, "for");
    ::quote::ToTokens::to_tokens(&df_name, &mut _s);
    ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
    ::quote::ToTokens::to_tokens(&debug_where, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "fmt");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "self");
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "__f");
                    ::quote::__private::push_colon(&mut _s);
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "mut");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "core");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "fmt");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Formatter");
                    ::quote::__private::push_lt(&mut _s);
                    ::quote::__private::push_lifetime(&mut _s, "\'_");
                    ::quote::__private::push_gt(&mut _s);
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "core");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "fmt");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Result");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "__f");
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "debug_struct");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::ToTokens::to_tokens(&df_name_str, &mut _s);
                            _s
                        });
                    {
                        use ::quote::__private::ext::*;
                        let has_iter = ::quote::__private::HasIterator::<false>;
                        #[allow(unused_mut)]
                        let (mut names, i) = names.quote_into_iter();
                        let has_iter = has_iter | i;
                        #[allow(unused_mut)]
                        let (mut idents, i) = idents.quote_into_iter();
                        let has_iter = has_iter | i;
                        <_ as
                                ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                        while true {
                            let names =
                                match names.next() {
                                    Some(_x) => ::quote::__private::RepInterp(_x),
                                    None => break,
                                };
                            let idents =
                                match idents.next() {
                                    Some(_x) => ::quote::__private::RepInterp(_x),
                                    None => break,
                                };
                            ::quote::__private::push_dot(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "field");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::ToTokens::to_tokens(&names, &mut _s);
                                    ::quote::__private::push_comma(&mut _s);
                                    ::quote::__private::push_and(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "self");
                                    ::quote::__private::push_dot(&mut _s);
                                    ::quote::ToTokens::to_tokens(&idents, &mut _s);
                                    _s
                                });
                        }
                    }
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "finish");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        ::quote::__private::TokenStream::new());
                    _s
                });
            _s
        });
    ::quote::__private::push_pound(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "automatically_derived");
            _s
        });
    ::quote::__private::push_pound(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "allow");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "unused_lifetimes");
                    _s
                });
            _s
        });
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::ToTokens::to_tokens(&impl_generics, &mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "clone");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Clone");
    ::quote::__private::push_ident(&mut _s, "for");
    ::quote::ToTokens::to_tokens(&df_name, &mut _s);
    ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
    ::quote::ToTokens::to_tokens(&clone_where, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "clone");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "self");
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Self");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "Self");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Brace,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            {
                                use ::quote::__private::ext::*;
                                let mut _first = true;
                                let has_iter = ::quote::__private::HasIterator::<false>;
                                #[allow(unused_mut)]
                                let (mut idents, i) = idents.quote_into_iter();
                                let has_iter = has_iter | i;
                                #[allow(unused_mut)]
                                let (mut idents, i) = idents.quote_into_iter();
                                let has_iter = has_iter | i;
                                <_ as
                                        ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                                while true {
                                    let idents =
                                        match idents.next() {
                                            Some(_x) => ::quote::__private::RepInterp(_x),
                                            None => break,
                                        };
                                    let idents =
                                        match idents.next() {
                                            Some(_x) => ::quote::__private::RepInterp(_x),
                                            None => break,
                                        };
                                    if !_first { ::quote::__private::push_comma(&mut _s); }
                                    _first = false;
                                    ::quote::ToTokens::to_tokens(&idents, &mut _s);
                                    ::quote::__private::push_colon(&mut _s);
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "core");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "clone");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "Clone");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "clone");
                                    ::quote::__private::push_group(&mut _s,
                                        ::quote::__private::Delimiter::Parenthesis,
                                        {
                                            let mut _s = ::quote::__private::TokenStream::new();
                                            ::quote::__private::push_and(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "self");
                                            ::quote::__private::push_dot(&mut _s);
                                            ::quote::ToTokens::to_tokens(&idents, &mut _s);
                                            _s
                                        });
                                }
                            }
                            _s
                        });
                    _s
                });
            _s
        });
    _s
}quote! {
1380        #[automatically_derived]
1381        #[allow(unused_lifetimes)]
1382        impl #impl_generics ::core::fmt::Debug for #df_name #ty_generics #debug_where {
1383            fn fmt(&self, __f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
1384                __f.debug_struct(#df_name_str)
1385                    #(.field(#names, &self.#idents))*
1386                    .finish()
1387            }
1388        }
1389
1390        #[automatically_derived]
1391        #[allow(unused_lifetimes)]
1392        impl #impl_generics ::core::clone::Clone for #df_name #ty_generics #clone_where {
1393            fn clone(&self) -> Self {
1394                Self { #(#idents: ::core::clone::Clone::clone(&self.#idents)),* }
1395            }
1396        }
1397    }
1398}
1399
1400/// The parallel column fill of a companion: `ParallelColumns` with `body` as
1401/// `from_rows_parallel(rows)`, implemented only where `bounds` hold (see
1402/// `miniextendr_api::dataframe::ParallelColumns`). Emitted only when
1403/// miniextendr-api has `rayon`; pair it with [`from_rows_par_override`].
1404pub(super) fn parallel_columns_impl(
1405    df_name: &syn::Ident,
1406    row_name: &syn::Ident,
1407    generics: &syn::Generics,
1408    bounds: &[(TokenStream, TokenStream)],
1409    body: TokenStream,
1410) -> TokenStream {
1411    let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
1412    let where_tokens = conditional_where(where_clause, bounds);
1413    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "miniextendr_api");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "__dataframe_row_when_rayon");
    ::quote::__private::push_bang(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_pound(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Bracket,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "allow");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "unused_lifetimes");
                            _s
                        });
                    _s
                });
            ::quote::__private::push_ident(&mut _s, "impl");
            ::quote::ToTokens::to_tokens(&impl_generics, &mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "dataframe");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "ParallelColumns");
            ::quote::__private::push_lt(&mut _s);
            ::quote::ToTokens::to_tokens(&row_name, &mut _s);
            ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_ident(&mut _s, "for");
            ::quote::ToTokens::to_tokens(&df_name, &mut _s);
            ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
            ::quote::ToTokens::to_tokens(&where_tokens, &mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "fn");
                    ::quote::__private::push_ident(&mut _s,
                        "from_rows_parallel");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "rows");
                            ::quote::__private::push_colon(&mut _s);
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "std");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "vec");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "Vec");
                            ::quote::__private::push_lt(&mut _s);
                            ::quote::ToTokens::to_tokens(&row_name, &mut _s);
                            ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
                            ::quote::__private::push_gt(&mut _s);
                            _s
                        });
                    ::quote::__private::push_rarrow(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Self");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Brace,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::ToTokens::to_tokens(&body, &mut _s);
                            _s
                        });
                    _s
                });
            _s
        });
    _s
}quote! {
1414        // The `#[cfg(feature = "rayon")]` gate lives on the api-side macro
1415        // (evaluated against miniextendr-api's own features), not here —
1416        // stamping the cfg into the consumer crate trips `unexpected_cfgs`
1417        // wherever the derive is used without a `rayon` feature (#1117).
1418        ::miniextendr_api::__dataframe_row_when_rayon! {
1419            #[allow(unused_lifetimes)]
1420            impl #impl_generics ::miniextendr_api::dataframe::ParallelColumns<#row_name #ty_generics>
1421                for #df_name #ty_generics #where_tokens
1422            {
1423                fn from_rows_parallel(rows: ::std::vec::Vec<#row_name #ty_generics>) -> Self {
1424                    #body
1425                }
1426            }
1427        }
1428    }
1429}
1430
1431/// The `from_rows_par` override of a companion's `ColumnarFrame` impl: the
1432/// companion's `ParallelColumns` impl where it applies, `from_rows` otherwise
1433/// (`miniextendr_api::dataframe::FromRowsParProbe`).
1434pub(super) fn from_rows_par_override(row_ty: TokenStream) -> TokenStream {
1435    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "miniextendr_api");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "__dataframe_row_when_rayon");
    ::quote::__private::push_bang(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_pound(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Bracket,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "allow");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "clippy");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "needless_borrow");
                            _s
                        });
                    _s
                });
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "from_rows_par");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "rows");
                    ::quote::__private::push_colon(&mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "std");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "vec");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Vec");
                    ::quote::__private::push_lt(&mut _s);
                    ::quote::ToTokens::to_tokens(&row_ty, &mut _s);
                    ::quote::__private::push_gt(&mut _s);
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Self");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_pound(&mut _s);
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Bracket,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "allow");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_ident(&mut _s, "unused_imports");
                                    _s
                                });
                            _s
                        });
                    ::quote::__private::push_ident(&mut _s, "use");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "miniextendr_api");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "dataframe");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Brace,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s,
                                "FromRowsParParallel");
                            ::quote::__private::push_ident(&mut _s, "as");
                            ::quote::__private::push_underscore(&mut _s);
                            ::quote::__private::push_comma(&mut _s);
                            ::quote::__private::push_ident(&mut _s,
                                "FromRowsParSequential");
                            ::quote::__private::push_ident(&mut _s, "as");
                            ::quote::__private::push_underscore(&mut _s);
                            ::quote::__private::push_comma(&mut _s);
                            _s
                        });
                    ::quote::__private::push_semi(&mut _s);
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_and(&mut _s);
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "dataframe");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "FromRowsParProbe");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_lt(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "Self");
                            ::quote::__private::push_comma(&mut _s);
                            ::quote::ToTokens::to_tokens(&row_ty, &mut _s);
                            ::quote::__private::push_gt(&mut _s);
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "new");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                ::quote::__private::TokenStream::new());
                            _s
                        });
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "fill_columns");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "rows");
                            _s
                        });
                    _s
                });
            _s
        });
    _s
}quote! {
1436        ::miniextendr_api::__dataframe_row_when_rayon! {
1437            // The explicit borrow is what lets lookup fall back to the
1438            // sequential arm; it is not needless.
1439            #[allow(clippy::needless_borrow)]
1440            fn from_rows_par(rows: ::std::vec::Vec<#row_ty>) -> Self {
1441                #[allow(unused_imports)]
1442                use ::miniextendr_api::dataframe::{
1443                    FromRowsParParallel as _, FromRowsParSequential as _,
1444                };
1445                (&::miniextendr_api::dataframe::FromRowsParProbe::<Self, #row_ty>::new())
1446                    .fill_columns(rows)
1447            }
1448        }
1449    }
1450}
1451
1452/// `<ty as Clone>::clone`, spanned at `ty`: a type without `Clone` is then
1453/// reported at the user's field instead of at the derive.
1454pub(super) fn spanned_clone_fn(ty: &syn::Type) -> TokenStream {
1455    let span = syn::spanned::Spanned::span(ty);
1456    {
    let mut _s = ::quote::__private::TokenStream::new();
    let _span: ::quote::__private::Span =
        ::quote::__private::get_span(span).__into_span();
    ::quote::__private::push_lt_spanned(&mut _s, _span);
    ::quote::ToTokens::to_tokens(&ty, &mut _s);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "as");
    ::quote::__private::push_colon2_spanned(&mut _s, _span);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "core");
    ::quote::__private::push_colon2_spanned(&mut _s, _span);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "clone");
    ::quote::__private::push_colon2_spanned(&mut _s, _span);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "Clone");
    ::quote::__private::push_gt_spanned(&mut _s, _span);
    ::quote::__private::push_colon2_spanned(&mut _s, _span);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "clone");
    _s
}quote_spanned! {span=> <#ty as ::core::clone::Clone>::clone }
1457}
1458
1459/// Bind each element of fixed-array field value `access` to its own variable
1460/// in `elems`: moved out of an owned array (indexing would need `Copy`), cloned
1461/// out of a borrowed one, which is the only way to own an element behind a
1462/// reference.
1463pub(super) fn fixed_array_elems(
1464    access: &TokenStream,
1465    borrowed: bool,
1466    elem_ty: &syn::Type,
1467    elems: &[syn::Ident],
1468) -> TokenStream {
1469    if borrowed {
1470        let clone = spanned_clone_fn(elem_ty);
1471        let lets: Vec<TokenStream> = elems
1472            .iter()
1473            .enumerate()
1474            .map(|(i, elem)| {
1475                let idx = syn::Index::from(i);
1476                {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::ToTokens::to_tokens(&elem, &mut _s);
    ::quote::__private::push_eq(&mut _s);
    ::quote::ToTokens::to_tokens(&clone, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_and(&mut _s);
            ::quote::ToTokens::to_tokens(&access, &mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Bracket,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::ToTokens::to_tokens(&idx, &mut _s);
                    _s
                });
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! { let #elem = #clone(&#access[#idx]); }
1477            })
1478            .collect();
1479        {
    let mut _s = ::quote::__private::TokenStream::new();
    {
        use ::quote::__private::ext::*;
        let has_iter = ::quote::__private::HasIterator::<false>;
        #[allow(unused_mut)]
        let (mut lets, i) = lets.quote_into_iter();
        let has_iter = has_iter | i;
        <_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
        while true {
            let lets =
                match lets.next() {
                    Some(_x) => ::quote::__private::RepInterp(_x),
                    None => break,
                };
            ::quote::ToTokens::to_tokens(&lets, &mut _s);
        }
    }
    _s
}quote! { #(#lets)* }
1480    } else {
1481        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            {
                use ::quote::__private::ext::*;
                let mut _first = true;
                let has_iter = ::quote::__private::HasIterator::<false>;
                #[allow(unused_mut)]
                let (mut elems, i) = elems.quote_into_iter();
                let has_iter = has_iter | i;
                <_ as
                        ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                while true {
                    let elems =
                        match elems.next() {
                            Some(_x) => ::quote::__private::RepInterp(_x),
                            None => break,
                        };
                    if !_first { ::quote::__private::push_comma(&mut _s); }
                    _first = false;
                    ::quote::ToTokens::to_tokens(&elems, &mut _s);
                }
            }
            _s
        });
    ::quote::__private::push_eq(&mut _s);
    ::quote::ToTokens::to_tokens(&access, &mut _s);
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! { let [#(#elems),*] = #access; }
1482    }
1483}
1484
1485/// The elements of an expanded `Vec<T>` / `Box<[T]>` / `&[T]` field value
1486/// `access` as an iterator of owned `T`: moved out of an owned container,
1487/// cloned out of a borrowed slice. `IntoIterator::into_iter` is called by path
1488/// so a `Box<[T]>` iterates by value in every edition.
1489pub(super) fn owned_elems_iter(
1490    access: &TokenStream,
1491    borrowed: bool,
1492    elem_ty: &syn::Type,
1493) -> TokenStream {
1494    if borrowed {
1495        // A closure, not the clone fn itself: the closure is `FnMut` whatever
1496        // `elem_ty` implements, so a missing `Clone` is reported once, at the
1497        // field, instead of again wherever the iterator is used.
1498        let clone = spanned_clone_fn(elem_ty);
1499        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "iter");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Iterator");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "map");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "core");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "iter");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "IntoIterator");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "into_iter");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::ToTokens::to_tokens(&access, &mut _s);
                    _s
                });
            ::quote::__private::push_comma(&mut _s);
            ::quote::__private::push_or(&mut _s);
            ::quote::__private::push_ident(&mut _s, "__mx_elem");
            ::quote::__private::push_colon(&mut _s);
            ::quote::__private::push_and(&mut _s);
            ::quote::ToTokens::to_tokens(&elem_ty, &mut _s);
            ::quote::__private::push_or(&mut _s);
            ::quote::ToTokens::to_tokens(&clone, &mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "__mx_elem");
                    _s
                });
            ::quote::__private::push_comma(&mut _s);
            _s
        });
    _s
}quote! {
1500            ::core::iter::Iterator::map(
1501                ::core::iter::IntoIterator::into_iter(#access),
1502                |__mx_elem: &#elem_ty| #clone(__mx_elem),
1503            )
1504        }
1505    } else {
1506        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "iter");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "IntoIterator");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "into_iter");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::ToTokens::to_tokens(&access, &mut _s);
            _s
        });
    _s
}quote! { ::core::iter::IntoIterator::into_iter(#access) }
1507    }
1508}
1509
1510/// Bind the first `elems.len()` elements of a `width = N` field value `access`
1511/// to `Option<T>` variables (`None` past its end; elements past `N` are
1512/// dropped), through iterator variable `iter`.
1513pub(super) fn width_elems(
1514    access: &TokenStream,
1515    borrowed: bool,
1516    elem_ty: &syn::Type,
1517    iter: &syn::Ident,
1518    elems: &[syn::Ident],
1519) -> TokenStream {
1520    let elems_iter = owned_elems_iter(access, borrowed, elem_ty);
1521    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::__private::push_ident(&mut _s, "mut");
    ::quote::ToTokens::to_tokens(&iter, &mut _s);
    ::quote::__private::push_eq(&mut _s);
    ::quote::ToTokens::to_tokens(&elems_iter, &mut _s);
    ::quote::__private::push_semi(&mut _s);
    {
        use ::quote::__private::ext::*;
        let has_iter = ::quote::__private::HasIterator::<false>;
        #[allow(unused_mut)]
        let (mut elems, i) = elems.quote_into_iter();
        let has_iter = has_iter | i;
        #[allow(unused_mut)]
        let (mut iter, i) = iter.quote_into_iter();
        let has_iter = has_iter | i;
        <_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
        while true {
            let elems =
                match elems.next() {
                    Some(_x) => ::quote::__private::RepInterp(_x),
                    None => break,
                };
            let iter =
                match iter.next() {
                    Some(_x) => ::quote::__private::RepInterp(_x),
                    None => break,
                };
            ::quote::__private::push_ident(&mut _s, "let");
            ::quote::ToTokens::to_tokens(&elems, &mut _s);
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "core");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "iter");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Iterator");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "next");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "mut");
                    ::quote::ToTokens::to_tokens(&iter, &mut _s);
                    _s
                });
            ::quote::__private::push_semi(&mut _s);
        }
    }
    _s
}quote! {
1522        let mut #iter = #elems_iter;
1523        #(let #elems = ::core::iter::Iterator::next(&mut #iter);)*
1524    }
1525}
1526
1527/// The variables [`fixed_array_elems`] / [`width_elems`] bind for the `n`
1528/// columns of the field `key` names. Leading underscores are dropped from `key`
1529/// so the variables stay snake case (`_0` gives `__mxe1_0`).
1530pub(super) fn expanded_elem_idents(key: &str, n: usize) -> Vec<syn::Ident> {
1531    let key = key.trim_start_matches('_');
1532    (1..=n)
1533        .map(|k| match ::quote::__private::IdentFragmentAdapter(&k) {
    arg =>
        match ::quote::__private::IdentFragmentAdapter(&key) {
            arg =>
                ::quote::__private::mk_ident(&::alloc::__export::must_use({
                                ::alloc::fmt::format(format_args!("__mxe{0}_{1}", arg, arg))
                            }),
                    ::quote::__private::Option::None.or(arg.span()).or(arg.span())),
        },
}format_ident!("__mxe{}_{}", k, key))
1534        .collect()
1535}
1536// endregion
1537
1538// region: Struct path (existing logic, extracted)
1539
1540/// Convert a companion column without adding R objects to the companion:
1541/// `as_list` uses the rooted list builder, `as_factor` uses `UnitEnumFactor`,
1542/// and ordinary columns convert the whole `Vec` through `IntoR`.
1543fn column_sexp(
1544    name: &syn::Ident,
1545    ty: &syn::Type,
1546    needs_into_list: bool,
1547    is_factor: bool,
1548) -> TokenStream {
1549    if needs_into_list {
1550        let into_list_column = list_column_fn(ty, false);
1551        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&into_list_column, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "self");
            ::quote::__private::push_dot(&mut _s);
            ::quote::ToTokens::to_tokens(&name, &mut _s);
            _s
        });
    _s
}quote! { #into_list_column(self.#name) }
1552    } else if is_factor {
1553        let span = syn::spanned::Spanned::span(ty);
1554        {
    let mut _s = ::quote::__private::TokenStream::new();
    let _span: ::quote::__private::Span =
        ::quote::__private::get_span(span).__into_span();
    ::quote::__private::push_colon2_spanned(&mut _s, _span);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "miniextendr_api");
    ::quote::__private::push_colon2_spanned(&mut _s, _span);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "IntoR");
    ::quote::__private::push_colon2_spanned(&mut _s, _span);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "into_sexp");
    ::quote::__private::push_group_spanned(&mut _s, _span,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            let _span: ::quote::__private::Span =
                ::quote::__private::get_span(_span).__into_span();
            ::quote::__private::push_colon2_spanned(&mut _s, _span);
            ::quote::__private::push_ident_spanned(&mut _s, _span,
                "miniextendr_api");
            ::quote::__private::push_colon2_spanned(&mut _s, _span);
            ::quote::__private::push_ident_spanned(&mut _s, _span, "factor");
            ::quote::__private::push_colon2_spanned(&mut _s, _span);
            ::quote::__private::push_ident_spanned(&mut _s, _span,
                "FactorVec");
            ::quote::__private::push_colon2_spanned(&mut _s, _span);
            ::quote::__private::push_lt_spanned(&mut _s, _span);
            ::quote::ToTokens::to_tokens(&ty, &mut _s);
            ::quote::__private::push_gt_spanned(&mut _s, _span);
            ::quote::__private::push_colon2_spanned(&mut _s, _span);
            ::quote::__private::push_ident_spanned(&mut _s, _span, "from");
            ::quote::__private::push_group_spanned(&mut _s, _span,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    let _span: ::quote::__private::Span =
                        ::quote::__private::get_span(_span).__into_span();
                    ::quote::__private::push_ident_spanned(&mut _s, _span,
                        "self");
                    ::quote::__private::push_dot_spanned(&mut _s, _span);
                    ::quote::ToTokens::to_tokens(&name, &mut _s);
                    _s
                });
            _s
        });
    _s
}quote_spanned! {span=>
1555            ::miniextendr_api::IntoR::into_sexp(
1556                ::miniextendr_api::factor::FactorVec::<#ty>::from(self.#name)
1557            )
1558        }
1559    } else {
1560        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "miniextendr_api");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "IntoR");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "into_sexp");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "self");
            ::quote::__private::push_dot(&mut _s);
            ::quote::ToTokens::to_tokens(&name, &mut _s);
            _s
        });
    _s
}quote! { ::miniextendr_api::IntoR::into_sexp(self.#name) }
1561    }
1562}
1563
1564/// `into_list_column::<#ty>` (or `into_option_list_column::<#ty>`, for a column
1565/// with absent rows), spanned at the field type: a type without `IntoList` is
1566/// then reported at the field instead of at the derive.
1567pub(super) fn list_column_fn(ty: &syn::Type, optional: bool) -> TokenStream {
1568    let span = syn::spanned::Spanned::span(ty);
1569    let name = if optional {
1570        "into_option_list_column"
1571    } else {
1572        "into_list_column"
1573    };
1574    let func = syn::Ident::new(name, span);
1575    {
    let mut _s = ::quote::__private::TokenStream::new();
    let _span: ::quote::__private::Span =
        ::quote::__private::get_span(span).__into_span();
    ::quote::__private::push_colon2_spanned(&mut _s, _span);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "miniextendr_api");
    ::quote::__private::push_colon2_spanned(&mut _s, _span);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "list");
    ::quote::__private::push_colon2_spanned(&mut _s, _span);
    ::quote::ToTokens::to_tokens(&func, &mut _s);
    ::quote::__private::push_colon2_spanned(&mut _s, _span);
    ::quote::__private::push_lt_spanned(&mut _s, _span);
    ::quote::ToTokens::to_tokens(&ty, &mut _s);
    ::quote::__private::push_gt_spanned(&mut _s, _span);
    _s
}quote_spanned! {span=> ::miniextendr_api::list::#func::<#ty> }
1576}
1577
1578/// Generate `DataFrameRow` expansion for struct types.
1579///
1580/// Produces:
1581/// - A companion struct `{Name}DataFrame` with `Vec<T>` columns
1582/// - `impl IntoDataFrame for {Name}DataFrame`
1583/// - `impl From<Vec<{Name}>> for {Name}DataFrame`
1584/// - `impl IntoIterator` (for named structs without expansion)
1585/// - Associated methods: `to_dataframe`, `from_dataframe`, `from_rows`, `from_rows_par`
1586///
1587/// Handles fixed-array expansion (`[T; N]`), pinned-width Vec expansion
1588/// (`Vec<T>` + `width`), and auto-expand Vec (`Vec<T>` + `expand`).
1589fn derive_struct_dataframe(
1590    row_name: &syn::Ident,
1591    input: &DeriveInput,
1592    data: &syn::DataStruct,
1593    df_name: &syn::Ident,
1594    attrs: &DataFrameAttrs,
1595) -> syn::Result<TokenStream> {
1596    let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
1597    // The companion and its row iterator take the row struct's visibility: their
1598    // `IntoIterator` / `Iterator` impls name the row type as `Item`, so a `pub`
1599    // companion over a private row is E0446 ("private type in public interface").
1600    let vis = &input.vis;
1601
1602    let is_tuple_struct = #[allow(non_exhaustive_omitted_patterns)] match &data.fields {
    Fields::Unnamed(_) => true,
    _ => false,
}matches!(&data.fields, Fields::Unnamed(_));
1603    let is_unit_struct = #[allow(non_exhaustive_omitted_patterns)] match &data.fields {
    Fields::Unit => true,
    _ => false,
}matches!(&data.fields, Fields::Unit);
1604
1605    // Resolve fields through the new FieldAttrs + type classification system.
1606    let resolved: Vec<ResolvedField> = match &data.fields {
1607        Fields::Named(fields) => {
1608            let mut out = Vec::new();
1609            for (i, f) in fields.named.iter().enumerate() {
1610                if let Some(rf) = resolve_struct_field(f, i, false)? {
1611                    out.push(rf);
1612                }
1613            }
1614            out
1615        }
1616        Fields::Unnamed(fields) => {
1617            let mut out = Vec::new();
1618            for (i, f) in fields.unnamed.iter().enumerate() {
1619                if let Some(rf) = resolve_struct_field(f, i, true)? {
1620                    out.push(rf);
1621                }
1622            }
1623            out
1624        }
1625        Fields::Unit => ::alloc::vec::Vec::new()vec![],
1626    };
1627
1628    // Check whether any field uses expansion — affects whether we can generate
1629    // IntoIterator (expanded fields change the companion struct shape).
1630    let has_expansion = resolved
1631        .iter()
1632        .any(|rf| !#[allow(non_exhaustive_omitted_patterns)] match rf {
    ResolvedField::Single(..) => true,
    _ => false,
}matches!(rf, ResolvedField::Single(..)));
1633    // Track which Rust fields were skipped, with their types (for destructure
1634    // patterns and the rows iterator's `Default` bounds).
1635    let skipped_fields: Vec<(syn::Ident, syn::Type)> = match &data.fields {
1636        Fields::Named(fields) => fields
1637            .named
1638            .iter()
1639            .filter_map(|f| {
1640                let fa = parse_field_attrs(f).ok()?;
1641                if fa.skip {
1642                    Some((f.ident.as_ref().unwrap().clone(), f.ty.clone()))
1643                } else {
1644                    None
1645                }
1646            })
1647            .collect(),
1648        _ => ::alloc::vec::Vec::new()vec![],
1649    };
1650
1651    let has_tag = attrs.tag.is_some();
1652    let row_name_str = row_name.to_string();
1653
1654    // region: Build flat column lists from resolved fields
1655    // Each resolved field may produce 1..N columns.
1656    struct FlatCol {
1657        /// Companion struct field name.
1658        df_field: syn::Ident,
1659        /// Column name string in the R data frame.
1660        col_name_str: String,
1661        /// Type of the companion Vec<T>.
1662        vec_elem_ty: syn::Type,
1663        /// `#[dataframe(as_list)]` on a struct-typed field — companion stores
1664        /// the struct values, converted to a list-column at frame assembly.
1665        /// The `from_rows_par` pre-pass clones these sequentially instead of
1666        /// scatter-writing (the struct need not implement `Default`).
1667        needs_into_list: bool,
1668        /// Convert this column through `UnitEnumFactor`.
1669        is_factor: bool,
1670    }
1671
1672    let mut flat_cols: Vec<FlatCol> = Vec::new();
1673
1674    for rf in &resolved {
1675        match rf {
1676            ResolvedField::Single(data) => {
1677                flat_cols.push(FlatCol {
1678                    df_field: data.col_name.clone(),
1679                    col_name_str: data.col_name_str.clone(),
1680                    vec_elem_ty: data.ty.clone(),
1681                    needs_into_list: data.needs_into_list,
1682                    is_factor: data.is_factor,
1683                });
1684            }
1685            ResolvedField::ExpandedFixed(data) => {
1686                for i in 1..=data.len {
1687                    let name = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}_{1}", data.base_name, i))
    })format!("{}_{}", data.base_name, i);
1688                    flat_cols.push(FlatCol {
1689                        df_field: match ::quote::__private::IdentFragmentAdapter(&data.base_name) {
    arg =>
        match ::quote::__private::IdentFragmentAdapter(&i) {
            arg =>
                ::quote::__private::mk_ident(&::alloc::__export::must_use({
                                ::alloc::fmt::format(format_args!("{0}_{1}", arg, arg))
                            }),
                    ::quote::__private::Option::None.or(arg.span()).or(arg.span())),
        },
}format_ident!("{}_{}", data.base_name, i),
1690                        col_name_str: name,
1691                        vec_elem_ty: data.elem_ty.clone(),
1692                        needs_into_list: false,
1693                        is_factor: false,
1694                    });
1695                }
1696            }
1697            ResolvedField::ExpandedVec(data) => {
1698                for i in 1..=data.width {
1699                    let name = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}_{1}", data.base_name, i))
    })format!("{}_{}", data.base_name, i);
1700                    let elem_ty = &data.elem_ty;
1701                    let opt_ty: syn::Type = ::syn::__private::parse_quote({
        let mut _s = ::quote::__private::TokenStream::new();
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "core");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "option");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "Option");
        ::quote::__private::push_lt(&mut _s);
        ::quote::ToTokens::to_tokens(&elem_ty, &mut _s);
        ::quote::__private::push_gt(&mut _s);
        _s
    })syn::parse_quote!(::core::option::Option<#elem_ty>);
1702                    flat_cols.push(FlatCol {
1703                        df_field: match ::quote::__private::IdentFragmentAdapter(&data.base_name) {
    arg =>
        match ::quote::__private::IdentFragmentAdapter(&i) {
            arg =>
                ::quote::__private::mk_ident(&::alloc::__export::must_use({
                                ::alloc::fmt::format(format_args!("{0}_{1}", arg, arg))
                            }),
                    ::quote::__private::Option::None.or(arg.span()).or(arg.span())),
        },
}format_ident!("{}_{}", data.base_name, i),
1704                        col_name_str: name,
1705                        vec_elem_ty: opt_ty,
1706                        needs_into_list: false,
1707                        is_factor: false,
1708                    });
1709                }
1710            }
1711            // AutoExpandVec / Struct do not produce FlatCols — handled separately.
1712            ResolvedField::AutoExpandVec(..) | ResolvedField::Struct(..) => {}
1713            // Map (#919): two parallel list-columns `<base>_keys` / `<base>_values`.
1714            // Each is a `Vec<Vec<K>>` / `Vec<Vec<V>>` (VECSXP of typed vectors).
1715            ResolvedField::Map(data) => {
1716                let keys_col_name = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}_keys", data.base_name))
    })format!("{}_keys", data.base_name);
1717                let vals_col_name = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}_values", data.base_name))
    })format!("{}_values", data.base_name);
1718                let key_ty = &data.key_ty;
1719                let val_ty = &data.val_ty;
1720                let keys_vec_ty: syn::Type = ::syn::__private::parse_quote({
        let mut _s = ::quote::__private::TokenStream::new();
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "std");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "vec");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "Vec");
        ::quote::__private::push_lt(&mut _s);
        ::quote::ToTokens::to_tokens(&key_ty, &mut _s);
        ::quote::__private::push_gt(&mut _s);
        _s
    })syn::parse_quote!(::std::vec::Vec<#key_ty>);
1721                let vals_vec_ty: syn::Type = ::syn::__private::parse_quote({
        let mut _s = ::quote::__private::TokenStream::new();
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "std");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "vec");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "Vec");
        ::quote::__private::push_lt(&mut _s);
        ::quote::ToTokens::to_tokens(&val_ty, &mut _s);
        ::quote::__private::push_gt(&mut _s);
        _s
    })syn::parse_quote!(::std::vec::Vec<#val_ty>);
1722                flat_cols.push(FlatCol {
1723                    df_field: match ::quote::__private::IdentFragmentAdapter(&data.base_name) {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("{0}_keys", arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("{}_keys", data.base_name),
1724                    col_name_str: keys_col_name,
1725                    vec_elem_ty: keys_vec_ty,
1726                    needs_into_list: false,
1727                    is_factor: false,
1728                });
1729                flat_cols.push(FlatCol {
1730                    df_field: match ::quote::__private::IdentFragmentAdapter(&data.base_name) {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("{0}_values", arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("{}_values", data.base_name),
1731                    col_name_str: vals_col_name,
1732                    vec_elem_ty: vals_vec_ty,
1733                    needs_into_list: false,
1734                    is_factor: false,
1735                });
1736            }
1737        }
1738    }
1739    // endregion
1740
1741    // region: Collect auto-expand fields
1742    struct AutoExpandCol {
1743        /// Companion struct field name.
1744        df_field: syn::Ident,
1745        /// Container type (Vec<T> or Box<[T]>).
1746        container_ty: syn::Type,
1747    }
1748
1749    let auto_expand_cols: Vec<AutoExpandCol> = resolved
1750        .iter()
1751        .filter_map(|rf| {
1752            if let ResolvedField::AutoExpandVec(data) = rf {
1753                Some(AutoExpandCol {
1754                    df_field: crate::naming::name_ident(&data.col_name_str),
1755                    container_ty: data.container_ty.clone(),
1756                })
1757            } else {
1758                None
1759            }
1760        })
1761        .collect();
1762    let has_auto_expand = !auto_expand_cols.is_empty();
1763    // endregion
1764
1765    // region: Collect struct (DataFrameRow-flattened) fields (#485)
1766    //
1767    // Only the codegen-time bits are mirrored here — `rust_name` / `tuple_index`
1768    // are read directly off `ResolvedField::Struct` at the per-row pushes site.
1769    struct StructCol {
1770        df_field: syn::Ident,
1771        col_name_str: String,
1772        inner_ty: syn::Type,
1773    }
1774
1775    let struct_cols: Vec<StructCol> = resolved
1776        .iter()
1777        .filter_map(|rf| {
1778            if let ResolvedField::Struct(data) = rf {
1779                Some(StructCol {
1780                    df_field: data.col_name.clone(),
1781                    col_name_str: data.col_name_str.clone(),
1782                    inner_ty: data.inner_ty.clone(),
1783                })
1784            } else {
1785                None
1786            }
1787        })
1788        .collect();
1789    let has_struct = !struct_cols.is_empty();
1790
1791    // Any `#[dataframe(as_list)]` on a struct-typed field (#485 opt-out) keeps
1792    // the struct in the companion and becomes a list-column only at frame
1793    // assembly. The struct need not implement `Default`, so several codegen
1794    // branches special-case it: IntoIterator generation is skipped, and
1795    // `from_rows_par` fills the column in a sequential pre-pass.
1796    let has_into_list_struct = resolved
1797        .iter()
1798        .any(|rf| #[allow(non_exhaustive_omitted_patterns)] match rf {
    ResolvedField::Single(d) if d.needs_into_list => true,
    _ => false,
}matches!(rf, ResolvedField::Single(d) if d.needs_into_list));
1799    // endregion
1800
1801    // region: Companion struct
1802    let tag_field_decl = if has_tag {
1803        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "pub");
    ::quote::__private::push_ident(&mut _s, "_tag");
    ::quote::__private::push_colon(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "string");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "String");
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_comma(&mut _s);
    _s
}quote! { pub _tag: ::std::vec::Vec<::std::string::String>, }
1804    } else {
1805        TokenStream::new()
1806    };
1807
1808    // The column fields with their types: declared below, and bounding the
1809    // companion's conditional `Debug` / `Clone`.
1810    let mut column_fields: Vec<(syn::Ident, TokenStream)> = flat_cols
1811        .iter()
1812        .map(|fc| {
1813            let ty = &fc.vec_elem_ty;
1814            (fc.df_field.clone(), {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_lt(&mut _s);
    ::quote::ToTokens::to_tokens(&ty, &mut _s);
    ::quote::__private::push_gt(&mut _s);
    _s
}quote! { ::std::vec::Vec<#ty> })
1815        })
1816        .collect();
1817    for ac in &auto_expand_cols {
1818        let cty = &ac.container_ty;
1819        column_fields.push((ac.df_field.clone(), {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_lt(&mut _s);
    ::quote::ToTokens::to_tokens(&cty, &mut _s);
    ::quote::__private::push_gt(&mut _s);
    _s
}quote! { ::std::vec::Vec<#cty> }));
1820    }
1821    for sc in &struct_cols {
1822        let ity = &sc.inner_ty;
1823        column_fields.push((sc.df_field.clone(), {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_lt(&mut _s);
    ::quote::ToTokens::to_tokens(&ity, &mut _s);
    ::quote::__private::push_gt(&mut _s);
    _s
}quote! { ::std::vec::Vec<#ity> }));
1824    }
1825    let df_fields_tokens: Vec<TokenStream> = column_fields
1826        .iter()
1827        .map(|(name, ty)| {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "pub");
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::ToTokens::to_tokens(&ty, &mut _s);
    _s
}quote! { pub #name: #ty })
1828        .collect();
1829
1830    let has_len_field =
1831        flat_cols.is_empty() && auto_expand_cols.is_empty() && struct_cols.is_empty() && !has_tag;
1832    let len_field_decl = if has_len_field {
1833        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "pub");
    ::quote::__private::push_ident(&mut _s, "_len");
    ::quote::__private::push_colon(&mut _s);
    ::quote::__private::push_ident(&mut _s, "usize");
    ::quote::__private::push_comma(&mut _s);
    _s
}quote! { pub _len: usize, }
1834    } else {
1835        TokenStream::new()
1836    };
1837
1838    let mut companion_fields: Vec<(syn::Ident, TokenStream)> = Vec::new();
1839    if has_tag {
1840        companion_fields.push((
1841            ::quote::__private::mk_ident(&::alloc::__export::must_use({
                ::alloc::fmt::format(format_args!("_tag"))
            }), ::quote::__private::Option::None)format_ident!("_tag"),
1842            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "string");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "String");
    ::quote::__private::push_gt(&mut _s);
    _s
}quote! { ::std::vec::Vec<::std::string::String> },
1843        ));
1844    }
1845    if has_len_field {
1846        companion_fields.push((::quote::__private::mk_ident(&::alloc::__export::must_use({
                ::alloc::fmt::format(format_args!("_len"))
            }), ::quote::__private::Option::None)format_ident!("_len"), {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "usize");
    _s
}quote! { usize }));
1847    }
1848    companion_fields.extend(column_fields);
1849    let (phantom_field, phantom_init) =
1850        companion_lifetime_marker(&input.generics, &mut companion_fields);
1851    let companion_debug_clone = companion_debug_clone(df_name, &input.generics, &companion_fields);
1852
1853    let dataframe_struct = {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&vis, &mut _s);
    ::quote::__private::push_ident(&mut _s, "struct");
    ::quote::ToTokens::to_tokens(&df_name, &mut _s);
    ::quote::ToTokens::to_tokens(&impl_generics, &mut _s);
    ::quote::ToTokens::to_tokens(&where_clause, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::ToTokens::to_tokens(&tag_field_decl, &mut _s);
            ::quote::ToTokens::to_tokens(&len_field_decl, &mut _s);
            ::quote::ToTokens::to_tokens(&phantom_field, &mut _s);
            {
                use ::quote::__private::ext::*;
                let mut _first = true;
                let has_iter = ::quote::__private::HasIterator::<false>;
                #[allow(unused_mut)]
                let (mut df_fields_tokens, i) =
                    df_fields_tokens.quote_into_iter();
                let has_iter = has_iter | i;
                <_ as
                        ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                while true {
                    let df_fields_tokens =
                        match df_fields_tokens.next() {
                            Some(_x) => ::quote::__private::RepInterp(_x),
                            None => break,
                        };
                    if !_first { ::quote::__private::push_comma(&mut _s); }
                    _first = false;
                    ::quote::ToTokens::to_tokens(&df_fields_tokens, &mut _s);
                }
            }
            _s
        });
    ::quote::ToTokens::to_tokens(&companion_debug_clone, &mut _s);
    _s
}quote! {
1854        #vis struct #df_name #impl_generics #where_clause {
1855            #tag_field_decl
1856            #len_field_decl
1857            #phantom_field
1858            #(#df_fields_tokens),*
1859        }
1860
1861        #companion_debug_clone
1862    };
1863    // endregion
1864
1865    // region: IntoDataFrame
1866    let length_ref = if has_tag {
1867        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "self");
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "_tag");
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "len");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    _s
}quote! { self._tag.len() }
1868    } else if !flat_cols.is_empty() {
1869        let first = &flat_cols[0].df_field;
1870        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "self");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&first, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "len");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    _s
}quote! { self.#first.len() }
1871    } else if !auto_expand_cols.is_empty() {
1872        let first = &auto_expand_cols[0].df_field;
1873        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "self");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&first, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "len");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    _s
}quote! { self.#first.len() }
1874    } else if !struct_cols.is_empty() {
1875        let first = &struct_cols[0].df_field;
1876        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "self");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&first, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "len");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    _s
}quote! { self.#first.len() }
1877    } else {
1878        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "self");
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "_len");
    _s
}quote! { self._len }
1879    };
1880
1881    // Each pair protects its SEXP via `__scope.protect_raw` so previously-built
1882    // column SEXPs survive subsequent column allocations. Pre-fix the raw
1883    // `vec![(name, into_sexp(...)), ...]` left every SEXP unrooted across the
1884    // next column's allocations — UAF under gctorture
1885    // (reviews/2026-05-07-gctorture-audit.md).
1886    let tag_pair = if let Some(ref tag_name) = attrs.tag {
1887        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::ToTokens::to_tokens(&tag_name, &mut _s);
            ::quote::__private::push_comma(&mut _s);
            ::quote::__private::push_ident(&mut _s, "__scope");
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "protect_raw");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "miniextendr_api");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "IntoR");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "into_sexp");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "self");
                            ::quote::__private::push_dot(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "_tag");
                            _s
                        });
                    _s
                });
            _s
        });
    ::quote::__private::push_comma(&mut _s);
    _s
}quote! { (#tag_name, __scope.protect_raw(::miniextendr_api::IntoR::into_sexp(self._tag))), }
1888    } else {
1889        TokenStream::new()
1890    };
1891
1892    let df_pairs: Vec<TokenStream> = flat_cols
1893        .iter()
1894        .map(|fc| {
1895            let name = &fc.df_field;
1896            let name_str = &fc.col_name_str;
1897            let column = column_sexp(name, &fc.vec_elem_ty, fc.needs_into_list, fc.is_factor);
1898            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::ToTokens::to_tokens(&name_str, &mut _s);
            ::quote::__private::push_comma(&mut _s);
            ::quote::__private::push_ident(&mut _s, "__scope");
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "protect_raw");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::ToTokens::to_tokens(&column, &mut _s);
                    _s
                });
            _s
        });
    _s
}quote! { (#name_str, __scope.protect_raw(#column)) }
1899        })
1900        .collect();
1901
1902    let mut length_checks: Vec<TokenStream> = flat_cols
1903        .iter()
1904        .map(|fc| {
1905            let name = &fc.df_field;
1906            let name_str = &fc.col_name_str;
1907            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "assert");
    ::quote::__private::push_bang(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "self");
            ::quote::__private::push_dot(&mut _s);
            ::quote::ToTokens::to_tokens(&name, &mut _s);
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "len");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            ::quote::__private::push_eq_eq(&mut _s);
            ::quote::__private::push_ident(&mut _s, "_n_rows");
            ::quote::__private::push_comma(&mut _s);
            ::quote::__private::parse(&mut _s,
                "\"column length mismatch in {}: column `{}` has length {} but expected {}\"");
            ::quote::__private::push_comma(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "core");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "stringify");
            ::quote::__private::push_bang(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::ToTokens::to_tokens(&df_name, &mut _s);
                    _s
                });
            ::quote::__private::push_comma(&mut _s);
            ::quote::ToTokens::to_tokens(&name_str, &mut _s);
            ::quote::__private::push_comma(&mut _s);
            ::quote::__private::push_ident(&mut _s, "self");
            ::quote::__private::push_dot(&mut _s);
            ::quote::ToTokens::to_tokens(&name, &mut _s);
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "len");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            ::quote::__private::push_comma(&mut _s);
            ::quote::__private::push_ident(&mut _s, "_n_rows");
            ::quote::__private::push_comma(&mut _s);
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! {
1908                ::core::assert!(
1909                    self.#name.len() == _n_rows,
1910                    "column length mismatch in {}: column `{}` has length {} but expected {}",
1911                    ::core::stringify!(#df_name),
1912                    #name_str,
1913                    self.#name.len(),
1914                    _n_rows,
1915                );
1916            }
1917        })
1918        .collect();
1919    for sc in &struct_cols {
1920        let name = &sc.df_field;
1921        let name_str = &sc.col_name_str;
1922        length_checks.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "assert");
    ::quote::__private::push_bang(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "self");
            ::quote::__private::push_dot(&mut _s);
            ::quote::ToTokens::to_tokens(&name, &mut _s);
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "len");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            ::quote::__private::push_eq_eq(&mut _s);
            ::quote::__private::push_ident(&mut _s, "_n_rows");
            ::quote::__private::push_comma(&mut _s);
            ::quote::__private::parse(&mut _s,
                "\"column length mismatch in {}: struct column `{}` has length {} but expected {}\"");
            ::quote::__private::push_comma(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "core");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "stringify");
            ::quote::__private::push_bang(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::ToTokens::to_tokens(&df_name, &mut _s);
                    _s
                });
            ::quote::__private::push_comma(&mut _s);
            ::quote::ToTokens::to_tokens(&name_str, &mut _s);
            ::quote::__private::push_comma(&mut _s);
            ::quote::__private::push_ident(&mut _s, "self");
            ::quote::__private::push_dot(&mut _s);
            ::quote::ToTokens::to_tokens(&name, &mut _s);
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "len");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            ::quote::__private::push_comma(&mut _s);
            ::quote::__private::push_ident(&mut _s, "_n_rows");
            ::quote::__private::push_comma(&mut _s);
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! {
1923            ::core::assert!(
1924                self.#name.len() == _n_rows,
1925                "column length mismatch in {}: struct column `{}` has length {} but expected {}",
1926                ::core::stringify!(#df_name),
1927                #name_str,
1928                self.#name.len(),
1929                _n_rows,
1930            );
1931        });
1932    }
1933
1934    let into_dataframe_impl = if has_auto_expand || has_struct {
1935        // Dynamic pair building: iterate resolved fields in order,
1936        // emitting static pairs for flat columns and runtime-expanded
1937        // pairs for auto-expand fields.
1938        let tag_push_pair = if let Some(ref tag_name) = attrs.tag {
1939            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "__df_pairs");
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "push");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::ToTokens::to_tokens(&tag_name, &mut _s);
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "to_string");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        ::quote::__private::TokenStream::new());
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "__scope");
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "protect_raw");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "IntoR");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "into_sexp");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_ident(&mut _s, "self");
                                    ::quote::__private::push_dot(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "_tag");
                                    _s
                                });
                            _s
                        });
                    _s
                });
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! {
1940                __df_pairs.push((#tag_name.to_string(), __scope.protect_raw(::miniextendr_api::IntoR::into_sexp(self._tag))));
1941            }
1942        } else {
1943            TokenStream::new()
1944        };
1945
1946        let pair_pushes: Vec<TokenStream> = resolved
1947            .iter()
1948            .map(|rf| match rf {
1949                ResolvedField::Single(data) => {
1950                    let col_name = &data.col_name;
1951                    let col_name_str = &data.col_name_str;
1952                    let column = column_sexp(col_name, &data.ty, data.needs_into_list, data.is_factor);
1953                    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "__df_pairs");
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "push");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::ToTokens::to_tokens(&col_name_str, &mut _s);
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "to_string");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        ::quote::__private::TokenStream::new());
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "__scope");
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "protect_raw");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::ToTokens::to_tokens(&column, &mut _s);
                            _s
                        });
                    ::quote::__private::push_comma(&mut _s);
                    _s
                });
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! {
1954                        __df_pairs.push((
1955                            #col_name_str.to_string(),
1956                            __scope.protect_raw(#column),
1957                        ));
1958                    }
1959                }
1960                ResolvedField::ExpandedFixed(data) => {
1961                    let pushes: Vec<TokenStream> = (1..=data.len)
1962                        .map(|i| {
1963                            let name = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}_{1}", data.base_name, i))
    })format!("{}_{}", data.base_name, i);
1964                            let ident = match ::quote::__private::IdentFragmentAdapter(&data.base_name) {
    arg =>
        match ::quote::__private::IdentFragmentAdapter(&i) {
            arg =>
                ::quote::__private::mk_ident(&::alloc::__export::must_use({
                                ::alloc::fmt::format(format_args!("{0}_{1}", arg, arg))
                            }),
                    ::quote::__private::Option::None.or(arg.span()).or(arg.span())),
        },
}format_ident!("{}_{}", data.base_name, i);
1965                            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "__df_pairs");
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "push");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::ToTokens::to_tokens(&name, &mut _s);
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "to_string");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        ::quote::__private::TokenStream::new());
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "__scope");
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "protect_raw");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "IntoR");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "into_sexp");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_ident(&mut _s, "self");
                                    ::quote::__private::push_dot(&mut _s);
                                    ::quote::ToTokens::to_tokens(&ident, &mut _s);
                                    _s
                                });
                            _s
                        });
                    ::quote::__private::push_comma(&mut _s);
                    _s
                });
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! {
1966                                __df_pairs.push((
1967                                    #name.to_string(),
1968                                    __scope.protect_raw(::miniextendr_api::IntoR::into_sexp(self.#ident)),
1969                                ));
1970                            }
1971                        })
1972                        .collect();
1973                    {
    let mut _s = ::quote::__private::TokenStream::new();
    {
        use ::quote::__private::ext::*;
        let has_iter = ::quote::__private::HasIterator::<false>;
        #[allow(unused_mut)]
        let (mut pushes, i) = pushes.quote_into_iter();
        let has_iter = has_iter | i;
        <_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
        while true {
            let pushes =
                match pushes.next() {
                    Some(_x) => ::quote::__private::RepInterp(_x),
                    None => break,
                };
            ::quote::ToTokens::to_tokens(&pushes, &mut _s);
        }
    }
    _s
}quote! { #(#pushes)* }
1974                }
1975                ResolvedField::ExpandedVec(data) => {
1976                    let pushes: Vec<TokenStream> = (1..=data.width)
1977                        .map(|i| {
1978                            let name = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}_{1}", data.base_name, i))
    })format!("{}_{}", data.base_name, i);
1979                            let ident = match ::quote::__private::IdentFragmentAdapter(&data.base_name) {
    arg =>
        match ::quote::__private::IdentFragmentAdapter(&i) {
            arg =>
                ::quote::__private::mk_ident(&::alloc::__export::must_use({
                                ::alloc::fmt::format(format_args!("{0}_{1}", arg, arg))
                            }),
                    ::quote::__private::Option::None.or(arg.span()).or(arg.span())),
        },
}format_ident!("{}_{}", data.base_name, i);
1980                            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "__df_pairs");
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "push");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::ToTokens::to_tokens(&name, &mut _s);
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "to_string");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        ::quote::__private::TokenStream::new());
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "__scope");
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "protect_raw");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "IntoR");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "into_sexp");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_ident(&mut _s, "self");
                                    ::quote::__private::push_dot(&mut _s);
                                    ::quote::ToTokens::to_tokens(&ident, &mut _s);
                                    _s
                                });
                            _s
                        });
                    ::quote::__private::push_comma(&mut _s);
                    _s
                });
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! {
1981                                __df_pairs.push((
1982                                    #name.to_string(),
1983                                    __scope.protect_raw(::miniextendr_api::IntoR::into_sexp(self.#ident)),
1984                                ));
1985                            }
1986                        })
1987                        .collect();
1988                    {
    let mut _s = ::quote::__private::TokenStream::new();
    {
        use ::quote::__private::ext::*;
        let has_iter = ::quote::__private::HasIterator::<false>;
        #[allow(unused_mut)]
        let (mut pushes, i) = pushes.quote_into_iter();
        let has_iter = has_iter | i;
        <_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
        while true {
            let pushes =
                match pushes.next() {
                    Some(_x) => ::quote::__private::RepInterp(_x),
                    None => break,
                };
            ::quote::ToTokens::to_tokens(&pushes, &mut _s);
        }
    }
    _s
}quote! { #(#pushes)* }
1989                }
1990                ResolvedField::AutoExpandVec(data) => {
1991                    let col_name = &data.col_name;
1992                    let col_name_str = &data.col_name_str;
1993                    let elem_ty = &data.elem_ty;
1994                    let elems_iter =
1995                        owned_elems_iter(&{
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "__row_vec");
    _s
}quote! { __row_vec }, data.borrowed, elem_ty);
1996                    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "let");
            ::quote::__private::push_ident(&mut _s, "__auto");
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::push_ident(&mut _s, "self");
            ::quote::__private::push_dot(&mut _s);
            ::quote::ToTokens::to_tokens(&col_name, &mut _s);
            ::quote::__private::push_semi(&mut _s);
            ::quote::__private::push_ident(&mut _s, "let");
            ::quote::__private::push_ident(&mut _s, "__max");
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::push_ident(&mut _s, "__auto");
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "iter");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "map");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_or(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "v");
                    ::quote::__private::push_or(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "v");
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "len");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        ::quote::__private::TokenStream::new());
                    _s
                });
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "max");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "unwrap_or");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::parse(&mut _s, "0");
                    _s
                });
            ::quote::__private::push_semi(&mut _s);
            ::quote::__private::push_ident(&mut _s, "let");
            ::quote::__private::push_ident(&mut _s, "mut");
            ::quote::__private::push_ident(&mut _s, "__cols");
            ::quote::__private::push_colon(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "std");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "vec");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Vec");
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "std");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "vec");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Vec");
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "core");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "option");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Option");
            ::quote::__private::push_lt(&mut _s);
            ::quote::ToTokens::to_tokens(&elem_ty, &mut _s);
            ::quote::__private::push_shr(&mut _s);
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::parse(&mut _s, "0");
                    ::quote::__private::push_dot2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "__max");
                    _s
                });
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "map");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_or(&mut _s);
                    ::quote::__private::push_underscore(&mut _s);
                    ::quote::__private::push_or(&mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "std");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "vec");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Vec");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "with_capacity");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "_n_rows");
                            _s
                        });
                    _s
                });
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "collect");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            ::quote::__private::push_semi(&mut _s);
            ::quote::__private::push_ident(&mut _s, "for");
            ::quote::__private::push_ident(&mut _s, "__row_vec");
            ::quote::__private::push_ident(&mut _s, "in");
            ::quote::__private::push_ident(&mut _s, "__auto");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "let");
                    ::quote::__private::push_ident(&mut _s, "mut");
                    ::quote::__private::push_ident(&mut _s, "__elems");
                    ::quote::__private::push_eq(&mut _s);
                    ::quote::ToTokens::to_tokens(&elems_iter, &mut _s);
                    ::quote::__private::push_semi(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "for");
                    ::quote::__private::push_ident(&mut _s, "__col");
                    ::quote::__private::push_ident(&mut _s, "in");
                    ::quote::__private::push_ident(&mut _s, "__cols");
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "iter_mut");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        ::quote::__private::TokenStream::new());
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Brace,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "__col");
                            ::quote::__private::push_dot(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "push");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "core");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "iter");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "Iterator");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "next");
                                    ::quote::__private::push_group(&mut _s,
                                        ::quote::__private::Delimiter::Parenthesis,
                                        {
                                            let mut _s = ::quote::__private::TokenStream::new();
                                            ::quote::__private::push_and(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "mut");
                                            ::quote::__private::push_ident(&mut _s, "__elems");
                                            _s
                                        });
                                    _s
                                });
                            ::quote::__private::push_semi(&mut _s);
                            _s
                        });
                    _s
                });
            ::quote::__private::push_ident(&mut _s, "for");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "__i");
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "__col");
                    _s
                });
            ::quote::__private::push_ident(&mut _s, "in");
            ::quote::__private::push_ident(&mut _s, "__cols");
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "into_iter");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "enumerate");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "__df_pairs");
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "push");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "std");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "format");
                                    ::quote::__private::push_bang(&mut _s);
                                    ::quote::__private::push_group(&mut _s,
                                        ::quote::__private::Delimiter::Parenthesis,
                                        {
                                            let mut _s = ::quote::__private::TokenStream::new();
                                            ::quote::__private::parse(&mut _s, "\"{}_{}\"");
                                            ::quote::__private::push_comma(&mut _s);
                                            ::quote::ToTokens::to_tokens(&col_name_str, &mut _s);
                                            ::quote::__private::push_comma(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "__i");
                                            ::quote::__private::push_add(&mut _s);
                                            ::quote::__private::parse(&mut _s, "1");
                                            _s
                                        });
                                    ::quote::__private::push_comma(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "__scope");
                                    ::quote::__private::push_dot(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "protect_raw");
                                    ::quote::__private::push_group(&mut _s,
                                        ::quote::__private::Delimiter::Parenthesis,
                                        {
                                            let mut _s = ::quote::__private::TokenStream::new();
                                            ::quote::__private::push_colon2(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
                                            ::quote::__private::push_colon2(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "IntoR");
                                            ::quote::__private::push_colon2(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "into_sexp");
                                            ::quote::__private::push_group(&mut _s,
                                                ::quote::__private::Delimiter::Parenthesis,
                                                {
                                                    let mut _s = ::quote::__private::TokenStream::new();
                                                    ::quote::__private::push_ident(&mut _s, "__col");
                                                    _s
                                                });
                                            _s
                                        });
                                    ::quote::__private::push_comma(&mut _s);
                                    _s
                                });
                            _s
                        });
                    ::quote::__private::push_semi(&mut _s);
                    _s
                });
            _s
        });
    _s
}quote! {
1997                        {
1998                            let __auto = self.#col_name;
1999                            let __max = __auto.iter().map(|v| v.len()).max().unwrap_or(0);
2000                            let mut __cols: ::std::vec::Vec<::std::vec::Vec<::core::option::Option<#elem_ty>>> = (0..__max)
2001                                .map(|_| ::std::vec::Vec::with_capacity(_n_rows))
2002                                .collect();
2003                            for __row_vec in __auto {
2004                                let mut __elems = #elems_iter;
2005                                for __col in __cols.iter_mut() {
2006                                    __col.push(::core::iter::Iterator::next(&mut __elems));
2007                                }
2008                            }
2009                            for (__i, __col) in __cols.into_iter().enumerate() {
2010                                __df_pairs.push((
2011                                    ::std::format!("{}_{}", #col_name_str, __i + 1),
2012                                    __scope.protect_raw(::miniextendr_api::IntoR::into_sexp(__col)),
2013                                ));
2014                            }
2015                        }
2016                    }
2017                }
2018                ResolvedField::Struct(data) => {
2019                    // Issue #485: convert `Vec<Inner>` via Inner::to_dataframe,
2020                    // extract its named columns, and push under `<base>_` prefix.
2021                    let col_name = &data.col_name;
2022                    let base_name_str = &data.col_name_str;
2023                    let inner_ty = &data.inner_ty;
2024                    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "let");
            ::quote::__private::push_ident(&mut _s, "__inner_df");
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::push_lt(&mut _s);
            ::quote::ToTokens::to_tokens(&inner_ty, &mut _s);
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "to_dataframe");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "self");
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::ToTokens::to_tokens(&col_name, &mut _s);
                    _s
                });
            ::quote::__private::push_semi(&mut _s);
            ::quote::__private::push_ident(&mut _s, "let");
            ::quote::__private::push_ident(&mut _s, "__inner_cols");
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "convert");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "ColumnSource");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "into_named_columns");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "__inner_df");
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "__scope");
                    ::quote::__private::push_comma(&mut _s);
                    _s
                });
            ::quote::__private::push_semi(&mut _s);
            ::quote::__private::push_ident(&mut _s, "for");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "__inner_col_name");
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "__inner_col_sexp");
                    _s
                });
            ::quote::__private::push_ident(&mut _s, "in");
            ::quote::__private::push_ident(&mut _s, "__inner_cols");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "__df_pairs");
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "push");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "std");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "format");
                                    ::quote::__private::push_bang(&mut _s);
                                    ::quote::__private::push_group(&mut _s,
                                        ::quote::__private::Delimiter::Parenthesis,
                                        {
                                            let mut _s = ::quote::__private::TokenStream::new();
                                            ::quote::__private::parse(&mut _s, "\"{}_{}\"");
                                            ::quote::__private::push_comma(&mut _s);
                                            ::quote::ToTokens::to_tokens(&base_name_str, &mut _s);
                                            ::quote::__private::push_comma(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "__inner_col_name");
                                            _s
                                        });
                                    ::quote::__private::push_comma(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "__inner_col_sexp");
                                    ::quote::__private::push_comma(&mut _s);
                                    _s
                                });
                            _s
                        });
                    ::quote::__private::push_semi(&mut _s);
                    _s
                });
            _s
        });
    _s
}quote! {
2025                        {
2026                            let __inner_df = <#inner_ty>::to_dataframe(self.#col_name);
2027                            // The inner column list is rooted in __scope, which keeps its
2028                            // columns alive across the later columns' allocations.
2029                            let __inner_cols = ::miniextendr_api::convert::ColumnSource::into_named_columns(
2030                                __inner_df,
2031                                &__scope,
2032                            );
2033                            for (__inner_col_name, __inner_col_sexp) in __inner_cols {
2034                                __df_pairs.push((
2035                                    ::std::format!("{}_{}", #base_name_str, __inner_col_name),
2036                                    __inner_col_sexp,
2037                                ));
2038                            }
2039                        }
2040                    }
2041                }
2042                // Map (#919): push two list-columns `<base>_keys` / `<base>_values`.
2043                ResolvedField::Map(data) => {
2044                    let keys_ident = match ::quote::__private::IdentFragmentAdapter(&data.base_name) {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("{0}_keys", arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("{}_keys", data.base_name);
2045                    let vals_ident = match ::quote::__private::IdentFragmentAdapter(&data.base_name) {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("{0}_values", arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("{}_values", data.base_name);
2046                    let keys_name = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}_keys", data.base_name))
    })format!("{}_keys", data.base_name);
2047                    let vals_name = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}_values", data.base_name))
    })format!("{}_values", data.base_name);
2048                    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "__df_pairs");
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "push");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::ToTokens::to_tokens(&keys_name, &mut _s);
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "to_string");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        ::quote::__private::TokenStream::new());
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "__scope");
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "protect_raw");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "IntoR");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "into_sexp");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_ident(&mut _s, "self");
                                    ::quote::__private::push_dot(&mut _s);
                                    ::quote::ToTokens::to_tokens(&keys_ident, &mut _s);
                                    _s
                                });
                            _s
                        });
                    ::quote::__private::push_comma(&mut _s);
                    _s
                });
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    ::quote::__private::push_ident(&mut _s, "__df_pairs");
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "push");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::ToTokens::to_tokens(&vals_name, &mut _s);
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "to_string");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        ::quote::__private::TokenStream::new());
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "__scope");
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "protect_raw");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "IntoR");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "into_sexp");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_ident(&mut _s, "self");
                                    ::quote::__private::push_dot(&mut _s);
                                    ::quote::ToTokens::to_tokens(&vals_ident, &mut _s);
                                    _s
                                });
                            _s
                        });
                    ::quote::__private::push_comma(&mut _s);
                    _s
                });
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! {
2049                        __df_pairs.push((
2050                            #keys_name.to_string(),
2051                            __scope.protect_raw(::miniextendr_api::IntoR::into_sexp(self.#keys_ident)),
2052                        ));
2053                        __df_pairs.push((
2054                            #vals_name.to_string(),
2055                            __scope.protect_raw(::miniextendr_api::IntoR::into_sexp(self.#vals_ident)),
2056                        ));
2057                    }
2058                }
2059            })
2060            .collect();
2061
2062        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::ToTokens::to_tokens(&impl_generics, &mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "miniextendr_api");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "convert");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "ColumnSource");
    ::quote::__private::push_ident(&mut _s, "for");
    ::quote::ToTokens::to_tokens(&df_name, &mut _s);
    ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
    ::quote::ToTokens::to_tokens(&where_clause, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "into_column_list");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "self");
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "List");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "let");
                    ::quote::__private::push_ident(&mut _s, "_n_rows");
                    ::quote::__private::push_eq(&mut _s);
                    ::quote::ToTokens::to_tokens(&length_ref, &mut _s);
                    ::quote::__private::push_semi(&mut _s);
                    {
                        use ::quote::__private::ext::*;
                        let has_iter = ::quote::__private::HasIterator::<false>;
                        #[allow(unused_mut)]
                        let (mut length_checks, i) =
                            length_checks.quote_into_iter();
                        let has_iter = has_iter | i;
                        <_ as
                                ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                        while true {
                            let length_checks =
                                match length_checks.next() {
                                    Some(_x) => ::quote::__private::RepInterp(_x),
                                    None => break,
                                };
                            ::quote::ToTokens::to_tokens(&length_checks, &mut _s);
                        }
                    }
                    ::quote::__private::push_ident(&mut _s, "unsafe");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Brace,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "let");
                            ::quote::__private::push_ident(&mut _s, "__scope");
                            ::quote::__private::push_eq(&mut _s);
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "gc_protect");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "ProtectScope");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "new");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                ::quote::__private::TokenStream::new());
                            ::quote::__private::push_semi(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "let");
                            ::quote::__private::push_ident(&mut _s, "mut");
                            ::quote::__private::push_ident(&mut _s, "__df_pairs");
                            ::quote::__private::push_colon(&mut _s);
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "std");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "vec");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "Vec");
                            ::quote::__private::push_lt(&mut _s);
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "std");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "string");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "String");
                                    ::quote::__private::push_comma(&mut _s);
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "miniextendr_api");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "SEXP");
                                    ::quote::__private::push_comma(&mut _s);
                                    _s
                                });
                            ::quote::__private::push_gt(&mut _s);
                            ::quote::__private::push_eq(&mut _s);
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "std");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "vec");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "Vec");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "new");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                ::quote::__private::TokenStream::new());
                            ::quote::__private::push_semi(&mut _s);
                            ::quote::ToTokens::to_tokens(&tag_push_pair, &mut _s);
                            {
                                use ::quote::__private::ext::*;
                                let has_iter = ::quote::__private::HasIterator::<false>;
                                #[allow(unused_mut)]
                                let (mut pair_pushes, i) = pair_pushes.quote_into_iter();
                                let has_iter = has_iter | i;
                                <_ as
                                        ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                                while true {
                                    let pair_pushes =
                                        match pair_pushes.next() {
                                            Some(_x) => ::quote::__private::RepInterp(_x),
                                            None => break,
                                        };
                                    ::quote::ToTokens::to_tokens(&pair_pushes, &mut _s);
                                }
                            }
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "list");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "List");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "from_raw_pairs");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_ident(&mut _s, "__df_pairs");
                                    _s
                                });
                            ::quote::__private::push_dot(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "set_class_str");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_and(&mut _s);
                                    ::quote::__private::push_group(&mut _s,
                                        ::quote::__private::Delimiter::Bracket,
                                        {
                                            let mut _s = ::quote::__private::TokenStream::new();
                                            ::quote::__private::parse(&mut _s, "\"data.frame\"");
                                            _s
                                        });
                                    _s
                                });
                            ::quote::__private::push_dot(&mut _s);
                            ::quote::__private::push_ident(&mut _s,
                                "set_row_names_int");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_ident(&mut _s, "_n_rows");
                                    _s
                                });
                            _s
                        });
                    _s
                });
            _s
        });
    _s
}quote! {
2063            impl #impl_generics ::miniextendr_api::convert::ColumnSource for #df_name #ty_generics #where_clause {
2064                fn into_column_list(self) -> ::miniextendr_api::List {
2065                    let _n_rows = #length_ref;
2066                    #(#length_checks)*
2067                    // SAFETY: into_column_list only runs on the R main thread.
2068                    // ProtectScope keeps each column SEXP rooted across the
2069                    // next column's allocations; from_raw_pairs writes them
2070                    // into the parent VECSXP before we drop the scope.
2071                    unsafe {
2072                        let __scope = ::miniextendr_api::gc_protect::ProtectScope::new();
2073                        let mut __df_pairs: ::std::vec::Vec<(
2074                            ::std::string::String,
2075                            ::miniextendr_api::SEXP,
2076                        )> = ::std::vec::Vec::new();
2077                        #tag_push_pair
2078                        #(#pair_pushes)*
2079                        ::miniextendr_api::list::List::from_raw_pairs(__df_pairs)
2080                            .set_class_str(&["data.frame"])
2081                            .set_row_names_int(_n_rows)
2082                    }
2083                }
2084            }
2085        }
2086    } else {
2087        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::ToTokens::to_tokens(&impl_generics, &mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "miniextendr_api");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "convert");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "ColumnSource");
    ::quote::__private::push_ident(&mut _s, "for");
    ::quote::ToTokens::to_tokens(&df_name, &mut _s);
    ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
    ::quote::ToTokens::to_tokens(&where_clause, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "into_column_list");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "self");
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "List");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "let");
                    ::quote::__private::push_ident(&mut _s, "_n_rows");
                    ::quote::__private::push_eq(&mut _s);
                    ::quote::ToTokens::to_tokens(&length_ref, &mut _s);
                    ::quote::__private::push_semi(&mut _s);
                    {
                        use ::quote::__private::ext::*;
                        let has_iter = ::quote::__private::HasIterator::<false>;
                        #[allow(unused_mut)]
                        let (mut length_checks, i) =
                            length_checks.quote_into_iter();
                        let has_iter = has_iter | i;
                        <_ as
                                ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                        while true {
                            let length_checks =
                                match length_checks.next() {
                                    Some(_x) => ::quote::__private::RepInterp(_x),
                                    None => break,
                                };
                            ::quote::ToTokens::to_tokens(&length_checks, &mut _s);
                        }
                    }
                    ::quote::__private::push_ident(&mut _s, "unsafe");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Brace,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "let");
                            ::quote::__private::push_ident(&mut _s, "__scope");
                            ::quote::__private::push_eq(&mut _s);
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "gc_protect");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "ProtectScope");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "new");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                ::quote::__private::TokenStream::new());
                            ::quote::__private::push_semi(&mut _s);
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "list");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "List");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "from_raw_pairs");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "std");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "vec");
                                    ::quote::__private::push_bang(&mut _s);
                                    ::quote::__private::push_group(&mut _s,
                                        ::quote::__private::Delimiter::Bracket,
                                        {
                                            let mut _s = ::quote::__private::TokenStream::new();
                                            ::quote::ToTokens::to_tokens(&tag_pair, &mut _s);
                                            {
                                                use ::quote::__private::ext::*;
                                                let mut _first = true;
                                                let has_iter = ::quote::__private::HasIterator::<false>;
                                                #[allow(unused_mut)]
                                                let (mut df_pairs, i) = df_pairs.quote_into_iter();
                                                let has_iter = has_iter | i;
                                                <_ as
                                                        ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                                                while true {
                                                    let df_pairs =
                                                        match df_pairs.next() {
                                                            Some(_x) => ::quote::__private::RepInterp(_x),
                                                            None => break,
                                                        };
                                                    if !_first { ::quote::__private::push_comma(&mut _s); }
                                                    _first = false;
                                                    ::quote::ToTokens::to_tokens(&df_pairs, &mut _s);
                                                }
                                            }
                                            _s
                                        });
                                    _s
                                });
                            ::quote::__private::push_dot(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "set_class_str");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_and(&mut _s);
                                    ::quote::__private::push_group(&mut _s,
                                        ::quote::__private::Delimiter::Bracket,
                                        {
                                            let mut _s = ::quote::__private::TokenStream::new();
                                            ::quote::__private::parse(&mut _s, "\"data.frame\"");
                                            _s
                                        });
                                    _s
                                });
                            ::quote::__private::push_dot(&mut _s);
                            ::quote::__private::push_ident(&mut _s,
                                "set_row_names_int");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_ident(&mut _s, "_n_rows");
                                    _s
                                });
                            _s
                        });
                    _s
                });
            _s
        });
    _s
}quote! {
2088            impl #impl_generics ::miniextendr_api::convert::ColumnSource for #df_name #ty_generics #where_clause {
2089                fn into_column_list(self) -> ::miniextendr_api::List {
2090                    let _n_rows = #length_ref;
2091                    #(#length_checks)*
2092                    // SAFETY: see auto-expand branch.
2093                    unsafe {
2094                        let __scope = ::miniextendr_api::gc_protect::ProtectScope::new();
2095                        ::miniextendr_api::list::List::from_raw_pairs(::std::vec![
2096                            #tag_pair
2097                            #(#df_pairs),*
2098                        ])
2099                        .set_class_str(&["data.frame"])
2100                        .set_row_names_int(_n_rows)
2101                    }
2102                }
2103            }
2104        }
2105    };
2106    // endregion
2107
2108    // region: From<Vec<RowType>>
2109    let mut col_vec_inits: Vec<TokenStream> = flat_cols
2110        .iter()
2111        .map(|fc| {
2112            let name = &fc.df_field;
2113            let ty = &fc.vec_elem_ty;
2114            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::__private::push_ident(&mut _s, "mut");
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_lt(&mut _s);
    ::quote::ToTokens::to_tokens(&ty, &mut _s);
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_eq(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "with_capacity");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "len");
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! { let mut #name: ::std::vec::Vec<#ty> = ::std::vec::Vec::with_capacity(len); }
2115        })
2116        .collect();
2117    for ac in &auto_expand_cols {
2118        let name = &ac.df_field;
2119        let cty = &ac.container_ty;
2120        col_vec_inits.push(
2121            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::__private::push_ident(&mut _s, "mut");
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_lt(&mut _s);
    ::quote::ToTokens::to_tokens(&cty, &mut _s);
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_eq(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "with_capacity");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "len");
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! { let mut #name: ::std::vec::Vec<#cty> = ::std::vec::Vec::with_capacity(len); },
2122        );
2123    }
2124    for sc in &struct_cols {
2125        let name = &sc.df_field;
2126        let ity = &sc.inner_ty;
2127        col_vec_inits.push(
2128            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::__private::push_ident(&mut _s, "mut");
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_lt(&mut _s);
    ::quote::ToTokens::to_tokens(&ity, &mut _s);
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_eq(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "with_capacity");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "len");
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! { let mut #name: ::std::vec::Vec<#ity> = ::std::vec::Vec::with_capacity(len); },
2129        );
2130    }
2131
2132    let tag_init = if has_tag {
2133        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::__private::push_ident(&mut _s, "mut");
    ::quote::__private::push_ident(&mut _s, "_tag");
    ::quote::__private::push_colon(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "string");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "String");
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_eq(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "with_capacity");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "len");
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! { let mut _tag: ::std::vec::Vec<::std::string::String> = ::std::vec::Vec::with_capacity(len); }
2134    } else {
2135        TokenStream::new()
2136    };
2137
2138    let tag_push = if has_tag {
2139        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "_tag");
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "push");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::ToTokens::to_tokens(&row_name_str, &mut _s);
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "to_string");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! { _tag.push(#row_name_str.to_string()); }
2140    } else {
2141        TokenStream::new()
2142    };
2143
2144    // Generate push statements for each resolved field
2145    let col_pushes: Vec<TokenStream> = resolved
2146        .iter()
2147        .map(|rf| match rf {
2148            ResolvedField::Single(data) => {
2149                let access = if let Some(idx) = &data.tuple_index {
2150                    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "row");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&idx, &mut _s);
    _s
}quote! { row.#idx }
2151                } else {
2152                    let rust_name = &data.rust_name;
2153                    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "row");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&rust_name, &mut _s);
    _s
}quote! { row.#rust_name }
2154                };
2155                let col_name = &data.col_name;
2156                {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&col_name, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "push");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::ToTokens::to_tokens(&access, &mut _s);
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! { #col_name.push(#access); }
2157            }
2158            ResolvedField::ExpandedFixed(data) => {
2159                let access = if let Some(idx) = &data.tuple_index {
2160                    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "row");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&idx, &mut _s);
    _s
}quote! { row.#idx }
2161                } else {
2162                    let rust_name = &data.rust_name;
2163                    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "row");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&rust_name, &mut _s);
    _s
}quote! { row.#rust_name }
2164                };
2165                let elems = expanded_elem_idents(
2166                    &crate::naming::unraw(&data.rust_name).to_string(),
2167                    data.len,
2168                );
2169                let bind = fixed_array_elems(&access, data.borrowed, &data.elem_ty, &elems);
2170                let pushes: Vec<TokenStream> = elems
2171                    .iter()
2172                    .enumerate()
2173                    .map(|(i, elem)| {
2174                        let col_ident = match ::quote::__private::IdentFragmentAdapter(&data.base_name) {
    arg =>
        match ::quote::__private::IdentFragmentAdapter(&(i + 1)) {
            arg =>
                ::quote::__private::mk_ident(&::alloc::__export::must_use({
                                ::alloc::fmt::format(format_args!("{0}_{1}", arg, arg))
                            }),
                    ::quote::__private::Option::None.or(arg.span()).or(arg.span())),
        },
}format_ident!("{}_{}", data.base_name, i + 1);
2175                        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&col_ident, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "push");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::ToTokens::to_tokens(&elem, &mut _s);
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! { #col_ident.push(#elem); }
2176                    })
2177                    .collect();
2178                {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&bind, &mut _s);
    {
        use ::quote::__private::ext::*;
        let has_iter = ::quote::__private::HasIterator::<false>;
        #[allow(unused_mut)]
        let (mut pushes, i) = pushes.quote_into_iter();
        let has_iter = has_iter | i;
        <_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
        while true {
            let pushes =
                match pushes.next() {
                    Some(_x) => ::quote::__private::RepInterp(_x),
                    None => break,
                };
            ::quote::ToTokens::to_tokens(&pushes, &mut _s);
        }
    }
    _s
}quote! {
2179                    #bind
2180                    #(#pushes)*
2181                }
2182            }
2183            ResolvedField::ExpandedVec(data) => {
2184                let access = if let Some(idx) = &data.tuple_index {
2185                    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "row");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&idx, &mut _s);
    _s
}quote! { row.#idx }
2186                } else {
2187                    let rust_name = &data.rust_name;
2188                    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "row");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&rust_name, &mut _s);
    _s
}quote! { row.#rust_name }
2189                };
2190                let iter = match ::quote::__private::IdentFragmentAdapter(&crate::naming::unraw(&data.rust_name).to_string().trim_start_matches('_'))
    {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("__mxv_{0}", arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!(
2191                    "__mxv_{}",
2192                    crate::naming::unraw(&data.rust_name)
2193                        .to_string()
2194                        .trim_start_matches('_')
2195                );
2196                let elems = expanded_elem_idents(
2197                    &crate::naming::unraw(&data.rust_name).to_string(),
2198                    data.width,
2199                );
2200                let bind = width_elems(&access, data.borrowed, &data.elem_ty, &iter, &elems);
2201                let pushes: Vec<TokenStream> = elems
2202                    .iter()
2203                    .enumerate()
2204                    .map(|(i, elem)| {
2205                        let col_ident = match ::quote::__private::IdentFragmentAdapter(&data.base_name) {
    arg =>
        match ::quote::__private::IdentFragmentAdapter(&(i + 1)) {
            arg =>
                ::quote::__private::mk_ident(&::alloc::__export::must_use({
                                ::alloc::fmt::format(format_args!("{0}_{1}", arg, arg))
                            }),
                    ::quote::__private::Option::None.or(arg.span()).or(arg.span())),
        },
}format_ident!("{}_{}", data.base_name, i + 1);
2206                        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&col_ident, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "push");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::ToTokens::to_tokens(&elem, &mut _s);
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! { #col_ident.push(#elem); }
2207                    })
2208                    .collect();
2209                {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&bind, &mut _s);
    {
        use ::quote::__private::ext::*;
        let has_iter = ::quote::__private::HasIterator::<false>;
        #[allow(unused_mut)]
        let (mut pushes, i) = pushes.quote_into_iter();
        let has_iter = has_iter | i;
        <_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
        while true {
            let pushes =
                match pushes.next() {
                    Some(_x) => ::quote::__private::RepInterp(_x),
                    None => break,
                };
            ::quote::ToTokens::to_tokens(&pushes, &mut _s);
        }
    }
    _s
}quote! {
2210                    #bind
2211                    #(#pushes)*
2212                }
2213            }
2214            ResolvedField::AutoExpandVec(data) => {
2215                let access = if let Some(idx) = &data.tuple_index {
2216                    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "row");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&idx, &mut _s);
    _s
}quote! { row.#idx }
2217                } else {
2218                    let rust_name = &data.rust_name;
2219                    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "row");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&rust_name, &mut _s);
    _s
}quote! { row.#rust_name }
2220                };
2221                let col_name = &data.col_name;
2222                {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&col_name, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "push");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::ToTokens::to_tokens(&access, &mut _s);
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! { #col_name.push(#access); }
2223            }
2224            ResolvedField::Struct(data) => {
2225                let access = if let Some(idx) = &data.tuple_index {
2226                    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "row");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&idx, &mut _s);
    _s
}quote! { row.#idx }
2227                } else {
2228                    let rust_name = &data.rust_name;
2229                    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "row");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&rust_name, &mut _s);
    _s
}quote! { row.#rust_name }
2230                };
2231                let col_name = &data.col_name;
2232                {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&col_name, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "push");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::ToTokens::to_tokens(&access, &mut _s);
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! { #col_name.push(#access); }
2233            }
2234            // Map (#919): unzip into parallel keys/values vecs.
2235            ResolvedField::Map(data) => {
2236                let access = if let Some(idx) = &data.tuple_index {
2237                    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "row");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&idx, &mut _s);
    _s
}quote! { row.#idx }
2238                } else {
2239                    let rust_name = &data.rust_name;
2240                    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "row");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&rust_name, &mut _s);
    _s
}quote! { row.#rust_name }
2241                };
2242                let keys_col = match ::quote::__private::IdentFragmentAdapter(&data.base_name) {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("{0}_keys", arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("{}_keys", data.base_name);
2243                let vals_col = match ::quote::__private::IdentFragmentAdapter(&data.base_name) {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("{0}_values", arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("{}_values", data.base_name);
2244                {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "__mx_keys");
            ::quote::__private::push_comma(&mut _s);
            ::quote::__private::push_ident(&mut _s, "__mx_vals");
            _s
        });
    ::quote::__private::push_eq(&mut _s);
    ::quote::ToTokens::to_tokens(&access, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "into_iter");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "unzip");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_underscore(&mut _s);
    ::quote::__private::push_comma(&mut _s);
    ::quote::__private::push_underscore(&mut _s);
    ::quote::__private::push_comma(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_underscore(&mut _s);
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_comma(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_underscore(&mut _s);
    ::quote::__private::push_shr(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_semi(&mut _s);
    ::quote::ToTokens::to_tokens(&keys_col, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "push");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "__mx_keys");
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    ::quote::ToTokens::to_tokens(&vals_col, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "push");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "__mx_vals");
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! {
2245                    let (__mx_keys, __mx_vals) = #access
2246                        .into_iter()
2247                        .unzip::<_, _, ::std::vec::Vec<_>, ::std::vec::Vec<_>>();
2248                    #keys_col.push(__mx_keys);
2249                    #vals_col.push(__mx_vals);
2250                }
2251            }
2252        })
2253        .collect();
2254
2255    let tag_struct_field = if has_tag {
2256        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "_tag");
    ::quote::__private::push_comma(&mut _s);
    _s
}quote! { _tag, }
2257    } else {
2258        TokenStream::new()
2259    };
2260
2261    let len_struct_field = if flat_cols.is_empty()
2262        && auto_expand_cols.is_empty()
2263        && struct_cols.is_empty()
2264        && !has_tag
2265    {
2266        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "_len");
    ::quote::__private::push_colon(&mut _s);
    ::quote::__private::push_ident(&mut _s, "len");
    ::quote::__private::push_comma(&mut _s);
    _s
}quote! { _len: len, }
2267    } else {
2268        TokenStream::new()
2269    };
2270
2271    let mut col_struct_fields: Vec<TokenStream> = flat_cols
2272        .iter()
2273        .map(|fc| {
2274            let name = &fc.df_field;
2275            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    _s
}quote! { #name }
2276        })
2277        .collect();
2278    for ac in &auto_expand_cols {
2279        let name = &ac.df_field;
2280        col_struct_fields.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    _s
}quote! { #name });
2281    }
2282    for sc in &struct_cols {
2283        let name = &sc.df_field;
2284        col_struct_fields.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    _s
}quote! { #name });
2285    }
2286
2287    // For skipped fields in destructure: bind to `_`
2288    let skip_bindings: Vec<TokenStream> = skipped_fields
2289        .iter()
2290        .map(|(name, _)| {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::__private::push_underscore(&mut _s);
    ::quote::__private::push_eq(&mut _s);
    ::quote::__private::push_ident(&mut _s, "row");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! { let _ = row.#name; })
2291        .collect();
2292
2293    let from_vec_impl = {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::ToTokens::to_tokens(&impl_generics, &mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "convert");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "From");
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_lt(&mut _s);
    ::quote::ToTokens::to_tokens(&row_name, &mut _s);
    ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
    ::quote::__private::push_shr(&mut _s);
    ::quote::__private::push_ident(&mut _s, "for");
    ::quote::ToTokens::to_tokens(&df_name, &mut _s);
    ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
    ::quote::ToTokens::to_tokens(&where_clause, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "from");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "rows");
                    ::quote::__private::push_colon(&mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "std");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "vec");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Vec");
                    ::quote::__private::push_lt(&mut _s);
                    ::quote::ToTokens::to_tokens(&row_name, &mut _s);
                    ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
                    ::quote::__private::push_gt(&mut _s);
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Self");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "let");
                    ::quote::__private::push_ident(&mut _s, "len");
                    ::quote::__private::push_eq(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "rows");
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "len");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        ::quote::__private::TokenStream::new());
                    ::quote::__private::push_semi(&mut _s);
                    ::quote::ToTokens::to_tokens(&tag_init, &mut _s);
                    {
                        use ::quote::__private::ext::*;
                        let has_iter = ::quote::__private::HasIterator::<false>;
                        #[allow(unused_mut)]
                        let (mut col_vec_inits, i) =
                            col_vec_inits.quote_into_iter();
                        let has_iter = has_iter | i;
                        <_ as
                                ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                        while true {
                            let col_vec_inits =
                                match col_vec_inits.next() {
                                    Some(_x) => ::quote::__private::RepInterp(_x),
                                    None => break,
                                };
                            ::quote::ToTokens::to_tokens(&col_vec_inits, &mut _s);
                        }
                    }
                    ::quote::__private::push_ident(&mut _s, "for");
                    ::quote::__private::push_ident(&mut _s, "row");
                    ::quote::__private::push_ident(&mut _s, "in");
                    ::quote::__private::push_ident(&mut _s, "rows");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Brace,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::ToTokens::to_tokens(&tag_push, &mut _s);
                            {
                                use ::quote::__private::ext::*;
                                let has_iter = ::quote::__private::HasIterator::<false>;
                                #[allow(unused_mut)]
                                let (mut skip_bindings, i) =
                                    skip_bindings.quote_into_iter();
                                let has_iter = has_iter | i;
                                <_ as
                                        ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                                while true {
                                    let skip_bindings =
                                        match skip_bindings.next() {
                                            Some(_x) => ::quote::__private::RepInterp(_x),
                                            None => break,
                                        };
                                    ::quote::ToTokens::to_tokens(&skip_bindings, &mut _s);
                                }
                            }
                            {
                                use ::quote::__private::ext::*;
                                let has_iter = ::quote::__private::HasIterator::<false>;
                                #[allow(unused_mut)]
                                let (mut col_pushes, i) = col_pushes.quote_into_iter();
                                let has_iter = has_iter | i;
                                <_ as
                                        ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                                while true {
                                    let col_pushes =
                                        match col_pushes.next() {
                                            Some(_x) => ::quote::__private::RepInterp(_x),
                                            None => break,
                                        };
                                    ::quote::ToTokens::to_tokens(&col_pushes, &mut _s);
                                }
                            }
                            _s
                        });
                    ::quote::ToTokens::to_tokens(&df_name, &mut _s);
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Brace,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::ToTokens::to_tokens(&tag_struct_field, &mut _s);
                            ::quote::ToTokens::to_tokens(&len_struct_field, &mut _s);
                            ::quote::ToTokens::to_tokens(&phantom_init, &mut _s);
                            {
                                use ::quote::__private::ext::*;
                                let mut _first = true;
                                let has_iter = ::quote::__private::HasIterator::<false>;
                                #[allow(unused_mut)]
                                let (mut col_struct_fields, i) =
                                    col_struct_fields.quote_into_iter();
                                let has_iter = has_iter | i;
                                <_ as
                                        ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                                while true {
                                    let col_struct_fields =
                                        match col_struct_fields.next() {
                                            Some(_x) => ::quote::__private::RepInterp(_x),
                                            None => break,
                                        };
                                    if !_first { ::quote::__private::push_comma(&mut _s); }
                                    _first = false;
                                    ::quote::ToTokens::to_tokens(&col_struct_fields, &mut _s);
                                }
                            }
                            _s
                        });
                    _s
                });
            _s
        });
    _s
}quote! {
2294        impl #impl_generics ::core::convert::From<::std::vec::Vec<#row_name #ty_generics>> for #df_name #ty_generics #where_clause {
2295            fn from(rows: ::std::vec::Vec<#row_name #ty_generics>) -> Self {
2296                let len = rows.len();
2297                #tag_init
2298                #(#col_vec_inits)*
2299                for row in rows {
2300                    #tag_push
2301                    #(#skip_bindings)*
2302                    #(#col_pushes)*
2303                }
2304                #df_name {
2305                    #tag_struct_field
2306                    #len_struct_field
2307                    #phantom_init
2308                    #(#col_struct_fields),*
2309                }
2310            }
2311        }
2312    };
2313    // endregion
2314
2315    // region: Generate from_rows_par (parallel scatter-write via ColumnWriter)
2316    //
2317    // The companion's `ParallelColumns` impl moves each row to a rayon worker,
2318    // which writes the row's values into columns pre-filled with `Default`
2319    // placeholders. Two field kinds keep their values in the companion and have
2320    // no placeholder:
2321    //   - struct (DataFrameRow-flattened) fields (#485): companion stores `Vec<Inner>`.
2322    //   - `as_list`-on-struct fields (#485 opt-out): converted to a list-column
2323    //     only at frame assembly.
2324    // Both are cloned in a sequential pre-pass (`for __prerow in &rows { ... }`)
2325    // before `into_par_iter()` consumes the rows, and skipped in the parallel loop.
2326    // The pre-pass is O(n) extra per such field: a constant factor, not a change
2327    // in asymptotic complexity.
2328    //
2329    // What the fill needs of the field types (the rows `Send`, placeholder
2330    // columns `Default + Send`, pre-pass columns `Clone`) is the impl's
2331    // conditional `where` clause, so a row shape without it is not an error:
2332    // `from_rows_par` falls back to `from_rows` (`from_rows_par_override`).
2333    let has_par_impl = !flat_cols.is_empty()
2334        || !auto_expand_cols.is_empty()
2335        || has_tag
2336        || has_struct
2337        || has_into_list_struct;
2338    let (parallel_columns_item, from_rows_par_method) = if has_par_impl {
2339        let mut par_bounds: Vec<(TokenStream, TokenStream)> = ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [({
                        let mut _s = ::quote::__private::TokenStream::new();
                        ::quote::ToTokens::to_tokens(&row_name, &mut _s);
                        ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
                        _s
                    },
                    {
                        let mut _s = ::quote::__private::TokenStream::new();
                        ::quote::__private::push_colon2(&mut _s);
                        ::quote::__private::push_ident(&mut _s, "core");
                        ::quote::__private::push_colon2(&mut _s);
                        ::quote::__private::push_ident(&mut _s, "marker");
                        ::quote::__private::push_colon2(&mut _s);
                        ::quote::__private::push_ident(&mut _s, "Send");
                        _s
                    })]))vec![(
2340            quote! { #row_name #ty_generics },
2341            quote! { ::core::marker::Send },
2342        )];
2343        for fc in &flat_cols {
2344            let ty = &fc.vec_elem_ty;
2345            let bound = if fc.needs_into_list {
2346                {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "clone");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Clone");
    _s
}quote! { ::core::clone::Clone }
2347            } else {
2348                {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "default");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Default");
    ::quote::__private::push_add(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "marker");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Send");
    _s
}quote! { ::core::default::Default + ::core::marker::Send }
2349            };
2350            par_bounds.push(({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&ty, &mut _s);
    _s
}quote! { #ty }, bound));
2351        }
2352        for ac in &auto_expand_cols {
2353            let cty = &ac.container_ty;
2354            par_bounds.push((
2355                {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&cty, &mut _s);
    _s
}quote! { #cty },
2356                {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "default");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Default");
    ::quote::__private::push_add(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "marker");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Send");
    _s
}quote! { ::core::default::Default + ::core::marker::Send },
2357            ));
2358        }
2359        for sc in &struct_cols {
2360            let ity = &sc.inner_ty;
2361            par_bounds.push(({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&ity, &mut _s);
    _s
}quote! { #ity }, {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "clone");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Clone");
    _s
}quote! { ::core::clone::Clone }));
2362        }
2363
2364        // Column declarations:
2365        //   - scalar / expand cols: `Default` placeholders (scatter-written in parallel)
2366        //   - struct / as_list-struct cols: filled in the pre-pass
2367        let mut par_col_decls = Vec::new();
2368        if has_tag {
2369            par_col_decls.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::__private::push_ident(&mut _s, "mut");
    ::quote::__private::push_ident(&mut _s, "_tag");
    ::quote::__private::push_colon(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "string");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "String");
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_eq(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_bang(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "std");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "string");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "String");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "new");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            ::quote::__private::push_semi(&mut _s);
            ::quote::__private::push_ident(&mut _s, "len");
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! {
2370                let mut _tag: ::std::vec::Vec<::std::string::String> = ::std::vec![::std::string::String::new(); len];
2371            });
2372        }
2373        // Sequential pre-pass: struct fields.
2374        // Iterate resolved to pick up tuple_index for tuple-struct outers.
2375        for rf in &resolved {
2376            if let ResolvedField::Struct(data) = rf {
2377                let col_name = &data.col_name;
2378                let ity = &data.inner_ty;
2379                let access = if let Some(idx) = &data.tuple_index {
2380                    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "__prerow");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&idx, &mut _s);
    _s
}quote! { __prerow.#idx }
2381                } else {
2382                    let rust_name = &data.rust_name;
2383                    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "__prerow");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&rust_name, &mut _s);
    _s
}quote! { __prerow.#rust_name }
2384                };
2385                par_col_decls.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::__private::push_ident(&mut _s, "mut");
    ::quote::ToTokens::to_tokens(&col_name, &mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_lt(&mut _s);
    ::quote::ToTokens::to_tokens(&ity, &mut _s);
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_eq(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "with_capacity");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "len");
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    ::quote::__private::push_ident(&mut _s, "for");
    ::quote::__private::push_ident(&mut _s, "__prerow");
    ::quote::__private::push_ident(&mut _s, "in");
    ::quote::__private::push_and(&mut _s);
    ::quote::__private::push_ident(&mut _s, "rows");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::ToTokens::to_tokens(&col_name, &mut _s);
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "push");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "core");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "clone");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Clone");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "clone");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_and(&mut _s);
                            ::quote::ToTokens::to_tokens(&access, &mut _s);
                            _s
                        });
                    _s
                });
            ::quote::__private::push_semi(&mut _s);
            _s
        });
    _s
}quote! {
2386                    let mut #col_name: ::std::vec::Vec<#ity> = ::std::vec::Vec::with_capacity(len);
2387                    for __prerow in &rows {
2388                        #col_name.push(::core::clone::Clone::clone(&#access));
2389                    }
2390                });
2391            }
2392        }
2393        // Sequential pre-pass: as_list-on-struct fields. Pure Rust: the
2394        // list-column is built at frame assembly.
2395        for rf in &resolved {
2396            if let ResolvedField::Single(data) = rf
2397                && data.needs_into_list
2398            {
2399                let col_name = &data.col_name;
2400                let rust_name = &data.rust_name;
2401                let ty = &data.ty;
2402                let access = if let Some(idx) = &data.tuple_index {
2403                    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "__prerow");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&idx, &mut _s);
    _s
}quote! { __prerow.#idx }
2404                } else {
2405                    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "__prerow");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&rust_name, &mut _s);
    _s
}quote! { __prerow.#rust_name }
2406                };
2407                par_col_decls.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::__private::push_ident(&mut _s, "mut");
    ::quote::ToTokens::to_tokens(&col_name, &mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_lt(&mut _s);
    ::quote::ToTokens::to_tokens(&ty, &mut _s);
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_eq(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "with_capacity");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "len");
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    ::quote::__private::push_ident(&mut _s, "for");
    ::quote::__private::push_ident(&mut _s, "__prerow");
    ::quote::__private::push_ident(&mut _s, "in");
    ::quote::__private::push_and(&mut _s);
    ::quote::__private::push_ident(&mut _s, "rows");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::ToTokens::to_tokens(&col_name, &mut _s);
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "push");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "core");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "clone");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Clone");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "clone");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_and(&mut _s);
                            ::quote::ToTokens::to_tokens(&access, &mut _s);
                            _s
                        });
                    _s
                });
            ::quote::__private::push_semi(&mut _s);
            _s
        });
    _s
}quote! {
2408                    let mut #col_name: ::std::vec::Vec<#ty> = ::std::vec::Vec::with_capacity(len);
2409                    for __prerow in &rows {
2410                        #col_name.push(::core::clone::Clone::clone(&#access));
2411                    }
2412                });
2413            }
2414        }
2415        // Parallel scalar/expand columns.
2416        let placeholders = |name: &syn::Ident, ty: &syn::Type| {
2417            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::__private::push_ident(&mut _s, "mut");
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_lt(&mut _s);
    ::quote::ToTokens::to_tokens(&ty, &mut _s);
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_eq(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "iter");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Iterator");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "collect");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "core");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "iter");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Iterator");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "take");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "core");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "iter");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "repeat_with");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_lt(&mut _s);
                            ::quote::ToTokens::to_tokens(&ty, &mut _s);
                            ::quote::__private::push_ident(&mut _s, "as");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "core");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "default");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "Default");
                            ::quote::__private::push_gt(&mut _s);
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "default");
                            _s
                        });
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "len");
                    ::quote::__private::push_comma(&mut _s);
                    _s
                });
            ::quote::__private::push_comma(&mut _s);
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! {
2418                let mut #name: ::std::vec::Vec<#ty> = ::core::iter::Iterator::collect(
2419                    ::core::iter::Iterator::take(
2420                        ::core::iter::repeat_with(<#ty as ::core::default::Default>::default),
2421                        len,
2422                    ),
2423                );
2424            }
2425        };
2426        for fc in &flat_cols {
2427            if fc.needs_into_list {
2428                // Handled in the sequential pre-pass above.
2429                continue;
2430            }
2431            par_col_decls.push(placeholders(&fc.df_field, &fc.vec_elem_ty));
2432        }
2433        for ac in &auto_expand_cols {
2434            par_col_decls.push(placeholders(&ac.df_field, &ac.container_ty));
2435        }
2436
2437        // Writer declarations (only for scatter-write cols — struct/as_list pre-pass
2438        // cols are already populated and need no ColumnWriter).
2439        let mut writer_decls = Vec::new();
2440        if has_tag {
2441            writer_decls.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::__private::push_ident(&mut _s, "__w_tag");
    ::quote::__private::push_eq(&mut _s);
    ::quote::__private::push_ident(&mut _s, "unsafe");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "rayon_bridge");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "ColumnWriter");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "new");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "mut");
                    ::quote::__private::push_ident(&mut _s, "_tag");
                    _s
                });
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! {
2442                let __w_tag = unsafe {
2443                    ::miniextendr_api::rayon_bridge::ColumnWriter::new(&mut _tag)
2444                };
2445            });
2446        }
2447        for fc in &flat_cols {
2448            if fc.needs_into_list {
2449                continue;
2450            }
2451            let name = &fc.df_field;
2452            let w_name = match ::quote::__private::IdentFragmentAdapter(&crate::naming::unraw(name)) {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("__w_{0}", arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("__w_{}", crate::naming::unraw(name));
2453            writer_decls.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::ToTokens::to_tokens(&w_name, &mut _s);
    ::quote::__private::push_eq(&mut _s);
    ::quote::__private::push_ident(&mut _s, "unsafe");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "rayon_bridge");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "ColumnWriter");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "new");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "mut");
                    ::quote::ToTokens::to_tokens(&name, &mut _s);
                    _s
                });
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! {
2454                let #w_name = unsafe {
2455                    ::miniextendr_api::rayon_bridge::ColumnWriter::new(&mut #name)
2456                };
2457            });
2458        }
2459        for ac in &auto_expand_cols {
2460            let name = &ac.df_field;
2461            let w_name = match ::quote::__private::IdentFragmentAdapter(&crate::naming::unraw(name)) {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("__w_{0}", arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("__w_{}", crate::naming::unraw(name));
2462            writer_decls.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::ToTokens::to_tokens(&w_name, &mut _s);
    ::quote::__private::push_eq(&mut _s);
    ::quote::__private::push_ident(&mut _s, "unsafe");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "rayon_bridge");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "ColumnWriter");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "new");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "mut");
                    ::quote::ToTokens::to_tokens(&name, &mut _s);
                    _s
                });
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! {
2463                let #w_name = unsafe {
2464                    ::miniextendr_api::rayon_bridge::ColumnWriter::new(&mut #name)
2465                };
2466            });
2467        }
2468
2469        // Write calls per resolved field (parallel scatter-write only).
2470        let tag_write = if has_tag {
2471            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "__w_tag");
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "write");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "__i");
            ::quote::__private::push_comma(&mut _s);
            ::quote::ToTokens::to_tokens(&row_name_str, &mut _s);
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "to_string");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! { __w_tag.write(__i, #row_name_str.to_string()); }
2472        } else {
2473            TokenStream::new()
2474        };
2475
2476        let par_write_calls: Vec<TokenStream> = resolved
2477            .iter()
2478            .map(|rf| match rf {
2479                ResolvedField::Single(data) => {
2480                    if data.needs_into_list {
2481                        // Handled in the sequential pre-pass; skip in par loop.
2482                        return TokenStream::new();
2483                    }
2484                    let access = if let Some(idx) = &data.tuple_index {
2485                        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "__row");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&idx, &mut _s);
    _s
}quote! { __row.#idx }
2486                    } else {
2487                        let rust_name = &data.rust_name;
2488                        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "__row");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&rust_name, &mut _s);
    _s
}quote! { __row.#rust_name }
2489                    };
2490                    let w_name = match ::quote::__private::IdentFragmentAdapter(&crate::naming::unraw(&data.col_name))
    {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("__w_{0}", arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("__w_{}", crate::naming::unraw(&data.col_name));
2491                    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&w_name, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "write");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "__i");
            ::quote::__private::push_comma(&mut _s);
            ::quote::ToTokens::to_tokens(&access, &mut _s);
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! { #w_name.write(__i, #access); }
2492                }
2493                ResolvedField::ExpandedFixed(data) => {
2494                    let access = if let Some(idx) = &data.tuple_index {
2495                        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "__row");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&idx, &mut _s);
    _s
}quote! { __row.#idx }
2496                    } else {
2497                        let rust_name = &data.rust_name;
2498                        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "__row");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&rust_name, &mut _s);
    _s
}quote! { __row.#rust_name }
2499                    };
2500                    let elems = expanded_elem_idents(
2501                        &crate::naming::unraw(&data.rust_name).to_string(),
2502                        data.len,
2503                    );
2504                    let bind = fixed_array_elems(&access, data.borrowed, &data.elem_ty, &elems);
2505                    let writes: Vec<TokenStream> = elems
2506                        .iter()
2507                        .enumerate()
2508                        .map(|(i, elem)| {
2509                            let w_name = match ::quote::__private::IdentFragmentAdapter(&data.base_name) {
    arg =>
        match ::quote::__private::IdentFragmentAdapter(&(i + 1)) {
            arg =>
                ::quote::__private::mk_ident(&::alloc::__export::must_use({
                                ::alloc::fmt::format(format_args!("__w_{0}_{1}", arg, arg))
                            }),
                    ::quote::__private::Option::None.or(arg.span()).or(arg.span())),
        },
}format_ident!("__w_{}_{}", data.base_name, i + 1);
2510                            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&w_name, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "write");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "__i");
            ::quote::__private::push_comma(&mut _s);
            ::quote::ToTokens::to_tokens(&elem, &mut _s);
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! { #w_name.write(__i, #elem); }
2511                        })
2512                        .collect();
2513                    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&bind, &mut _s);
    {
        use ::quote::__private::ext::*;
        let has_iter = ::quote::__private::HasIterator::<false>;
        #[allow(unused_mut)]
        let (mut writes, i) = writes.quote_into_iter();
        let has_iter = has_iter | i;
        <_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
        while true {
            let writes =
                match writes.next() {
                    Some(_x) => ::quote::__private::RepInterp(_x),
                    None => break,
                };
            ::quote::ToTokens::to_tokens(&writes, &mut _s);
        }
    }
    _s
}quote! {
2514                        #bind
2515                        #(#writes)*
2516                    }
2517                }
2518                ResolvedField::ExpandedVec(data) => {
2519                    let access = if let Some(idx) = &data.tuple_index {
2520                        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "__row");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&idx, &mut _s);
    _s
}quote! { __row.#idx }
2521                    } else {
2522                        let rust_name = &data.rust_name;
2523                        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "__row");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&rust_name, &mut _s);
    _s
}quote! { __row.#rust_name }
2524                    };
2525                    let iter = match ::quote::__private::IdentFragmentAdapter(&crate::naming::unraw(&data.rust_name).to_string().trim_start_matches('_'))
    {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("__mxv_{0}", arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!(
2526                        "__mxv_{}",
2527                        crate::naming::unraw(&data.rust_name)
2528                            .to_string()
2529                            .trim_start_matches('_')
2530                    );
2531                    let elems = expanded_elem_idents(
2532                        &crate::naming::unraw(&data.rust_name).to_string(),
2533                        data.width,
2534                    );
2535                    let bind = width_elems(&access, data.borrowed, &data.elem_ty, &iter, &elems);
2536                    let writes: Vec<TokenStream> = elems
2537                        .iter()
2538                        .enumerate()
2539                        .map(|(i, elem)| {
2540                            let w_name = match ::quote::__private::IdentFragmentAdapter(&data.base_name) {
    arg =>
        match ::quote::__private::IdentFragmentAdapter(&(i + 1)) {
            arg =>
                ::quote::__private::mk_ident(&::alloc::__export::must_use({
                                ::alloc::fmt::format(format_args!("__w_{0}_{1}", arg, arg))
                            }),
                    ::quote::__private::Option::None.or(arg.span()).or(arg.span())),
        },
}format_ident!("__w_{}_{}", data.base_name, i + 1);
2541                            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&w_name, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "write");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "__i");
            ::quote::__private::push_comma(&mut _s);
            ::quote::ToTokens::to_tokens(&elem, &mut _s);
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! { #w_name.write(__i, #elem); }
2542                        })
2543                        .collect();
2544                    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&bind, &mut _s);
    {
        use ::quote::__private::ext::*;
        let has_iter = ::quote::__private::HasIterator::<false>;
        #[allow(unused_mut)]
        let (mut writes, i) = writes.quote_into_iter();
        let has_iter = has_iter | i;
        <_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
        while true {
            let writes =
                match writes.next() {
                    Some(_x) => ::quote::__private::RepInterp(_x),
                    None => break,
                };
            ::quote::ToTokens::to_tokens(&writes, &mut _s);
        }
    }
    _s
}quote! {
2545                        #bind
2546                        #(#writes)*
2547                    }
2548                }
2549                ResolvedField::AutoExpandVec(data) => {
2550                    let access = if let Some(idx) = &data.tuple_index {
2551                        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "__row");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&idx, &mut _s);
    _s
}quote! { __row.#idx }
2552                    } else {
2553                        let rust_name = &data.rust_name;
2554                        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "__row");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&rust_name, &mut _s);
    _s
}quote! { __row.#rust_name }
2555                    };
2556                    let w_name = match ::quote::__private::IdentFragmentAdapter(&crate::naming::unraw(&data.col_name))
    {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("__w_{0}", arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("__w_{}", crate::naming::unraw(&data.col_name));
2557                    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&w_name, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "write");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "__i");
            ::quote::__private::push_comma(&mut _s);
            ::quote::ToTokens::to_tokens(&access, &mut _s);
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! { #w_name.write(__i, #access); }
2558                }
2559                // Struct fields (#485) are collected in the sequential pre-pass
2560                // above; nothing to write in the parallel loop.
2561                ResolvedField::Struct(_) => TokenStream::new(),
2562                // Map (#919): unzip into parallel keys/values vecs via scatter-write.
2563                ResolvedField::Map(data) => {
2564                    let access = if let Some(idx) = &data.tuple_index {
2565                        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "__row");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&idx, &mut _s);
    _s
}quote! { __row.#idx }
2566                    } else {
2567                        let rust_name = &data.rust_name;
2568                        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "__row");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&rust_name, &mut _s);
    _s
}quote! { __row.#rust_name }
2569                    };
2570                    let w_keys = match ::quote::__private::IdentFragmentAdapter(&data.base_name) {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("__w_{0}_keys", arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("__w_{}_keys", data.base_name);
2571                    let w_vals = match ::quote::__private::IdentFragmentAdapter(&data.base_name) {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("__w_{0}_values", arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("__w_{}_values", data.base_name);
2572                    {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "__mx_keys");
            ::quote::__private::push_comma(&mut _s);
            ::quote::__private::push_ident(&mut _s, "__mx_vals");
            _s
        });
    ::quote::__private::push_eq(&mut _s);
    ::quote::ToTokens::to_tokens(&access, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "into_iter");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "unzip");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_underscore(&mut _s);
    ::quote::__private::push_comma(&mut _s);
    ::quote::__private::push_underscore(&mut _s);
    ::quote::__private::push_comma(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_underscore(&mut _s);
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_comma(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_underscore(&mut _s);
    ::quote::__private::push_shr(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_semi(&mut _s);
    ::quote::ToTokens::to_tokens(&w_keys, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "write");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "__i");
            ::quote::__private::push_comma(&mut _s);
            ::quote::__private::push_ident(&mut _s, "__mx_keys");
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    ::quote::ToTokens::to_tokens(&w_vals, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "write");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "__i");
            ::quote::__private::push_comma(&mut _s);
            ::quote::__private::push_ident(&mut _s, "__mx_vals");
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! {
2573                        let (__mx_keys, __mx_vals) = #access
2574                            .into_iter()
2575                            .unzip::<_, _, ::std::vec::Vec<_>, ::std::vec::Vec<_>>();
2576                        #w_keys.write(__i, __mx_keys);
2577                        #w_vals.write(__i, __mx_vals);
2578                    }
2579                }
2580            })
2581            .collect();
2582
2583        let par_skip_bindings: Vec<TokenStream> = skipped_fields
2584            .iter()
2585            .map(|(name, _)| {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::__private::push_underscore(&mut _s);
    ::quote::__private::push_eq(&mut _s);
    ::quote::__private::push_ident(&mut _s, "__row");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! { let _ = __row.#name; })
2586            .collect();
2587
2588        // Return struct fields
2589        let par_tag_field = if has_tag {
2590            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "_tag");
    ::quote::__private::push_comma(&mut _s);
    _s
}quote! { _tag, }
2591        } else {
2592            TokenStream::new()
2593        };
2594        let mut par_struct_fields: Vec<TokenStream> = flat_cols
2595            .iter()
2596            .map(|fc| {
2597                let name = &fc.df_field;
2598                {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    _s
}quote! { #name }
2599            })
2600            .collect();
2601        for ac in &auto_expand_cols {
2602            let name = &ac.df_field;
2603            par_struct_fields.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    _s
}quote! { #name });
2604        }
2605        for sc in &struct_cols {
2606            let name = &sc.df_field;
2607            par_struct_fields.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    _s
}quote! { #name });
2608        }
2609
2610        // Only emit an into_par_iter call when there are scalar/expand/tag cols
2611        // to scatter-write; struct/as_list-only structs skip the parallel loop.
2612        let has_par_cols = !flat_cols.iter().all(|fc| fc.needs_into_list)
2613            || !auto_expand_cols.is_empty()
2614            || has_tag;
2615        let par_loop = if has_par_cols {
2616            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "use");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "rayon_bridge");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "rayon");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "prelude");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_star(&mut _s);
            ::quote::__private::push_semi(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "optionals");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "parallel");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "ensure_pool");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            ::quote::__private::push_semi(&mut _s);
            {
                use ::quote::__private::ext::*;
                let has_iter = ::quote::__private::HasIterator::<false>;
                #[allow(unused_mut)]
                let (mut writer_decls, i) = writer_decls.quote_into_iter();
                let has_iter = has_iter | i;
                <_ as
                        ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                while true {
                    let writer_decls =
                        match writer_decls.next() {
                            Some(_x) => ::quote::__private::RepInterp(_x),
                            None => break,
                        };
                    ::quote::ToTokens::to_tokens(&writer_decls, &mut _s);
                }
            }
            ::quote::__private::push_ident(&mut _s, "rows");
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "into_par_iter");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "enumerate");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "for_each");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_or(&mut _s);
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "__i");
                            ::quote::__private::push_comma(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "__row");
                            _s
                        });
                    ::quote::__private::push_or(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "unsafe");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Brace,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::ToTokens::to_tokens(&tag_write, &mut _s);
                            {
                                use ::quote::__private::ext::*;
                                let has_iter = ::quote::__private::HasIterator::<false>;
                                #[allow(unused_mut)]
                                let (mut par_write_calls, i) =
                                    par_write_calls.quote_into_iter();
                                let has_iter = has_iter | i;
                                <_ as
                                        ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                                while true {
                                    let par_write_calls =
                                        match par_write_calls.next() {
                                            Some(_x) => ::quote::__private::RepInterp(_x),
                                            None => break,
                                        };
                                    ::quote::ToTokens::to_tokens(&par_write_calls, &mut _s);
                                }
                            }
                            {
                                use ::quote::__private::ext::*;
                                let has_iter = ::quote::__private::HasIterator::<false>;
                                #[allow(unused_mut)]
                                let (mut par_skip_bindings, i) =
                                    par_skip_bindings.quote_into_iter();
                                let has_iter = has_iter | i;
                                <_ as
                                        ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                                while true {
                                    let par_skip_bindings =
                                        match par_skip_bindings.next() {
                                            Some(_x) => ::quote::__private::RepInterp(_x),
                                            None => break,
                                        };
                                    ::quote::ToTokens::to_tokens(&par_skip_bindings, &mut _s);
                                }
                            }
                            _s
                        });
                    _s
                });
            ::quote::__private::push_semi(&mut _s);
            _s
        });
    _s
}quote! {
2617                {
2618                    use ::miniextendr_api::rayon_bridge::rayon::prelude::*;
2619                    ::miniextendr_api::optionals::parallel::ensure_pool();
2620                    #(#writer_decls)*
2621                    rows.into_par_iter().enumerate().for_each(|(__i, __row)| unsafe {
2622                        #tag_write
2623                        #(#par_write_calls)*
2624                        #(#par_skip_bindings)*
2625                    });
2626                }
2627            }
2628        } else {
2629            // All columns were collected in the pre-pass; rows already consumed.
2630            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::__private::push_ident(&mut _s, "_rows");
    ::quote::__private::push_eq(&mut _s);
    ::quote::__private::push_ident(&mut _s, "rows");
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! { let _rows = rows; }
2631        };
2632
2633        let parallel_columns_item = parallel_columns_impl(
2634            df_name,
2635            row_name,
2636            &input.generics,
2637            &par_bounds,
2638            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::__private::push_ident(&mut _s, "len");
    ::quote::__private::push_eq(&mut _s);
    ::quote::__private::push_ident(&mut _s, "rows");
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "len");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_semi(&mut _s);
    {
        use ::quote::__private::ext::*;
        let has_iter = ::quote::__private::HasIterator::<false>;
        #[allow(unused_mut)]
        let (mut par_col_decls, i) = par_col_decls.quote_into_iter();
        let has_iter = has_iter | i;
        <_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
        while true {
            let par_col_decls =
                match par_col_decls.next() {
                    Some(_x) => ::quote::__private::RepInterp(_x),
                    None => break,
                };
            ::quote::ToTokens::to_tokens(&par_col_decls, &mut _s);
        }
    }
    ::quote::ToTokens::to_tokens(&par_loop, &mut _s);
    ::quote::ToTokens::to_tokens(&df_name, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::ToTokens::to_tokens(&par_tag_field, &mut _s);
            ::quote::ToTokens::to_tokens(&phantom_init, &mut _s);
            {
                use ::quote::__private::ext::*;
                let mut _first = true;
                let has_iter = ::quote::__private::HasIterator::<false>;
                #[allow(unused_mut)]
                let (mut par_struct_fields, i) =
                    par_struct_fields.quote_into_iter();
                let has_iter = has_iter | i;
                <_ as
                        ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                while true {
                    let par_struct_fields =
                        match par_struct_fields.next() {
                            Some(_x) => ::quote::__private::RepInterp(_x),
                            None => break,
                        };
                    if !_first { ::quote::__private::push_comma(&mut _s); }
                    _first = false;
                    ::quote::ToTokens::to_tokens(&par_struct_fields, &mut _s);
                }
            }
            _s
        });
    _s
}quote! {
2639                let len = rows.len();
2640                #(#par_col_decls)*
2641                #par_loop
2642                #df_name { #par_tag_field #phantom_init #(#par_struct_fields),* }
2643            },
2644        );
2645        (
2646            parallel_columns_item,
2647            from_rows_par_override({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&row_name, &mut _s);
    ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
    _s
}quote! { #row_name #ty_generics }),
2648        )
2649    } else {
2650        (TokenStream::new(), TokenStream::new())
2651    };
2652
2653    // region: IntoIterator (only for named non-empty structs without expansion)
2654    let can_iterate = !flat_cols.is_empty()
2655        && !is_tuple_struct
2656        && !is_unit_struct
2657        && !has_expansion
2658        && !has_into_list_struct;
2659    let into_iterator_impl = if can_iterate {
2660        let iterator_name = match ::quote::__private::IdentFragmentAdapter(&df_name) {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("{0}Iterator", arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("{}Iterator", df_name);
2661
2662        let iter_field_decls: Vec<_> = flat_cols
2663            .iter()
2664            .map(|fc| {
2665                let name = &fc.df_field;
2666                let ty = &fc.vec_elem_ty;
2667                {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "IntoIter");
    ::quote::__private::push_lt(&mut _s);
    ::quote::ToTokens::to_tokens(&ty, &mut _s);
    ::quote::__private::push_gt(&mut _s);
    _s
}quote! { #name: ::std::vec::IntoIter<#ty> }
2668            })
2669            .collect();
2670
2671        let destruct_pattern: Vec<_> = flat_cols
2672            .iter()
2673            .map(|fc| {
2674                let name = &fc.df_field;
2675                {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    _s
}quote! { #name }
2676            })
2677            .collect();
2678
2679        let mut iter_init_tokens = TokenStream::new();
2680        for (i, fc) in flat_cols.iter().enumerate() {
2681            let name = &fc.df_field;
2682            let ty = &fc.vec_elem_ty;
2683            if i > 0 {
2684                iter_init_tokens.extend({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_comma(&mut _s);
    _s
}quote! { , });
2685            }
2686            iter_init_tokens.extend({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_lt(&mut _s);
    ::quote::ToTokens::to_tokens(&ty, &mut _s);
    ::quote::__private::push_shr(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "into_iter");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::ToTokens::to_tokens(&name, &mut _s);
            _s
        });
    _s
}quote! { #name: <::std::vec::Vec<#ty>>::into_iter(#name) });
2687        }
2688
2689        // For next(): reconstruct original field names (col_name == rust_name for Single)
2690        let mut next_struct_tokens = TokenStream::new();
2691        for (i, rf) in resolved.iter().enumerate() {
2692            if let ResolvedField::Single(data) = rf {
2693                if i > 0 {
2694                    next_struct_tokens.extend({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_comma(&mut _s);
    _s
}quote! { , });
2695                }
2696                let rust_name = &data.rust_name;
2697                let col_name = &data.col_name;
2698                next_struct_tokens.extend({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&rust_name, &mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::__private::push_ident(&mut _s, "self");
    ::quote::__private::push_dot(&mut _s);
    ::quote::ToTokens::to_tokens(&col_name, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "next");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_question(&mut _s);
    _s
}quote! { #rust_name: self.#col_name.next()? });
2699            }
2700        }
2701
2702        // Skipped fields are reconstructed via `Default::default()` each time
2703        // `next()` yields a row, so the companion iterates rows only where every
2704        // `#[dataframe(skip)]` field type implements `Default`.
2705        let skip_defaults: Vec<TokenStream> = skipped_fields
2706            .iter()
2707            .map(|(name, _)| {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_comma(&mut _s);
    ::quote::ToTokens::to_tokens(&name, &mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "default");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Default");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "default");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    _s
}quote! { , #name: ::core::default::Default::default() })
2708            .collect();
2709        let skip_bounds: Vec<(TokenStream, TokenStream)> = skipped_fields
2710            .iter()
2711            .map(|(_, ty)| ({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&ty, &mut _s);
    _s
}quote! { #ty }, {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "default");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Default");
    _s
}quote! { ::core::default::Default }))
2712            .collect();
2713        let iter_where = conditional_where(where_clause, &skip_bounds);
2714
2715        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&vis, &mut _s);
    ::quote::__private::push_ident(&mut _s, "struct");
    ::quote::ToTokens::to_tokens(&iterator_name, &mut _s);
    ::quote::ToTokens::to_tokens(&impl_generics, &mut _s);
    ::quote::ToTokens::to_tokens(&where_clause, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::ToTokens::to_tokens(&phantom_field, &mut _s);
            {
                use ::quote::__private::ext::*;
                let mut _first = true;
                let has_iter = ::quote::__private::HasIterator::<false>;
                #[allow(unused_mut)]
                let (mut iter_field_decls, i) =
                    iter_field_decls.quote_into_iter();
                let has_iter = has_iter | i;
                <_ as
                        ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                while true {
                    let iter_field_decls =
                        match iter_field_decls.next() {
                            Some(_x) => ::quote::__private::RepInterp(_x),
                            None => break,
                        };
                    if !_first { ::quote::__private::push_comma(&mut _s); }
                    _first = false;
                    ::quote::ToTokens::to_tokens(&iter_field_decls, &mut _s);
                }
            }
            _s
        });
    ::quote::__private::push_pound(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "allow");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "unused_lifetimes");
                    _s
                });
            _s
        });
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::ToTokens::to_tokens(&impl_generics, &mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "iter");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "IntoIterator");
    ::quote::__private::push_ident(&mut _s, "for");
    ::quote::ToTokens::to_tokens(&df_name, &mut _s);
    ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
    ::quote::ToTokens::to_tokens(&iter_where, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "type");
            ::quote::__private::push_ident(&mut _s, "Item");
            ::quote::__private::push_eq(&mut _s);
            ::quote::ToTokens::to_tokens(&row_name, &mut _s);
            ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
            ::quote::__private::push_semi(&mut _s);
            ::quote::__private::push_ident(&mut _s, "type");
            ::quote::__private::push_ident(&mut _s, "IntoIter");
            ::quote::__private::push_eq(&mut _s);
            ::quote::ToTokens::to_tokens(&iterator_name, &mut _s);
            ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
            ::quote::__private::push_semi(&mut _s);
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "into_iter");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "self");
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Self");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "IntoIter");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "let");
                    ::quote::ToTokens::to_tokens(&df_name, &mut _s);
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Brace,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            {
                                use ::quote::__private::ext::*;
                                let has_iter = ::quote::__private::HasIterator::<false>;
                                #[allow(unused_mut)]
                                let (mut destruct_pattern, i) =
                                    destruct_pattern.quote_into_iter();
                                let has_iter = has_iter | i;
                                <_ as
                                        ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                                while true {
                                    let destruct_pattern =
                                        match destruct_pattern.next() {
                                            Some(_x) => ::quote::__private::RepInterp(_x),
                                            None => break,
                                        };
                                    ::quote::ToTokens::to_tokens(&destruct_pattern, &mut _s);
                                    ::quote::__private::push_comma(&mut _s);
                                }
                            }
                            ::quote::__private::push_dot2(&mut _s);
                            _s
                        });
                    ::quote::__private::push_eq(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "self");
                    ::quote::__private::push_semi(&mut _s);
                    ::quote::ToTokens::to_tokens(&iterator_name, &mut _s);
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Brace,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::ToTokens::to_tokens(&phantom_init, &mut _s);
                            ::quote::ToTokens::to_tokens(&iter_init_tokens, &mut _s);
                            _s
                        });
                    _s
                });
            _s
        });
    ::quote::__private::push_pound(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "allow");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "unused_lifetimes");
                    _s
                });
            _s
        });
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::ToTokens::to_tokens(&impl_generics, &mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "iter");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Iterator");
    ::quote::__private::push_ident(&mut _s, "for");
    ::quote::ToTokens::to_tokens(&iterator_name, &mut _s);
    ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
    ::quote::ToTokens::to_tokens(&iter_where, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "type");
            ::quote::__private::push_ident(&mut _s, "Item");
            ::quote::__private::push_eq(&mut _s);
            ::quote::ToTokens::to_tokens(&row_name, &mut _s);
            ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
            ::quote::__private::push_semi(&mut _s);
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "next");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "mut");
                    ::quote::__private::push_ident(&mut _s, "self");
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "core");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "option");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Option");
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Self");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Item");
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "core");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "option");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Option");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Some");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::ToTokens::to_tokens(&row_name, &mut _s);
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Brace,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::ToTokens::to_tokens(&next_struct_tokens, &mut _s);
                                    {
                                        use ::quote::__private::ext::*;
                                        let has_iter = ::quote::__private::HasIterator::<false>;
                                        #[allow(unused_mut)]
                                        let (mut skip_defaults, i) =
                                            skip_defaults.quote_into_iter();
                                        let has_iter = has_iter | i;
                                        <_ as
                                                ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                                        while true {
                                            let skip_defaults =
                                                match skip_defaults.next() {
                                                    Some(_x) => ::quote::__private::RepInterp(_x),
                                                    None => break,
                                                };
                                            ::quote::ToTokens::to_tokens(&skip_defaults, &mut _s);
                                        }
                                    }
                                    _s
                                });
                            _s
                        });
                    _s
                });
            _s
        });
    _s
}quote! {
2716            #vis struct #iterator_name #impl_generics #where_clause {
2717                #phantom_field
2718                #(#iter_field_decls),*
2719            }
2720
2721            #[allow(unused_lifetimes)]
2722            impl #impl_generics ::core::iter::IntoIterator for #df_name #ty_generics #iter_where {
2723                type Item = #row_name #ty_generics;
2724                type IntoIter = #iterator_name #ty_generics;
2725
2726                fn into_iter(self) -> Self::IntoIter {
2727                    let #df_name { #(#destruct_pattern,)* .. } = self;
2728                    #iterator_name {
2729                        #phantom_init
2730                        #iter_init_tokens
2731                    }
2732                }
2733            }
2734
2735            #[allow(unused_lifetimes)]
2736            impl #impl_generics ::core::iter::Iterator for #iterator_name #ty_generics #iter_where {
2737                type Item = #row_name #ty_generics;
2738
2739                fn next(&mut self) -> ::core::option::Option<Self::Item> {
2740                    ::core::option::Option::Some(#row_name {
2741                        #next_struct_tokens
2742                        #(#skip_defaults)*
2743                    })
2744                }
2745            }
2746        }
2747    } else {
2748        TokenStream::new()
2749    };
2750    // endregion
2751
2752    // The companion→rows path (`from_dataframe`) is not an inherent method: it is the
2753    // companion's `IntoIterator` impl, surfaced as the documented verb
2754    // `ColumnarFrame::into_rows` (available for row-iterable companions).
2755
2756    // region: from-R readers (try_from_dataframe / try_from_dataframe_par, #738/#782)
2757    //
2758    // Read an R `data.frame` SEXP directly into `Vec<Self>` without first
2759    // materialising a companion `#df_name`. A reader is generated for every
2760    // *named* struct whose fields are all reader-capable (see
2761    // `field_reader_capable`): scalar `Single` fields, column-expansion fields
2762    // (`[T; N]` / `Vec<T>` + `width`/`expand`), and struct-flatten fields (nested
2763    // `DataFrameRow`). Each shape's reader is the exact inverse of its write rule
2764    // — regroup the suffixed expansion columns, un-prefix and recurse into the
2765    // nested reader. Struct-path `HashMap<String, V>`/`BTreeMap<String, V>` map
2766    // columns read whole via `Vec<map>: TryFromSexp` (#764) — they share the
2767    // scalar `pull_col` path, gated by `SingleFieldData::map_reader` (non-String
2768    // keys / non-scalar values / custom hashers stay reader-incapable). `skip` /
2769    // `as_list` / set columns / tuple / unit shapes are not reader-capable and
2770    // fall through to the trait default (a clear runtime `DataFrameError`).
2771    // Tagged-enum and enum-`Map` readers already landed (#807/#816) — see
2772    // `enum_expansion::build_enum_reader`.
2773    //
2774    // The parallel variant (`#[cfg(feature = "rayon")]`) splits cleanly along the
2775    // R-thread boundary: all SEXP access (column extraction, ALTREP
2776    // materialisation, sub-frame selection + recursive nested reads) happens up
2777    // front on the R/worker thread; only then does `(0..nrow).into_par_iter()`
2778    // assemble each `Self` from the pre-extracted, owned column data by index —
2779    // pure Rust, zero R API calls. Flattened and factor fields would need
2780    // `Clone` for by-index assembly, so their `_par` reader delegates to the
2781    // sequential one (which moves) rather than imposing `Clone`.
2782    let struct_reader = !is_tuple_struct
2783        && !is_unit_struct
2784        && !has_tag
2785        && skipped_fields.is_empty()
2786        && !resolved.is_empty()
2787        && resolved.iter().all(field_reader_capable);
2788
2789    let has_autoexpand_field = resolved
2790        .iter()
2791        .any(|rf| #[allow(non_exhaustive_omitted_patterns)] match rf {
    ResolvedField::AutoExpandVec(_) => true,
    _ => false,
}matches!(rf, ResolvedField::AutoExpandVec(_)));
2792    let has_moved_reader_field = resolved.iter().any(|rf| match rf {
2793        ResolvedField::Struct(_) => true,
2794        ResolvedField::Single(data) => data.is_factor,
2795        _ => false,
2796    });
2797
2798    let reader_methods = if struct_reader {
2799        // Per-field fragments:
2800        //   extracts   — prelude statements (R-thread): pull/convert columns, run
2801        //                length checks, materialise nested sub-frames.
2802        //   seq_decls  — draining-iterator decls for the sequential row loop.
2803        //   seq_builds — `field: expr` in the sequential `Self { … }` literal
2804        //                (drains moved columns; indexes only `AutoExpandVec`).
2805        //   par_builds — `field: expr` in the parallel `Self { … }` literal
2806        //                (by-index `.clone()`; scalars only — never reached when
2807        //                a struct-flatten field is present).
2808        let mut extracts: Vec<TokenStream> = Vec::new();
2809        let mut seq_decls: Vec<TokenStream> = Vec::new();
2810        let mut seq_builds: Vec<TokenStream> = Vec::new();
2811        let mut par_builds: Vec<TokenStream> = Vec::new();
2812
2813        // Pull a named column out of R as an owned `Vec<#elem>` via `TryFromSexp`
2814        // (NA-aware, ALTREP-materialising), then length-check it against `__nrow`.
2815        // Bypasses `DataFrame::column` because its `Error = SexpError` bound is
2816        // tighter than the scalar element types' `TryFromSexp::Error`.
2817        let pull_col = |col_var: &syn::Ident,
2818                        col_name_str: &str,
2819                        elem_ty: &syn::Type,
2820                        is_factor: bool| {
2821            let convert = if is_factor {
2822                let span = syn::spanned::Spanned::span(elem_ty);
2823                {
    let mut _s = ::quote::__private::TokenStream::new();
    let _span: ::quote::__private::Span =
        ::quote::__private::get_span(span).__into_span();
    ::quote::__private::push_lt_spanned(&mut _s, _span);
    ::quote::__private::push_colon2_spanned(&mut _s, _span);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "miniextendr_api");
    ::quote::__private::push_colon2_spanned(&mut _s, _span);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "factor");
    ::quote::__private::push_colon2_spanned(&mut _s, _span);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "FactorVec");
    ::quote::__private::push_lt_spanned(&mut _s, _span);
    ::quote::ToTokens::to_tokens(&elem_ty, &mut _s);
    ::quote::__private::push_gt_spanned(&mut _s, _span);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "as");
    ::quote::__private::push_colon2_spanned(&mut _s, _span);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "miniextendr_api");
    ::quote::__private::push_colon2_spanned(&mut _s, _span);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "from_r");
    ::quote::__private::push_colon2_spanned(&mut _s, _span);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "TryFromSexp");
    ::quote::__private::push_gt_spanned(&mut _s, _span);
    ::quote::__private::push_colon2_spanned(&mut _s, _span);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "try_from_sexp");
    ::quote::__private::push_group_spanned(&mut _s, _span,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            let _span: ::quote::__private::Span =
                ::quote::__private::get_span(_span).__into_span();
            ::quote::__private::push_ident_spanned(&mut _s, _span,
                "__col_sexp");
            _s
        });
    ::quote::__private::push_dot_spanned(&mut _s, _span);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "map");
    ::quote::__private::push_group_spanned(&mut _s, _span,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            let _span: ::quote::__private::Span =
                ::quote::__private::get_span(_span).__into_span();
            ::quote::__private::push_or_spanned(&mut _s, _span);
            ::quote::__private::push_ident_spanned(&mut _s, _span, "values");
            ::quote::__private::push_or_spanned(&mut _s, _span);
            ::quote::__private::push_ident_spanned(&mut _s, _span, "values");
            ::quote::__private::push_dot_spanned(&mut _s, _span);
            ::quote::__private::push_ident_spanned(&mut _s, _span,
                "into_inner");
            ::quote::__private::push_group_spanned(&mut _s, _span,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let _: ::quote::__private::Span =
                        ::quote::__private::get_span(_span).__into_span();
                    ::quote::__private::TokenStream::new()
                });
            _s
        });
    _s
}quote_spanned! {span=>
2824                    <::miniextendr_api::factor::FactorVec<#elem_ty> as ::miniextendr_api::from_r::TryFromSexp>::try_from_sexp(__col_sexp)
2825                        .map(|values| values.into_inner())
2826                }
2827            } else {
2828                {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_lt(&mut _s);
    ::quote::ToTokens::to_tokens(&elem_ty, &mut _s);
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_ident(&mut _s, "as");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "miniextendr_api");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "from_r");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "TryFromSexp");
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "try_from_sexp");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "__col_sexp");
            _s
        });
    _s
}quote! {
2829                    <::std::vec::Vec<#elem_ty> as ::miniextendr_api::from_r::TryFromSexp>::try_from_sexp(__col_sexp)
2830                }
2831            };
2832            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::ToTokens::to_tokens(&col_var, &mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_lt(&mut _s);
    ::quote::ToTokens::to_tokens(&elem_ty, &mut _s);
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_eq(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "let");
            ::quote::__private::push_ident(&mut _s, "__col_sexp");
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::push_ident(&mut _s, "__view");
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "column_raw");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::ToTokens::to_tokens(&col_name_str, &mut _s);
                    _s
                });
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "ok_or_else");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_or_or(&mut _s);
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Brace,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "std");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "format");
                            ::quote::__private::push_bang(&mut _s);
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::parse(&mut _s,
                                        "\"column `{}` is missing from the data.frame\"");
                                    ::quote::__private::push_comma(&mut _s);
                                    ::quote::ToTokens::to_tokens(&col_name_str, &mut _s);
                                    _s
                                });
                            _s
                        });
                    _s
                });
            ::quote::__private::push_question(&mut _s);
            ::quote::__private::push_semi(&mut _s);
            ::quote::ToTokens::to_tokens(&convert, &mut _s);
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "map_err");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_or(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "e");
                    ::quote::__private::push_or(&mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "std");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "format");
                    ::quote::__private::push_bang(&mut _s);
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::parse(&mut _s,
                                "\"column `{}` could not be converted to the expected type: {}\"");
                            ::quote::__private::push_comma(&mut _s);
                            ::quote::ToTokens::to_tokens(&col_name_str, &mut _s);
                            ::quote::__private::push_comma(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "e");
                            _s
                        });
                    _s
                });
            ::quote::__private::push_question(&mut _s);
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    ::quote::__private::push_ident(&mut _s, "if");
    ::quote::ToTokens::to_tokens(&col_var, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "len");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_ne(&mut _s);
    ::quote::__private::push_ident(&mut _s, "__nrow");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "return");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "core");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "result");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Result");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Err");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "std");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "format");
                    ::quote::__private::push_bang(&mut _s);
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::parse(&mut _s,
                                "\"column `{}` has length {} but data.frame has {} rows\"");
                            ::quote::__private::push_comma(&mut _s);
                            ::quote::ToTokens::to_tokens(&col_name_str, &mut _s);
                            ::quote::__private::push_comma(&mut _s);
                            ::quote::ToTokens::to_tokens(&col_var, &mut _s);
                            ::quote::__private::push_dot(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "len");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                ::quote::__private::TokenStream::new());
                            ::quote::__private::push_comma(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "__nrow");
                            _s
                        });
                    _s
                });
            ::quote::__private::push_semi(&mut _s);
            _s
        });
    _s
}quote! {
2833                let #col_var: ::std::vec::Vec<#elem_ty> = {
2834                    let __col_sexp = __view.column_raw(#col_name_str).ok_or_else(|| {
2835                        ::std::format!("column `{}` is missing from the data.frame", #col_name_str)
2836                    })?;
2837                    #convert
2838                        .map_err(|e| ::std::format!(
2839                            "column `{}` could not be converted to the expected type: {}",
2840                            #col_name_str, e
2841                        ))?
2842                };
2843                if #col_var.len() != __nrow {
2844                    return ::core::result::Result::Err(::std::format!(
2845                        "column `{}` has length {} but data.frame has {} rows",
2846                        #col_name_str, #col_var.len(), __nrow
2847                    ));
2848                }
2849            }
2850        };
2851
2852        for rf in &resolved {
2853            match rf {
2854                ResolvedField::Single(data) => {
2855                    let rust_name = &data.rust_name;
2856                    let col_var = match ::quote::__private::IdentFragmentAdapter(&crate::naming::unraw(rust_name))
    {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("__col_{0}", arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("__col_{}", crate::naming::unraw(rust_name));
2857                    let it_var = match ::quote::__private::IdentFragmentAdapter(&crate::naming::unraw(rust_name))
    {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("__it_{0}", arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("__it_{}", crate::naming::unraw(rust_name));
2858                    match &data.list_elem_ty {
2859                        // Un-annotated owned collection: opaque list-column (VECSXP). Read
2860                        // each row's element back via `Vec<elem>: TryFromSexp`, then
2861                        // `.into()` to the field container type (`Vec<elem>` identity /
2862                        // `Box<[elem]>`). A non-list column (e.g. an all-empty column
2863                        // materialised as logical-NA) reads back as `__nrow` empty
2864                        // collections. (#809)
2865                        ::core::option::Option::Some(elem_ty) => {
2866                            let field_ty = &data.ty;
2867                            let col_name_str = &data.col_name_str;
2868                            extracts.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::ToTokens::to_tokens(&col_var, &mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_lt(&mut _s);
    ::quote::ToTokens::to_tokens(&field_ty, &mut _s);
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_eq(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "let");
            ::quote::__private::push_ident(&mut _s, "__col_sexp");
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::push_ident(&mut _s, "__view");
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "column_raw");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::ToTokens::to_tokens(&col_name_str, &mut _s);
                    _s
                });
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "ok_or_else");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_or_or(&mut _s);
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Brace,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "std");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "format");
                            ::quote::__private::push_bang(&mut _s);
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::parse(&mut _s,
                                        "\"column `{}` is missing from the data.frame\"");
                                    ::quote::__private::push_comma(&mut _s);
                                    ::quote::ToTokens::to_tokens(&col_name_str, &mut _s);
                                    _s
                                });
                            _s
                        });
                    _s
                });
            ::quote::__private::push_question(&mut _s);
            ::quote::__private::push_semi(&mut _s);
            ::quote::__private::push_ident(&mut _s, "if");
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "SEXP");
            ::quote::__private::push_ident(&mut _s, "as");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "SexpExt");
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "is_list");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "__col_sexp");
                    _s
                });
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "let");
                    ::quote::__private::push_ident(&mut _s, "__list");
                    ::quote::__private::push_eq(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "unsafe");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Brace,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "list");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "List");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "from_raw");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_ident(&mut _s, "__col_sexp");
                                    _s
                                });
                            _s
                        });
                    ::quote::__private::push_semi(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "let");
                    ::quote::__private::push_ident(&mut _s, "__len");
                    ::quote::__private::push_eq(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "__list");
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "len");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        ::quote::__private::TokenStream::new());
                    ::quote::__private::push_semi(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "let");
                    ::quote::__private::push_ident(&mut _s, "mut");
                    ::quote::__private::push_ident(&mut _s, "__v");
                    ::quote::__private::push_colon(&mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "std");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "vec");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Vec");
                    ::quote::__private::push_lt(&mut _s);
                    ::quote::ToTokens::to_tokens(&field_ty, &mut _s);
                    ::quote::__private::push_gt(&mut _s);
                    ::quote::__private::push_eq(&mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "std");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "vec");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Vec");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "with_capacity");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "__len");
                            ::quote::__private::push_ident(&mut _s, "as");
                            ::quote::__private::push_ident(&mut _s, "usize");
                            _s
                        });
                    ::quote::__private::push_semi(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "for");
                    ::quote::__private::push_ident(&mut _s, "__j");
                    ::quote::__private::push_ident(&mut _s, "in");
                    ::quote::__private::parse(&mut _s, "0");
                    ::quote::__private::push_dot2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "__len");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Brace,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "let");
                            ::quote::__private::push_ident(&mut _s, "__elt");
                            ::quote::__private::push_eq(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "__list");
                            ::quote::__private::push_dot(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "get");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_ident(&mut _s, "__j");
                                    _s
                                });
                            ::quote::__private::push_dot(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "unwrap");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                ::quote::__private::TokenStream::new());
                            ::quote::__private::push_semi(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "let");
                            ::quote::__private::push_ident(&mut _s, "__inner");
                            ::quote::__private::push_colon(&mut _s);
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "std");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "vec");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "Vec");
                            ::quote::__private::push_lt(&mut _s);
                            ::quote::ToTokens::to_tokens(&elem_ty, &mut _s);
                            ::quote::__private::push_gt(&mut _s);
                            ::quote::__private::push_eq(&mut _s);
                            ::quote::__private::push_lt(&mut _s);
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "std");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "vec");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "Vec");
                            ::quote::__private::push_lt(&mut _s);
                            ::quote::ToTokens::to_tokens(&elem_ty, &mut _s);
                            ::quote::__private::push_gt(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "as");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "from_r");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "TryFromSexp");
                            ::quote::__private::push_gt(&mut _s);
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "try_from_sexp");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_ident(&mut _s, "__elt");
                                    _s
                                });
                            ::quote::__private::push_dot(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "map_err");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_or(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "e");
                                    ::quote::__private::push_or(&mut _s);
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "std");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "format");
                                    ::quote::__private::push_bang(&mut _s);
                                    ::quote::__private::push_group(&mut _s,
                                        ::quote::__private::Delimiter::Parenthesis,
                                        {
                                            let mut _s = ::quote::__private::TokenStream::new();
                                            ::quote::__private::parse(&mut _s,
                                                "\"column `{}` element {} could not be converted to the expected type: {}\"");
                                            ::quote::__private::push_comma(&mut _s);
                                            ::quote::ToTokens::to_tokens(&col_name_str, &mut _s);
                                            ::quote::__private::push_comma(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "__j");
                                            ::quote::__private::push_comma(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "e");
                                            _s
                                        });
                                    _s
                                });
                            ::quote::__private::push_question(&mut _s);
                            ::quote::__private::push_semi(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "__v");
                            ::quote::__private::push_dot(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "push");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "core");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "convert");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "Into");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "into");
                                    ::quote::__private::push_group(&mut _s,
                                        ::quote::__private::Delimiter::Parenthesis,
                                        {
                                            let mut _s = ::quote::__private::TokenStream::new();
                                            ::quote::__private::push_ident(&mut _s, "__inner");
                                            _s
                                        });
                                    _s
                                });
                            ::quote::__private::push_semi(&mut _s);
                            _s
                        });
                    ::quote::__private::push_ident(&mut _s, "__v");
                    _s
                });
            ::quote::__private::push_ident(&mut _s, "else");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::parse(&mut _s, "0");
                            ::quote::__private::push_dot2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "__nrow");
                            _s
                        });
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "map");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_or(&mut _s);
                            ::quote::__private::push_underscore(&mut _s);
                            ::quote::__private::push_or(&mut _s);
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "core");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "convert");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "Into");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "into");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "std");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "vec");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "Vec");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_lt(&mut _s);
                                    ::quote::ToTokens::to_tokens(&elem_ty, &mut _s);
                                    ::quote::__private::push_gt(&mut _s);
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "new");
                                    ::quote::__private::push_group(&mut _s,
                                        ::quote::__private::Delimiter::Parenthesis,
                                        ::quote::__private::TokenStream::new());
                                    _s
                                });
                            _s
                        });
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "collect");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        ::quote::__private::TokenStream::new());
                    _s
                });
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    ::quote::__private::push_ident(&mut _s, "if");
    ::quote::ToTokens::to_tokens(&col_var, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "len");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_ne(&mut _s);
    ::quote::__private::push_ident(&mut _s, "__nrow");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "return");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "core");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "result");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Result");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Err");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "std");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "format");
                    ::quote::__private::push_bang(&mut _s);
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::parse(&mut _s,
                                "\"column `{}` has length {} but data.frame has {} rows\"");
                            ::quote::__private::push_comma(&mut _s);
                            ::quote::ToTokens::to_tokens(&col_name_str, &mut _s);
                            ::quote::__private::push_comma(&mut _s);
                            ::quote::ToTokens::to_tokens(&col_var, &mut _s);
                            ::quote::__private::push_dot(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "len");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                ::quote::__private::TokenStream::new());
                            ::quote::__private::push_comma(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "__nrow");
                            _s
                        });
                    _s
                });
            ::quote::__private::push_semi(&mut _s);
            _s
        });
    _s
}quote! {
2869                                let #col_var: ::std::vec::Vec<#field_ty> = {
2870                                    let __col_sexp = __view.column_raw(#col_name_str).ok_or_else(|| {
2871                                        ::std::format!("column `{}` is missing from the data.frame", #col_name_str)
2872                                    })?;
2873                                    // VECSXP check via `SexpExt::is_list` (UFCS — avoids the
2874                                    // `List::is_list()` bug that calls `is_pair_list()` instead).
2875                                    if <::miniextendr_api::SEXP as ::miniextendr_api::SexpExt>::is_list(&__col_sexp) {
2876                                        let __list = unsafe {
2877                                            ::miniextendr_api::list::List::from_raw(__col_sexp)
2878                                        };
2879                                        let __len = __list.len();
2880                                        let mut __v: ::std::vec::Vec<#field_ty> = ::std::vec::Vec::with_capacity(__len as usize);
2881                                        for __j in 0..__len {
2882                                            // in-bounds by construction (0..len)
2883                                            let __elt = __list.get(__j).unwrap();
2884                                            let __inner: ::std::vec::Vec<#elem_ty> =
2885                                                <::std::vec::Vec<#elem_ty> as ::miniextendr_api::from_r::TryFromSexp>::try_from_sexp(__elt)
2886                                                    .map_err(|e| ::std::format!(
2887                                                        "column `{}` element {} could not be converted to the expected type: {}",
2888                                                        #col_name_str, __j, e
2889                                                    ))?;
2890                                            __v.push(::core::convert::Into::into(__inner));
2891                                        }
2892                                        __v
2893                                    } else {
2894                                        // Non-list column → every row is an empty collection.
2895                                        (0..__nrow)
2896                                            .map(|_| ::core::convert::Into::into(::std::vec::Vec::<#elem_ty>::new()))
2897                                            .collect()
2898                                    }
2899                                };
2900                                if #col_var.len() != __nrow {
2901                                    return ::core::result::Result::Err(::std::format!(
2902                                        "column `{}` has length {} but data.frame has {} rows",
2903                                        #col_name_str, #col_var.len(), __nrow
2904                                    ));
2905                                }
2906                            });
2907                            seq_decls.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::__private::push_ident(&mut _s, "mut");
    ::quote::ToTokens::to_tokens(&it_var, &mut _s);
    ::quote::__private::push_eq(&mut _s);
    ::quote::ToTokens::to_tokens(&col_var, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "into_iter");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! { let mut #it_var = #col_var.into_iter(); });
2908                            seq_builds.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&rust_name, &mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::ToTokens::to_tokens(&it_var, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "next");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "unwrap");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    _s
}quote! { #rust_name: #it_var.next().unwrap() });
2909                            par_builds.push(
2910                                {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&rust_name, &mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "clone");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Clone");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "clone");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_and(&mut _s);
            ::quote::ToTokens::to_tokens(&col_var, &mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Bracket,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "__i");
                    _s
                });
            _s
        });
    _s
}quote! { #rust_name: ::core::clone::Clone::clone(&#col_var[__i]) },
2911                            );
2912                        }
2913                        // Scalar Single — and reader-capable map Single (#764):
2914                        // `pull_col`'s `Vec<#ty>: TryFromSexp` covers both
2915                        // (maps via the list-of-named-lists impl).
2916                        ::core::option::Option::None => {
2917                            extracts.push(pull_col(
2918                                &col_var,
2919                                &data.col_name_str,
2920                                &data.ty,
2921                                data.is_factor,
2922                            ));
2923                            seq_decls.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::__private::push_ident(&mut _s, "mut");
    ::quote::ToTokens::to_tokens(&it_var, &mut _s);
    ::quote::__private::push_eq(&mut _s);
    ::quote::ToTokens::to_tokens(&col_var, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "into_iter");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! { let mut #it_var = #col_var.into_iter(); });
2924                            seq_builds.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&rust_name, &mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::ToTokens::to_tokens(&it_var, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "next");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "unwrap");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    _s
}quote! { #rust_name: #it_var.next().unwrap() });
2925                            par_builds.push(
2926                                {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&rust_name, &mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "clone");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Clone");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "clone");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_and(&mut _s);
            ::quote::ToTokens::to_tokens(&col_var, &mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Bracket,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "__i");
                    _s
                });
            _s
        });
    _s
}quote! { #rust_name: ::core::clone::Clone::clone(&#col_var[__i]) },
2927                            );
2928                        }
2929                    }
2930                }
2931                // `[T; N]` → columns `base_1..base_N`, each a plain `Vec<elem>`.
2932                // Regroup into the fixed array per row.
2933                ResolvedField::ExpandedFixed(data) => {
2934                    let rust_name = &data.rust_name;
2935                    let elem_ty = &data.elem_ty;
2936                    let mut it_nexts: Vec<TokenStream> = Vec::new();
2937                    let mut idx_clones: Vec<TokenStream> = Vec::new();
2938                    for k in 1..=data.len {
2939                        let col_var =
2940                            match ::quote::__private::IdentFragmentAdapter(&crate::naming::unraw(rust_name))
    {
    arg =>
        match ::quote::__private::IdentFragmentAdapter(&k) {
            arg =>
                ::quote::__private::mk_ident(&::alloc::__export::must_use({
                                ::alloc::fmt::format(format_args!("__ef_{0}_{1}", arg, arg))
                            }),
                    ::quote::__private::Option::None.or(arg.span()).or(arg.span())),
        },
}format_ident!("__ef_{}_{}", crate::naming::unraw(rust_name), k);
2941                        let it_var =
2942                            match ::quote::__private::IdentFragmentAdapter(&crate::naming::unraw(rust_name))
    {
    arg =>
        match ::quote::__private::IdentFragmentAdapter(&k) {
            arg =>
                ::quote::__private::mk_ident(&::alloc::__export::must_use({
                                ::alloc::fmt::format(format_args!("__efit_{0}_{1}", arg,
                                        arg))
                            }),
                    ::quote::__private::Option::None.or(arg.span()).or(arg.span())),
        },
}format_ident!("__efit_{}_{}", crate::naming::unraw(rust_name), k);
2943                        let col_name_str = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}_{1}", data.base_name, k))
    })format!("{}_{}", data.base_name, k);
2944                        extracts.push(pull_col(&col_var, &col_name_str, elem_ty, false));
2945                        seq_decls.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::__private::push_ident(&mut _s, "mut");
    ::quote::ToTokens::to_tokens(&it_var, &mut _s);
    ::quote::__private::push_eq(&mut _s);
    ::quote::ToTokens::to_tokens(&col_var, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "into_iter");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! { let mut #it_var = #col_var.into_iter(); });
2946                        it_nexts.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&it_var, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "next");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "unwrap");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    _s
}quote! { #it_var.next().unwrap() });
2947                        idx_clones.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "clone");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Clone");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "clone");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_and(&mut _s);
            ::quote::ToTokens::to_tokens(&col_var, &mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Bracket,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "__i");
                    _s
                });
            _s
        });
    _s
}quote! { ::core::clone::Clone::clone(&#col_var[__i]) });
2948                    }
2949                    seq_builds.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&rust_name, &mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            {
                use ::quote::__private::ext::*;
                let mut _first = true;
                let has_iter = ::quote::__private::HasIterator::<false>;
                #[allow(unused_mut)]
                let (mut it_nexts, i) = it_nexts.quote_into_iter();
                let has_iter = has_iter | i;
                <_ as
                        ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                while true {
                    let it_nexts =
                        match it_nexts.next() {
                            Some(_x) => ::quote::__private::RepInterp(_x),
                            None => break,
                        };
                    if !_first { ::quote::__private::push_comma(&mut _s); }
                    _first = false;
                    ::quote::ToTokens::to_tokens(&it_nexts, &mut _s);
                }
            }
            _s
        });
    _s
}quote! { #rust_name: [ #(#it_nexts),* ] });
2950                    par_builds.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&rust_name, &mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            {
                use ::quote::__private::ext::*;
                let mut _first = true;
                let has_iter = ::quote::__private::HasIterator::<false>;
                #[allow(unused_mut)]
                let (mut idx_clones, i) = idx_clones.quote_into_iter();
                let has_iter = has_iter | i;
                <_ as
                        ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                while true {
                    let idx_clones =
                        match idx_clones.next() {
                            Some(_x) => ::quote::__private::RepInterp(_x),
                            None => break,
                        };
                    if !_first { ::quote::__private::push_comma(&mut _s); }
                    _first = false;
                    ::quote::ToTokens::to_tokens(&idx_clones, &mut _s);
                }
            }
            _s
        });
    _s
}quote! { #rust_name: [ #(#idx_clones),* ] });
2951                }
2952                // `Vec<T>` + `width = N` → columns `base_1..base_N`, each
2953                // `Vec<Option<elem>>`. Flatten the N optionals per row back into a
2954                // `Vec<elem>` (trailing-NA padding from the write side drops out).
2955                ResolvedField::ExpandedVec(data) => {
2956                    let rust_name = &data.rust_name;
2957                    let elem_ty = &data.elem_ty;
2958                    let opt_ty: syn::Type = ::syn::__private::parse_quote({
        let mut _s = ::quote::__private::TokenStream::new();
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "core");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "option");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "Option");
        ::quote::__private::push_lt(&mut _s);
        ::quote::ToTokens::to_tokens(&elem_ty, &mut _s);
        ::quote::__private::push_gt(&mut _s);
        _s
    })syn::parse_quote!(::core::option::Option<#elem_ty>);
2959                    let mut it_nexts: Vec<TokenStream> = Vec::new();
2960                    let mut idx_clones: Vec<TokenStream> = Vec::new();
2961                    for k in 1..=data.width {
2962                        let col_var =
2963                            match ::quote::__private::IdentFragmentAdapter(&crate::naming::unraw(rust_name))
    {
    arg =>
        match ::quote::__private::IdentFragmentAdapter(&k) {
            arg =>
                ::quote::__private::mk_ident(&::alloc::__export::must_use({
                                ::alloc::fmt::format(format_args!("__ev_{0}_{1}", arg, arg))
                            }),
                    ::quote::__private::Option::None.or(arg.span()).or(arg.span())),
        },
}format_ident!("__ev_{}_{}", crate::naming::unraw(rust_name), k);
2964                        let it_var =
2965                            match ::quote::__private::IdentFragmentAdapter(&crate::naming::unraw(rust_name))
    {
    arg =>
        match ::quote::__private::IdentFragmentAdapter(&k) {
            arg =>
                ::quote::__private::mk_ident(&::alloc::__export::must_use({
                                ::alloc::fmt::format(format_args!("__evit_{0}_{1}", arg,
                                        arg))
                            }),
                    ::quote::__private::Option::None.or(arg.span()).or(arg.span())),
        },
}format_ident!("__evit_{}_{}", crate::naming::unraw(rust_name), k);
2966                        let col_name_str = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}_{1}", data.base_name, k))
    })format!("{}_{}", data.base_name, k);
2967                        extracts.push(pull_col(&col_var, &col_name_str, &opt_ty, false));
2968                        seq_decls.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::__private::push_ident(&mut _s, "mut");
    ::quote::ToTokens::to_tokens(&it_var, &mut _s);
    ::quote::__private::push_eq(&mut _s);
    ::quote::ToTokens::to_tokens(&col_var, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "into_iter");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! { let mut #it_var = #col_var.into_iter(); });
2969                        it_nexts.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&it_var, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "next");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "unwrap");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    _s
}quote! { #it_var.next().unwrap() });
2970                        idx_clones.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "clone");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Clone");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "clone");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_and(&mut _s);
            ::quote::ToTokens::to_tokens(&col_var, &mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Bracket,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "__i");
                    _s
                });
            _s
        });
    _s
}quote! { ::core::clone::Clone::clone(&#col_var[__i]) });
2971                    }
2972                    // `.into()` converts the collected `Vec<elem>` to the field's
2973                    // own container type (`Vec<T>` identity or `Box<[T]>`).
2974                    seq_builds.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&rust_name, &mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            {
                use ::quote::__private::ext::*;
                let mut _first = true;
                let has_iter = ::quote::__private::HasIterator::<false>;
                #[allow(unused_mut)]
                let (mut it_nexts, i) = it_nexts.quote_into_iter();
                let has_iter = has_iter | i;
                <_ as
                        ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                while true {
                    let it_nexts =
                        match it_nexts.next() {
                            Some(_x) => ::quote::__private::RepInterp(_x),
                            None => break,
                        };
                    if !_first { ::quote::__private::push_comma(&mut _s); }
                    _first = false;
                    ::quote::ToTokens::to_tokens(&it_nexts, &mut _s);
                }
            }
            _s
        });
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "into_iter");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "flatten");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "collect");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_lt(&mut _s);
    ::quote::ToTokens::to_tokens(&elem_ty, &mut _s);
    ::quote::__private::push_shr(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "into");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    _s
}quote! {
2975                        #rust_name: [ #(#it_nexts),* ]
2976                            .into_iter().flatten().collect::<::std::vec::Vec<#elem_ty>>().into()
2977                    });
2978                    par_builds.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&rust_name, &mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            {
                use ::quote::__private::ext::*;
                let mut _first = true;
                let has_iter = ::quote::__private::HasIterator::<false>;
                #[allow(unused_mut)]
                let (mut idx_clones, i) = idx_clones.quote_into_iter();
                let has_iter = has_iter | i;
                <_ as
                        ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                while true {
                    let idx_clones =
                        match idx_clones.next() {
                            Some(_x) => ::quote::__private::RepInterp(_x),
                            None => break,
                        };
                    if !_first { ::quote::__private::push_comma(&mut _s); }
                    _first = false;
                    ::quote::ToTokens::to_tokens(&idx_clones, &mut _s);
                }
            }
            _s
        });
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "into_iter");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "flatten");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "collect");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_lt(&mut _s);
    ::quote::ToTokens::to_tokens(&elem_ty, &mut _s);
    ::quote::__private::push_shr(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "into");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    _s
}quote! {
2979                        #rust_name: [ #(#idx_clones),* ]
2980                            .into_iter().flatten().collect::<::std::vec::Vec<#elem_ty>>().into()
2981                    });
2982                }
2983                // `Vec<T>`/`Box<[T]>` + `expand` → a runtime-determined number of
2984                // columns `name_1..name_k`, each `Vec<Option<elem>>`. Discover them
2985                // by walking `name_<i>` until the first gap, then flatten per row.
2986                ResolvedField::AutoExpandVec(data) => {
2987                    let rust_name = &data.rust_name;
2988                    let elem_ty = &data.elem_ty;
2989                    let cols_var = match ::quote::__private::IdentFragmentAdapter(&crate::naming::unraw(rust_name))
    {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("__aev_{0}", arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("__aev_{}", crate::naming::unraw(rust_name));
2990                    let col_name_str = &data.col_name_str;
2991                    extracts.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::ToTokens::to_tokens(&cols_var, &mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "option");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Option");
    ::quote::__private::push_lt(&mut _s);
    ::quote::ToTokens::to_tokens(&elem_ty, &mut _s);
    ::quote::__private::push_shr(&mut _s);
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_eq(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "let");
            ::quote::__private::push_ident(&mut _s, "mut");
            ::quote::__private::push_ident(&mut _s, "__cols");
            ::quote::__private::push_colon(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "std");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "vec");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Vec");
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "std");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "vec");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Vec");
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "core");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "option");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Option");
            ::quote::__private::push_lt(&mut _s);
            ::quote::ToTokens::to_tokens(&elem_ty, &mut _s);
            ::quote::__private::push_shr(&mut _s);
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "std");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "vec");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Vec");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "new");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            ::quote::__private::push_semi(&mut _s);
            ::quote::__private::push_ident(&mut _s, "let");
            ::quote::__private::push_ident(&mut _s, "mut");
            ::quote::__private::push_ident(&mut _s, "__k");
            ::quote::__private::push_colon(&mut _s);
            ::quote::__private::push_ident(&mut _s, "usize");
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::parse(&mut _s, "1");
            ::quote::__private::push_semi(&mut _s);
            ::quote::__private::push_ident(&mut _s, "loop");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "let");
                    ::quote::__private::push_ident(&mut _s, "__cn");
                    ::quote::__private::push_eq(&mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "std");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "format");
                    ::quote::__private::push_bang(&mut _s);
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::parse(&mut _s, "\"{}_{}\"");
                            ::quote::__private::push_comma(&mut _s);
                            ::quote::ToTokens::to_tokens(&col_name_str, &mut _s);
                            ::quote::__private::push_comma(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "__k");
                            _s
                        });
                    ::quote::__private::push_semi(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "match");
                    ::quote::__private::push_ident(&mut _s, "__view");
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "column_raw");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_and(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "__cn");
                            _s
                        });
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Brace,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "core");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "option");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "Option");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "Some");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_ident(&mut _s, "__s");
                                    _s
                                });
                            ::quote::__private::push_fat_arrow(&mut _s);
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Brace,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_ident(&mut _s, "let");
                                    ::quote::__private::push_ident(&mut _s, "__c");
                                    ::quote::__private::push_colon(&mut _s);
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "std");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "vec");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "Vec");
                                    ::quote::__private::push_lt(&mut _s);
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "core");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "option");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "Option");
                                    ::quote::__private::push_lt(&mut _s);
                                    ::quote::ToTokens::to_tokens(&elem_ty, &mut _s);
                                    ::quote::__private::push_shr(&mut _s);
                                    ::quote::__private::push_eq(&mut _s);
                                    ::quote::__private::push_lt(&mut _s);
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "std");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "vec");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "Vec");
                                    ::quote::__private::push_lt(&mut _s);
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "core");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "option");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "Option");
                                    ::quote::__private::push_lt(&mut _s);
                                    ::quote::ToTokens::to_tokens(&elem_ty, &mut _s);
                                    ::quote::__private::push_shr(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "as");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "miniextendr_api");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "from_r");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "TryFromSexp");
                                    ::quote::__private::push_gt(&mut _s);
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "try_from_sexp");
                                    ::quote::__private::push_group(&mut _s,
                                        ::quote::__private::Delimiter::Parenthesis,
                                        {
                                            let mut _s = ::quote::__private::TokenStream::new();
                                            ::quote::__private::push_ident(&mut _s, "__s");
                                            _s
                                        });
                                    ::quote::__private::push_dot(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "map_err");
                                    ::quote::__private::push_group(&mut _s,
                                        ::quote::__private::Delimiter::Parenthesis,
                                        {
                                            let mut _s = ::quote::__private::TokenStream::new();
                                            ::quote::__private::push_or(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "e");
                                            ::quote::__private::push_or(&mut _s);
                                            ::quote::__private::push_colon2(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "std");
                                            ::quote::__private::push_colon2(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "format");
                                            ::quote::__private::push_bang(&mut _s);
                                            ::quote::__private::push_group(&mut _s,
                                                ::quote::__private::Delimiter::Parenthesis,
                                                {
                                                    let mut _s = ::quote::__private::TokenStream::new();
                                                    ::quote::__private::parse(&mut _s,
                                                        "\"column `{}` could not be converted to the expected type: {}\"");
                                                    ::quote::__private::push_comma(&mut _s);
                                                    ::quote::__private::push_ident(&mut _s, "__cn");
                                                    ::quote::__private::push_comma(&mut _s);
                                                    ::quote::__private::push_ident(&mut _s, "e");
                                                    _s
                                                });
                                            _s
                                        });
                                    ::quote::__private::push_question(&mut _s);
                                    ::quote::__private::push_semi(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "if");
                                    ::quote::__private::push_ident(&mut _s, "__c");
                                    ::quote::__private::push_dot(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "len");
                                    ::quote::__private::push_group(&mut _s,
                                        ::quote::__private::Delimiter::Parenthesis,
                                        ::quote::__private::TokenStream::new());
                                    ::quote::__private::push_ne(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "__nrow");
                                    ::quote::__private::push_group(&mut _s,
                                        ::quote::__private::Delimiter::Brace,
                                        {
                                            let mut _s = ::quote::__private::TokenStream::new();
                                            ::quote::__private::push_ident(&mut _s, "return");
                                            ::quote::__private::push_colon2(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "core");
                                            ::quote::__private::push_colon2(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "result");
                                            ::quote::__private::push_colon2(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "Result");
                                            ::quote::__private::push_colon2(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "Err");
                                            ::quote::__private::push_group(&mut _s,
                                                ::quote::__private::Delimiter::Parenthesis,
                                                {
                                                    let mut _s = ::quote::__private::TokenStream::new();
                                                    ::quote::__private::push_colon2(&mut _s);
                                                    ::quote::__private::push_ident(&mut _s, "std");
                                                    ::quote::__private::push_colon2(&mut _s);
                                                    ::quote::__private::push_ident(&mut _s, "format");
                                                    ::quote::__private::push_bang(&mut _s);
                                                    ::quote::__private::push_group(&mut _s,
                                                        ::quote::__private::Delimiter::Parenthesis,
                                                        {
                                                            let mut _s = ::quote::__private::TokenStream::new();
                                                            ::quote::__private::parse(&mut _s,
                                                                "\"column `{}` has length {} but data.frame has {} rows\"");
                                                            ::quote::__private::push_comma(&mut _s);
                                                            ::quote::__private::push_ident(&mut _s, "__cn");
                                                            ::quote::__private::push_comma(&mut _s);
                                                            ::quote::__private::push_ident(&mut _s, "__c");
                                                            ::quote::__private::push_dot(&mut _s);
                                                            ::quote::__private::push_ident(&mut _s, "len");
                                                            ::quote::__private::push_group(&mut _s,
                                                                ::quote::__private::Delimiter::Parenthesis,
                                                                ::quote::__private::TokenStream::new());
                                                            ::quote::__private::push_comma(&mut _s);
                                                            ::quote::__private::push_ident(&mut _s, "__nrow");
                                                            _s
                                                        });
                                                    _s
                                                });
                                            ::quote::__private::push_semi(&mut _s);
                                            _s
                                        });
                                    ::quote::__private::push_ident(&mut _s, "__cols");
                                    ::quote::__private::push_dot(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "push");
                                    ::quote::__private::push_group(&mut _s,
                                        ::quote::__private::Delimiter::Parenthesis,
                                        {
                                            let mut _s = ::quote::__private::TokenStream::new();
                                            ::quote::__private::push_ident(&mut _s, "__c");
                                            _s
                                        });
                                    ::quote::__private::push_semi(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "__k");
                                    ::quote::__private::push_add_eq(&mut _s);
                                    ::quote::__private::parse(&mut _s, "1");
                                    ::quote::__private::push_semi(&mut _s);
                                    _s
                                });
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "core");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "option");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "Option");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "None");
                            ::quote::__private::push_fat_arrow(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "break");
                            ::quote::__private::push_comma(&mut _s);
                            _s
                        });
                    _s
                });
            ::quote::__private::push_ident(&mut _s, "__cols");
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! {
2992                        let #cols_var: ::std::vec::Vec<::std::vec::Vec<::core::option::Option<#elem_ty>>> = {
2993                            let mut __cols: ::std::vec::Vec<::std::vec::Vec<::core::option::Option<#elem_ty>>> =
2994                                ::std::vec::Vec::new();
2995                            let mut __k: usize = 1;
2996                            loop {
2997                                let __cn = ::std::format!("{}_{}", #col_name_str, __k);
2998                                match __view.column_raw(&__cn) {
2999                                    ::core::option::Option::Some(__s) => {
3000                                        let __c: ::std::vec::Vec<::core::option::Option<#elem_ty>> =
3001                                            <::std::vec::Vec<::core::option::Option<#elem_ty>> as ::miniextendr_api::from_r::TryFromSexp>::try_from_sexp(__s)
3002                                                .map_err(|e| ::std::format!(
3003                                                    "column `{}` could not be converted to the expected type: {}",
3004                                                    __cn, e
3005                                                ))?;
3006                                        if __c.len() != __nrow {
3007                                            return ::core::result::Result::Err(::std::format!(
3008                                                "column `{}` has length {} but data.frame has {} rows",
3009                                                __cn, __c.len(), __nrow
3010                                            ));
3011                                        }
3012                                        __cols.push(__c);
3013                                        __k += 1;
3014                                    }
3015                                    ::core::option::Option::None => break,
3016                                }
3017                            }
3018                            __cols
3019                        };
3020                    });
3021                    // Both seq and par index by row (`__i`): the columns are a
3022                    // `Vec<Vec<…>>`, so there is nothing to drain field-wise.
3023                    let build = {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&rust_name, &mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::ToTokens::to_tokens(&cols_var, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "iter");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "filter_map");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_or(&mut _s);
            ::quote::__private::push_ident(&mut _s, "__c");
            ::quote::__private::push_or(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "core");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "clone");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Clone");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "clone");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "__c");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Bracket,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "__i");
                            _s
                        });
                    _s
                });
            _s
        });
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "collect");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_lt(&mut _s);
    ::quote::ToTokens::to_tokens(&elem_ty, &mut _s);
    ::quote::__private::push_shr(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "into");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    _s
}quote! {
3024                        #rust_name: #cols_var
3025                            .iter()
3026                            .filter_map(|__c| ::core::clone::Clone::clone(&__c[__i]))
3027                            .collect::<::std::vec::Vec<#elem_ty>>()
3028                            .into()
3029                    };
3030                    seq_builds.push(build.clone());
3031                    par_builds.push(build);
3032                }
3033                // Nested `DataFrameRow` (#485): the inner type's columns were
3034                // written under a `<base>_` prefix. Select those parent columns,
3035                // strip the prefix into a fresh sub-frame, and recurse through the
3036                // inner type's `DataFrameRowConvert` reader. Routing through the
3037                // trait (rather than `Inner::try_from_dataframe`) keeps this
3038                // compiling even when the inner shape has no reader — it degrades
3039                // to a clear runtime error instead.
3040                ResolvedField::Struct(data) => {
3041                    let rust_name = &data.rust_name;
3042                    let inner_ty = &data.inner_ty;
3043                    let vec_var = match ::quote::__private::IdentFragmentAdapter(&crate::naming::unraw(rust_name))
    {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("__sf_{0}", arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("__sf_{}", crate::naming::unraw(rust_name));
3044                    let it_var = match ::quote::__private::IdentFragmentAdapter(&crate::naming::unraw(rust_name))
    {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("__sfit_{0}", arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("__sfit_{}", crate::naming::unraw(rust_name));
3045                    let base = &data.col_name_str;
3046                    let prefix_lit = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}_", data.col_name_str))
    })format!("{}_", data.col_name_str);
3047                    extracts.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::ToTokens::to_tokens(&vec_var, &mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_lt(&mut _s);
    ::quote::ToTokens::to_tokens(&inner_ty, &mut _s);
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_eq(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "let");
            ::quote::__private::push_ident(&mut _s, "__prefix");
            ::quote::__private::push_colon(&mut _s);
            ::quote::__private::push_and(&mut _s);
            ::quote::__private::push_ident(&mut _s, "str");
            ::quote::__private::push_eq(&mut _s);
            ::quote::ToTokens::to_tokens(&prefix_lit, &mut _s);
            ::quote::__private::push_semi(&mut _s);
            ::quote::__private::push_ident(&mut _s, "let");
            ::quote::__private::push_ident(&mut _s, "__names");
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::push_ident(&mut _s, "__view");
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "names");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            ::quote::__private::push_semi(&mut _s);
            ::quote::__private::push_ident(&mut _s, "let");
            ::quote::__private::push_ident(&mut _s, "__sel");
            ::quote::__private::push_colon(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "std");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "vec");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Vec");
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_and(&mut _s);
            ::quote::__private::push_ident(&mut _s, "str");
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::push_ident(&mut _s, "__names");
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "iter");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "filter");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_or(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "__n");
                    ::quote::__private::push_or(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "__n");
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "starts_with");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "__prefix");
                            _s
                        });
                    _s
                });
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "map");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_or(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "__n");
                    ::quote::__private::push_or(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "__n");
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "as_str");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        ::quote::__private::TokenStream::new());
                    _s
                });
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "collect");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            ::quote::__private::push_semi(&mut _s);
            ::quote::__private::push_ident(&mut _s, "if");
            ::quote::__private::push_ident(&mut _s, "__sel");
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "is_empty");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "return");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "core");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "result");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Result");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Err");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "std");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "format");
                            ::quote::__private::push_bang(&mut _s);
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::parse(&mut _s,
                                        "\"struct column `{}`: no columns with prefix `{}` found in the data.frame\"");
                                    ::quote::__private::push_comma(&mut _s);
                                    ::quote::ToTokens::to_tokens(&base, &mut _s);
                                    ::quote::__private::push_comma(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "__prefix");
                                    _s
                                });
                            _s
                        });
                    ::quote::__private::push_semi(&mut _s);
                    _s
                });
            ::quote::__private::push_ident(&mut _s, "let");
            ::quote::__private::push_ident(&mut _s, "__sub");
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::push_ident(&mut _s, "__view");
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "select");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "__sel");
                    _s
                });
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "strip_prefix");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "__prefix");
                    _s
                });
            ::quote::__private::push_semi(&mut _s);
            ::quote::__private::push_ident(&mut _s, "let");
            ::quote::__private::push_ident(&mut _s, "__out");
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::push_ident(&mut _s, "match");
            ::quote::__private::push_lt(&mut _s);
            ::quote::ToTokens::to_tokens(&inner_ty, &mut _s);
            ::quote::__private::push_ident(&mut _s, "as");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "dataframe");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "DataFrameRowConvert");
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "rows_from_dataframe");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "__sub");
                    _s
                });
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "core");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "option");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Option");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Some");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "core");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "result");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "Result");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "Ok");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_ident(&mut _s, "__v");
                                    _s
                                });
                            _s
                        });
                    ::quote::__private::push_fat_arrow(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "__v");
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "core");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "option");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Option");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Some");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "core");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "result");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "Result");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "Err");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_ident(&mut _s, "__e");
                                    _s
                                });
                            _s
                        });
                    ::quote::__private::push_fat_arrow(&mut _s);
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Brace,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "return");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "core");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "result");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "Result");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "Err");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "std");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "format");
                                    ::quote::__private::push_bang(&mut _s);
                                    ::quote::__private::push_group(&mut _s,
                                        ::quote::__private::Delimiter::Parenthesis,
                                        {
                                            let mut _s = ::quote::__private::TokenStream::new();
                                            ::quote::__private::parse(&mut _s,
                                                "\"struct column `{}`: {}\"");
                                            ::quote::__private::push_comma(&mut _s);
                                            ::quote::ToTokens::to_tokens(&base, &mut _s);
                                            ::quote::__private::push_comma(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "__e");
                                            _s
                                        });
                                    _s
                                });
                            ::quote::__private::push_semi(&mut _s);
                            _s
                        });
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "core");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "option");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Option");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "None");
                    ::quote::__private::push_fat_arrow(&mut _s);
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Brace,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "return");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "core");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "result");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "Result");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "Err");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "std");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "format");
                                    ::quote::__private::push_bang(&mut _s);
                                    ::quote::__private::push_group(&mut _s,
                                        ::quote::__private::Delimiter::Parenthesis,
                                        {
                                            let mut _s = ::quote::__private::TokenStream::new();
                                            ::quote::__private::parse(&mut _s,
                                                "\"struct column `{}`: nested type has no data.frame reader\"");
                                            ::quote::__private::push_comma(&mut _s);
                                            ::quote::ToTokens::to_tokens(&base, &mut _s);
                                            _s
                                        });
                                    _s
                                });
                            ::quote::__private::push_semi(&mut _s);
                            _s
                        });
                    _s
                });
            ::quote::__private::push_semi(&mut _s);
            ::quote::__private::push_ident(&mut _s, "__out");
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    ::quote::__private::push_ident(&mut _s, "if");
    ::quote::ToTokens::to_tokens(&vec_var, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "len");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_ne(&mut _s);
    ::quote::__private::push_ident(&mut _s, "__nrow");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "return");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "core");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "result");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Result");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Err");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "std");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "format");
                    ::quote::__private::push_bang(&mut _s);
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::parse(&mut _s,
                                "\"struct column `{}` produced {} rows but data.frame has {} rows\"");
                            ::quote::__private::push_comma(&mut _s);
                            ::quote::ToTokens::to_tokens(&base, &mut _s);
                            ::quote::__private::push_comma(&mut _s);
                            ::quote::ToTokens::to_tokens(&vec_var, &mut _s);
                            ::quote::__private::push_dot(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "len");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                ::quote::__private::TokenStream::new());
                            ::quote::__private::push_comma(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "__nrow");
                            _s
                        });
                    _s
                });
            ::quote::__private::push_semi(&mut _s);
            _s
        });
    _s
}quote! {
3048                        let #vec_var: ::std::vec::Vec<#inner_ty> = {
3049                            let __prefix: &str = #prefix_lit;
3050                            let __names = __view.names();
3051                            let __sel: ::std::vec::Vec<&str> = __names
3052                                .iter()
3053                                .filter(|__n| __n.starts_with(__prefix))
3054                                .map(|__n| __n.as_str())
3055                                .collect();
3056                            if __sel.is_empty() {
3057                                return ::core::result::Result::Err(::std::format!(
3058                                    "struct column `{}`: no columns with prefix `{}` found in the data.frame",
3059                                    #base, __prefix
3060                                ));
3061                            }
3062                            // `select` returns an owned, GC-rooted `BuiltDataFrame`
3063                            // (#1247); `strip_prefix` (inherent forward) edits the
3064                            // same frame in place and carries the handle through, so
3065                            // the sub-frame stays rooted across the CHARSXP
3066                            // allocations and the recursive read below.
3067                            let __sub = __view.select(&__sel).strip_prefix(__prefix);
3068                            let __out = match <#inner_ty as ::miniextendr_api::dataframe::DataFrameRowConvert>::rows_from_dataframe(&__sub) {
3069                                ::core::option::Option::Some(::core::result::Result::Ok(__v)) => __v,
3070                                ::core::option::Option::Some(::core::result::Result::Err(__e)) => {
3071                                    return ::core::result::Result::Err(::std::format!(
3072                                        "struct column `{}`: {}", #base, __e
3073                                    ));
3074                                }
3075                                ::core::option::Option::None => {
3076                                    return ::core::result::Result::Err(::std::format!(
3077                                        "struct column `{}`: nested type has no data.frame reader", #base
3078                                    ));
3079                                }
3080                            };
3081                            __out
3082                        };
3083                        if #vec_var.len() != __nrow {
3084                            return ::core::result::Result::Err(::std::format!(
3085                                "struct column `{}` produced {} rows but data.frame has {} rows",
3086                                #base, #vec_var.len(), __nrow
3087                            ));
3088                        }
3089                    });
3090                    seq_decls.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::__private::push_ident(&mut _s, "mut");
    ::quote::ToTokens::to_tokens(&it_var, &mut _s);
    ::quote::__private::push_eq(&mut _s);
    ::quote::ToTokens::to_tokens(&vec_var, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "into_iter");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! { let mut #it_var = #vec_var.into_iter(); });
3091                    seq_builds.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&rust_name, &mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::ToTokens::to_tokens(&it_var, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "next");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "unwrap");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    _s
}quote! { #rust_name: #it_var.next().unwrap() });
3092                    par_builds
3093                        .push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&rust_name, &mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "clone");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Clone");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "clone");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_and(&mut _s);
            ::quote::ToTokens::to_tokens(&vec_var, &mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Bracket,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "__i");
                    _s
                });
            _s
        });
    _s
}quote! { #rust_name: ::core::clone::Clone::clone(&#vec_var[__i]) });
3094                }
3095                // Non-String-keyed map (#919): read two parallel list-columns
3096                // `<base>_keys` / `<base>_values` (VECSXP of typed vectors), then
3097                // zip keys[i] with values[i] back into the map type per row.
3098                // NULL VECSXP elements → empty Vec (not None — struct path uses owned cols).
3099                // All SEXP access happens in `extracts` on the R thread; the
3100                // parallel iterator touches only owned Rust `Vec<Vec<K>>` / `Vec<Vec<V>>`.
3101                ResolvedField::Map(data) => {
3102                    let rust_name = &data.rust_name;
3103                    let key_ty = &data.key_ty;
3104                    let val_ty = &data.val_ty;
3105                    let map_ty = &data.map_ty;
3106                    let base = &data.base_name;
3107                    let keys_col_name = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}_keys", base))
    })format!("{}_keys", base);
3108                    let vals_col_name = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}_values", base))
    })format!("{}_values", base);
3109                    let keys_var = match ::quote::__private::IdentFragmentAdapter(&base.replace('-', "_")) {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("__mapcol_{0}_keys", arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("__mapcol_{}_keys", base.replace('-', "_"));
3110                    let vals_var = match ::quote::__private::IdentFragmentAdapter(&base.replace('-', "_")) {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("__mapcol_{0}_values",
                                arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("__mapcol_{}_values", base.replace('-', "_"));
3111                    let keys_it_var = match ::quote::__private::IdentFragmentAdapter(&base.replace('-', "_")) {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("__mapcol_it_{0}_keys",
                                arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("__mapcol_it_{}_keys", base.replace('-', "_"));
3112                    let vals_it_var =
3113                        match ::quote::__private::IdentFragmentAdapter(&base.replace('-', "_")) {
    arg =>
        ::quote::__private::mk_ident(&::alloc::__export::must_use({
                        ::alloc::fmt::format(format_args!("__mapcol_it_{0}_values",
                                arg))
                    }), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("__mapcol_it_{}_values", base.replace('-', "_"));
3114
3115                    // Extract helper: walk a VECSXP list-column; NULL/nil element → empty Vec.
3116                    let extract_col = |col_var: &syn::Ident,
3117                                       col_name: &str,
3118                                       elem_ty: &syn::Type| {
3119                        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::ToTokens::to_tokens(&col_var, &mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_lt(&mut _s);
    ::quote::ToTokens::to_tokens(&elem_ty, &mut _s);
    ::quote::__private::push_shr(&mut _s);
    ::quote::__private::push_eq(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "let");
            ::quote::__private::push_ident(&mut _s, "__col_sexp");
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::push_ident(&mut _s, "__view");
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "column_raw");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::ToTokens::to_tokens(&col_name, &mut _s);
                    _s
                });
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "ok_or_else");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_or_or(&mut _s);
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Brace,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "std");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "format");
                            ::quote::__private::push_bang(&mut _s);
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::parse(&mut _s,
                                        "\"column `{}` is missing from the data.frame\"");
                                    ::quote::__private::push_comma(&mut _s);
                                    ::quote::ToTokens::to_tokens(&col_name, &mut _s);
                                    _s
                                });
                            _s
                        });
                    _s
                });
            ::quote::__private::push_question(&mut _s);
            ::quote::__private::push_semi(&mut _s);
            ::quote::__private::push_ident(&mut _s, "if");
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "SEXP");
            ::quote::__private::push_ident(&mut _s, "as");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "SexpExt");
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "is_list");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "__col_sexp");
                    _s
                });
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "let");
                    ::quote::__private::push_ident(&mut _s, "__list");
                    ::quote::__private::push_eq(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "unsafe");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Brace,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "list");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "List");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "from_raw");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_ident(&mut _s, "__col_sexp");
                                    _s
                                });
                            _s
                        });
                    ::quote::__private::push_semi(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "let");
                    ::quote::__private::push_ident(&mut _s, "__len");
                    ::quote::__private::push_eq(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "__list");
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "len");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        ::quote::__private::TokenStream::new());
                    ::quote::__private::push_semi(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "let");
                    ::quote::__private::push_ident(&mut _s, "mut");
                    ::quote::__private::push_ident(&mut _s, "__v");
                    ::quote::__private::push_colon(&mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "std");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "vec");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Vec");
                    ::quote::__private::push_lt(&mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "std");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "vec");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Vec");
                    ::quote::__private::push_lt(&mut _s);
                    ::quote::ToTokens::to_tokens(&elem_ty, &mut _s);
                    ::quote::__private::push_shr(&mut _s);
                    ::quote::__private::push_eq(&mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "std");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "vec");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Vec");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "with_capacity");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "__len");
                            ::quote::__private::push_ident(&mut _s, "as");
                            ::quote::__private::push_ident(&mut _s, "usize");
                            _s
                        });
                    ::quote::__private::push_semi(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "for");
                    ::quote::__private::push_ident(&mut _s, "__j");
                    ::quote::__private::push_ident(&mut _s, "in");
                    ::quote::__private::parse(&mut _s, "0");
                    ::quote::__private::push_dot2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "__len");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Brace,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "let");
                            ::quote::__private::push_ident(&mut _s, "__elt");
                            ::quote::__private::push_eq(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "__list");
                            ::quote::__private::push_dot(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "get");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_ident(&mut _s, "__j");
                                    _s
                                });
                            ::quote::__private::push_dot(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "unwrap");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                ::quote::__private::TokenStream::new());
                            ::quote::__private::push_semi(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "if");
                            ::quote::__private::push_ident(&mut _s, "__elt");
                            ::quote::__private::push_eq_eq(&mut _s);
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "SEXP");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "nil");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                ::quote::__private::TokenStream::new());
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Brace,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_ident(&mut _s, "__v");
                                    ::quote::__private::push_dot(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "push");
                                    ::quote::__private::push_group(&mut _s,
                                        ::quote::__private::Delimiter::Parenthesis,
                                        {
                                            let mut _s = ::quote::__private::TokenStream::new();
                                            ::quote::__private::push_colon2(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "std");
                                            ::quote::__private::push_colon2(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "vec");
                                            ::quote::__private::push_colon2(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "Vec");
                                            ::quote::__private::push_colon2(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "new");
                                            ::quote::__private::push_group(&mut _s,
                                                ::quote::__private::Delimiter::Parenthesis,
                                                ::quote::__private::TokenStream::new());
                                            _s
                                        });
                                    ::quote::__private::push_semi(&mut _s);
                                    _s
                                });
                            ::quote::__private::push_ident(&mut _s, "else");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Brace,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_ident(&mut _s, "let");
                                    ::quote::__private::push_ident(&mut _s, "__inner");
                                    ::quote::__private::push_colon(&mut _s);
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "std");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "vec");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "Vec");
                                    ::quote::__private::push_lt(&mut _s);
                                    ::quote::ToTokens::to_tokens(&elem_ty, &mut _s);
                                    ::quote::__private::push_gt(&mut _s);
                                    ::quote::__private::push_eq(&mut _s);
                                    ::quote::__private::push_lt(&mut _s);
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "std");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "vec");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "Vec");
                                    ::quote::__private::push_lt(&mut _s);
                                    ::quote::ToTokens::to_tokens(&elem_ty, &mut _s);
                                    ::quote::__private::push_gt(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "as");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "miniextendr_api");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "from_r");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "TryFromSexp");
                                    ::quote::__private::push_gt(&mut _s);
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "try_from_sexp");
                                    ::quote::__private::push_group(&mut _s,
                                        ::quote::__private::Delimiter::Parenthesis,
                                        {
                                            let mut _s = ::quote::__private::TokenStream::new();
                                            ::quote::__private::push_ident(&mut _s, "__elt");
                                            _s
                                        });
                                    ::quote::__private::push_dot(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "map_err");
                                    ::quote::__private::push_group(&mut _s,
                                        ::quote::__private::Delimiter::Parenthesis,
                                        {
                                            let mut _s = ::quote::__private::TokenStream::new();
                                            ::quote::__private::push_or(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "e");
                                            ::quote::__private::push_or(&mut _s);
                                            ::quote::__private::push_colon2(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "std");
                                            ::quote::__private::push_colon2(&mut _s);
                                            ::quote::__private::push_ident(&mut _s, "format");
                                            ::quote::__private::push_bang(&mut _s);
                                            ::quote::__private::push_group(&mut _s,
                                                ::quote::__private::Delimiter::Parenthesis,
                                                {
                                                    let mut _s = ::quote::__private::TokenStream::new();
                                                    ::quote::__private::parse(&mut _s,
                                                        "\"column `{}` element {} could not be converted: {}\"");
                                                    ::quote::__private::push_comma(&mut _s);
                                                    ::quote::ToTokens::to_tokens(&col_name, &mut _s);
                                                    ::quote::__private::push_comma(&mut _s);
                                                    ::quote::__private::push_ident(&mut _s, "__j");
                                                    ::quote::__private::push_comma(&mut _s);
                                                    ::quote::__private::push_ident(&mut _s, "e");
                                                    _s
                                                });
                                            _s
                                        });
                                    ::quote::__private::push_question(&mut _s);
                                    ::quote::__private::push_semi(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "__v");
                                    ::quote::__private::push_dot(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "push");
                                    ::quote::__private::push_group(&mut _s,
                                        ::quote::__private::Delimiter::Parenthesis,
                                        {
                                            let mut _s = ::quote::__private::TokenStream::new();
                                            ::quote::__private::push_ident(&mut _s, "__inner");
                                            _s
                                        });
                                    ::quote::__private::push_semi(&mut _s);
                                    _s
                                });
                            _s
                        });
                    ::quote::__private::push_ident(&mut _s, "__v");
                    _s
                });
            ::quote::__private::push_ident(&mut _s, "else");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::parse(&mut _s, "0");
                            ::quote::__private::push_dot2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "__nrow");
                            _s
                        });
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "map");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_or(&mut _s);
                            ::quote::__private::push_underscore(&mut _s);
                            ::quote::__private::push_or(&mut _s);
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "std");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "vec");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "Vec");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "new");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                ::quote::__private::TokenStream::new());
                            _s
                        });
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "collect");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        ::quote::__private::TokenStream::new());
                    _s
                });
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    ::quote::__private::push_ident(&mut _s, "if");
    ::quote::ToTokens::to_tokens(&col_var, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "len");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_ne(&mut _s);
    ::quote::__private::push_ident(&mut _s, "__nrow");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "return");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "core");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "result");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Result");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Err");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "std");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "format");
                    ::quote::__private::push_bang(&mut _s);
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::parse(&mut _s,
                                "\"column `{}` has length {} but data.frame has {} rows\"");
                            ::quote::__private::push_comma(&mut _s);
                            ::quote::ToTokens::to_tokens(&col_name, &mut _s);
                            ::quote::__private::push_comma(&mut _s);
                            ::quote::ToTokens::to_tokens(&col_var, &mut _s);
                            ::quote::__private::push_dot(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "len");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                ::quote::__private::TokenStream::new());
                            ::quote::__private::push_comma(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "__nrow");
                            _s
                        });
                    _s
                });
            ::quote::__private::push_semi(&mut _s);
            _s
        });
    _s
}quote! {
3120                            let #col_var: ::std::vec::Vec<::std::vec::Vec<#elem_ty>> = {
3121                                let __col_sexp = __view.column_raw(#col_name).ok_or_else(|| {
3122                                    ::std::format!("column `{}` is missing from the data.frame", #col_name)
3123                                })?;
3124                                if <::miniextendr_api::SEXP as ::miniextendr_api::SexpExt>::is_list(&__col_sexp) {
3125                                    let __list = unsafe {
3126                                        ::miniextendr_api::list::List::from_raw(__col_sexp)
3127                                    };
3128                                    let __len = __list.len();
3129                                    let mut __v: ::std::vec::Vec<::std::vec::Vec<#elem_ty>> =
3130                                        ::std::vec::Vec::with_capacity(__len as usize);
3131                                    for __j in 0..__len {
3132                                        let __elt = __list.get(__j).unwrap();
3133                                        if __elt == ::miniextendr_api::SEXP::nil() {
3134                                            __v.push(::std::vec::Vec::new());
3135                                        } else {
3136                                            let __inner: ::std::vec::Vec<#elem_ty> =
3137                                                <::std::vec::Vec<#elem_ty> as ::miniextendr_api::from_r::TryFromSexp>::try_from_sexp(__elt)
3138                                                    .map_err(|e| ::std::format!(
3139                                                        "column `{}` element {} could not be converted: {}",
3140                                                        #col_name, __j, e
3141                                                    ))?;
3142                                            __v.push(__inner);
3143                                        }
3144                                    }
3145                                    __v
3146                                } else {
3147                                    // Non-list column → all rows have empty maps.
3148                                    (0..__nrow).map(|_| ::std::vec::Vec::new()).collect()
3149                                }
3150                            };
3151                            if #col_var.len() != __nrow {
3152                                return ::core::result::Result::Err(::std::format!(
3153                                    "column `{}` has length {} but data.frame has {} rows",
3154                                    #col_name, #col_var.len(), __nrow
3155                                ));
3156                            }
3157                        }
3158                    };
3159                    extracts.push(extract_col(&keys_var, &keys_col_name, key_ty));
3160                    extracts.push(extract_col(&vals_var, &vals_col_name, val_ty));
3161
3162                    seq_decls.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::__private::push_ident(&mut _s, "mut");
    ::quote::ToTokens::to_tokens(&keys_it_var, &mut _s);
    ::quote::__private::push_eq(&mut _s);
    ::quote::ToTokens::to_tokens(&keys_var, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "into_iter");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! { let mut #keys_it_var = #keys_var.into_iter(); });
3163                    seq_decls.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::__private::push_ident(&mut _s, "mut");
    ::quote::ToTokens::to_tokens(&vals_it_var, &mut _s);
    ::quote::__private::push_eq(&mut _s);
    ::quote::ToTokens::to_tokens(&vals_var, &mut _s);
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "into_iter");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! { let mut #vals_it_var = #vals_var.into_iter(); });
3164                    seq_builds.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&rust_name, &mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "let");
            ::quote::__private::push_ident(&mut _s, "__k");
            ::quote::__private::push_eq(&mut _s);
            ::quote::ToTokens::to_tokens(&keys_it_var, &mut _s);
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "next");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "unwrap");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            ::quote::__private::push_semi(&mut _s);
            ::quote::__private::push_ident(&mut _s, "let");
            ::quote::__private::push_ident(&mut _s, "__v");
            ::quote::__private::push_eq(&mut _s);
            ::quote::ToTokens::to_tokens(&vals_it_var, &mut _s);
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "next");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "unwrap");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            ::quote::__private::push_semi(&mut _s);
            ::quote::__private::push_ident(&mut _s, "__k");
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "into_iter");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "zip");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "__v");
                    _s
                });
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "collect");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_lt(&mut _s);
            ::quote::ToTokens::to_tokens(&map_ty, &mut _s);
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            _s
        });
    _s
}quote! {
3165                        #rust_name: {
3166                            let __k = #keys_it_var.next().unwrap();
3167                            let __v = #vals_it_var.next().unwrap();
3168                            __k.into_iter().zip(__v).collect::<#map_ty>()
3169                        }
3170                    });
3171                    par_builds.push({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&rust_name, &mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "clone");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Clone");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "clone");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_and(&mut _s);
            ::quote::ToTokens::to_tokens(&keys_var, &mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Bracket,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "__i");
                    _s
                });
            _s
        });
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "into_iter");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "zip");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "core");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "clone");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Clone");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "clone");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_and(&mut _s);
                    ::quote::ToTokens::to_tokens(&vals_var, &mut _s);
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Bracket,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "__i");
                            _s
                        });
                    _s
                });
            _s
        });
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "collect");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_lt(&mut _s);
    ::quote::ToTokens::to_tokens(&map_ty, &mut _s);
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    _s
}quote! {
3172                        #rust_name: ::core::clone::Clone::clone(&#keys_var[__i])
3173                            .into_iter()
3174                            .zip(::core::clone::Clone::clone(&#vals_var[__i]))
3175                            .collect::<#map_ty>()
3176                    });
3177                }
3178            }
3179        }
3180
3181        // Only `AutoExpandVec` builds reference `__i` in the sequential loop; bind
3182        // the counter only then to avoid an `unused_variables` warning.
3183        let seq_counter = if has_autoexpand_field {
3184            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "__i");
    _s
}quote! { __i }
3185        } else {
3186            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_underscore(&mut _s);
    _s
}quote! { _ }
3187        };
3188
3189        // Flattened and factor values need not be `Clone`. Move them through
3190        // the sequential reader, as the enum reader does for the same shapes.
3191        let par_body = if has_moved_reader_field {
3192            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "Self");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "try_from_dataframe");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "sexp");
            _s
        });
    _s
}quote! { Self::try_from_dataframe(sexp) }
3193        } else {
3194            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "use");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "miniextendr_api");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "rayon_bridge");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "rayon");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "prelude");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_star(&mut _s);
    ::quote::__private::push_semi(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "miniextendr_api");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "optionals");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "parallel");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "ensure_pool");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_semi(&mut _s);
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::__private::push_ident(&mut _s, "__view");
    ::quote::__private::push_eq(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "miniextendr_api");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "dataframe");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "DataFrame");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "from_sexp");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "sexp");
            _s
        });
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "map_err");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_or(&mut _s);
            ::quote::__private::push_ident(&mut _s, "e");
            ::quote::__private::push_or(&mut _s);
            ::quote::__private::push_ident(&mut _s, "e");
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "to_string");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            _s
        });
    ::quote::__private::push_question(&mut _s);
    ::quote::__private::push_semi(&mut _s);
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::__private::push_ident(&mut _s, "__nrow");
    ::quote::__private::push_eq(&mut _s);
    ::quote::__private::push_ident(&mut _s, "__view");
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "nrow");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_semi(&mut _s);
    {
        use ::quote::__private::ext::*;
        let has_iter = ::quote::__private::HasIterator::<false>;
        #[allow(unused_mut)]
        let (mut extracts, i) = extracts.quote_into_iter();
        let has_iter = has_iter | i;
        <_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
        while true {
            let extracts =
                match extracts.next() {
                    Some(_x) => ::quote::__private::RepInterp(_x),
                    None => break,
                };
            ::quote::ToTokens::to_tokens(&extracts, &mut _s);
        }
    }
    ::quote::__private::push_ident(&mut _s, "let");
    ::quote::__private::push_ident(&mut _s, "__rows");
    ::quote::__private::push_colon(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Self");
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_eq(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::parse(&mut _s, "0");
            ::quote::__private::push_dot2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "__nrow");
            _s
        });
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "into_par_iter");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "map");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_or(&mut _s);
            ::quote::__private::push_ident(&mut _s, "__i");
            ::quote::__private::push_or(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Self");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    {
                        use ::quote::__private::ext::*;
                        let mut _first = true;
                        let has_iter = ::quote::__private::HasIterator::<false>;
                        #[allow(unused_mut)]
                        let (mut par_builds, i) = par_builds.quote_into_iter();
                        let has_iter = has_iter | i;
                        <_ as
                                ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                        while true {
                            let par_builds =
                                match par_builds.next() {
                                    Some(_x) => ::quote::__private::RepInterp(_x),
                                    None => break,
                                };
                            if !_first { ::quote::__private::push_comma(&mut _s); }
                            _first = false;
                            ::quote::ToTokens::to_tokens(&par_builds, &mut _s);
                        }
                    }
                    _s
                });
            _s
        });
    ::quote::__private::push_dot(&mut _s);
    ::quote::__private::push_ident(&mut _s, "collect");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_semi(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "result");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Result");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Ok");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "__rows");
            _s
        });
    _s
}quote! {
3195                use ::miniextendr_api::rayon_bridge::rayon::prelude::*;
3196                ::miniextendr_api::optionals::parallel::ensure_pool();
3197                let __view = ::miniextendr_api::dataframe::DataFrame::from_sexp(sexp)
3198                    .map_err(|e| e.to_string())?;
3199                let __nrow = __view.nrow();
3200                #(#extracts)*
3201                let __rows: ::std::vec::Vec<Self> = (0..__nrow)
3202                    .into_par_iter()
3203                    .map(|__i| Self { #(#par_builds),* })
3204                    .collect();
3205                ::core::result::Result::Ok(__rows)
3206            }
3207        };
3208
3209        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_pound(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "doc");
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::parse(&mut _s,
                "r\" Read an R `data.frame` directly into a `Vec<Self>` (sequential).\"");
            _s
        });
    ::quote::__private::push_pound(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "doc");
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::parse(&mut _s, "r\"\"");
            _s
        });
    ::quote::__private::push_pound(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "doc");
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::parse(&mut _s,
                "r\" Each column is materialised out of R (NA-aware, ALTREP-materialising)\"");
            _s
        });
    ::quote::__private::push_pound(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "doc");
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::parse(&mut _s,
                "r\" and the rows are assembled by transposing column-major into row-major.\"");
            _s
        });
    ::quote::__private::push_pound(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "doc");
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::parse(&mut _s,
                "r\" Column-expansion fields are regrouped and nested-struct fields are\"");
            _s
        });
    ::quote::__private::push_pound(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "doc");
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::parse(&mut _s,
                "r\" read from their `<field>_`-prefixed sub-frame. Returns `Err` with a\"");
            _s
        });
    ::quote::__private::push_pound(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "doc");
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::parse(&mut _s,
                "r\" descriptive message if a column is missing, mis-typed, or ragged.\"");
            _s
        });
    ::quote::__private::push_pound(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "doc");
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::parse(&mut _s, "r\"\"");
            _s
        });
    ::quote::__private::push_pound(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "doc");
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::parse(&mut _s,
                "r\" This is the one-call `SEXP \u{2192} Vec<Self>` reader; the same conversion is also\"");
            _s
        });
    ::quote::__private::push_pound(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "doc");
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::parse(&mut _s,
                "r\" reachable via the boundary-crossing [`FromDataFrame`] trait as\"");
            _s
        });
    ::quote::__private::push_pound(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "doc");
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::parse(&mut _s,
                "r\" `Vec::<Self>::from_dataframe(&df)`.\"");
            _s
        });
    ::quote::__private::push_pound(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "doc");
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::parse(&mut _s, "r\"\"");
            _s
        });
    ::quote::__private::push_pound(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Bracket,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "doc");
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::parse(&mut _s,
                "r\" [`FromDataFrame`]: ::miniextendr_api::dataframe::FromDataFrame\"");
            _s
        });
    ::quote::__private::push_ident(&mut _s, "pub");
    ::quote::__private::push_ident(&mut _s, "fn");
    ::quote::__private::push_ident(&mut _s, "try_from_dataframe");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "sexp");
            ::quote::__private::push_colon(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "SEXP");
            ::quote::__private::push_comma(&mut _s);
            _s
        });
    ::quote::__private::push_rarrow(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "result");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Result");
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Self");
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_comma(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "string");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "String");
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "let");
            ::quote::__private::push_ident(&mut _s, "__view");
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "dataframe");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "DataFrame");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "from_sexp");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "sexp");
                    _s
                });
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "map_err");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_or(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "e");
                    ::quote::__private::push_or(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "e");
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "to_string");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        ::quote::__private::TokenStream::new());
                    _s
                });
            ::quote::__private::push_question(&mut _s);
            ::quote::__private::push_semi(&mut _s);
            ::quote::__private::push_ident(&mut _s, "let");
            ::quote::__private::push_ident(&mut _s, "__nrow");
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::push_ident(&mut _s, "__view");
            ::quote::__private::push_dot(&mut _s);
            ::quote::__private::push_ident(&mut _s, "nrow");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            ::quote::__private::push_semi(&mut _s);
            {
                use ::quote::__private::ext::*;
                let has_iter = ::quote::__private::HasIterator::<false>;
                #[allow(unused_mut)]
                let (mut extracts, i) = extracts.quote_into_iter();
                let has_iter = has_iter | i;
                <_ as
                        ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                while true {
                    let extracts =
                        match extracts.next() {
                            Some(_x) => ::quote::__private::RepInterp(_x),
                            None => break,
                        };
                    ::quote::ToTokens::to_tokens(&extracts, &mut _s);
                }
            }
            {
                use ::quote::__private::ext::*;
                let has_iter = ::quote::__private::HasIterator::<false>;
                #[allow(unused_mut)]
                let (mut seq_decls, i) = seq_decls.quote_into_iter();
                let has_iter = has_iter | i;
                <_ as
                        ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                while true {
                    let seq_decls =
                        match seq_decls.next() {
                            Some(_x) => ::quote::__private::RepInterp(_x),
                            None => break,
                        };
                    ::quote::ToTokens::to_tokens(&seq_decls, &mut _s);
                }
            }
            ::quote::__private::push_ident(&mut _s, "let");
            ::quote::__private::push_ident(&mut _s, "mut");
            ::quote::__private::push_ident(&mut _s, "__rows");
            ::quote::__private::push_colon(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "std");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "vec");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Vec");
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Self");
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "std");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "vec");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Vec");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "with_capacity");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "__nrow");
                    _s
                });
            ::quote::__private::push_semi(&mut _s);
            ::quote::__private::push_ident(&mut _s, "for");
            ::quote::ToTokens::to_tokens(&seq_counter, &mut _s);
            ::quote::__private::push_ident(&mut _s, "in");
            ::quote::__private::parse(&mut _s, "0");
            ::quote::__private::push_dot2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "__nrow");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "__rows");
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "push");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "Self");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Brace,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    {
                                        use ::quote::__private::ext::*;
                                        let mut _first = true;
                                        let has_iter = ::quote::__private::HasIterator::<false>;
                                        #[allow(unused_mut)]
                                        let (mut seq_builds, i) = seq_builds.quote_into_iter();
                                        let has_iter = has_iter | i;
                                        <_ as
                                                ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                                        while true {
                                            let seq_builds =
                                                match seq_builds.next() {
                                                    Some(_x) => ::quote::__private::RepInterp(_x),
                                                    None => break,
                                                };
                                            if !_first { ::quote::__private::push_comma(&mut _s); }
                                            _first = false;
                                            ::quote::ToTokens::to_tokens(&seq_builds, &mut _s);
                                        }
                                    }
                                    _s
                                });
                            _s
                        });
                    ::quote::__private::push_semi(&mut _s);
                    _s
                });
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "core");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "result");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Result");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Ok");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "__rows");
                    _s
                });
            _s
        });
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "miniextendr_api");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "__dataframe_row_when_rayon");
    ::quote::__private::push_bang(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_pound(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Bracket,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "doc");
                    ::quote::__private::push_eq(&mut _s);
                    ::quote::__private::parse(&mut _s,
                        "r\" Read an R `data.frame` directly into a `Vec<Self>` (parallel).\"");
                    _s
                });
            ::quote::__private::push_pound(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Bracket,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "doc");
                    ::quote::__private::push_eq(&mut _s);
                    ::quote::__private::parse(&mut _s, "r\"\"");
                    _s
                });
            ::quote::__private::push_pound(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Bracket,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "doc");
                    ::quote::__private::push_eq(&mut _s);
                    ::quote::__private::parse(&mut _s,
                        "r\" Mirrors [`Self::try_from_dataframe`] but assembles rows off the R\"");
                    _s
                });
            ::quote::__private::push_pound(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Bracket,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "doc");
                    ::quote::__private::push_eq(&mut _s);
                    ::quote::__private::parse(&mut _s,
                        "r\" thread via rayon. Safety: all SEXP access (column extraction, ALTREP\"");
                    _s
                });
            ::quote::__private::push_pound(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Bracket,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "doc");
                    ::quote::__private::push_eq(&mut _s);
                    ::quote::__private::parse(&mut _s,
                        "r\" materialisation, nested sub-frame reads) happens up front on the\"");
                    _s
                });
            ::quote::__private::push_pound(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Bracket,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "doc");
                    ::quote::__private::push_eq(&mut _s);
                    ::quote::__private::parse(&mut _s,
                        "r\" R/worker thread; the `into_par_iter()` region touches only\"");
                    _s
                });
            ::quote::__private::push_pound(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Bracket,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "doc");
                    ::quote::__private::push_eq(&mut _s);
                    ::quote::__private::parse(&mut _s,
                        "r\" pre-extracted owned data and makes no R API calls.\"");
                    _s
                });
            ::quote::__private::push_ident(&mut _s, "pub");
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "try_from_dataframe_par");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "sexp");
                    ::quote::__private::push_colon(&mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "miniextendr_api");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "SEXP");
                    ::quote::__private::push_comma(&mut _s);
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "core");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "result");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Result");
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "std");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "vec");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Vec");
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Self");
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_comma(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "std");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "string");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "String");
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::ToTokens::to_tokens(&par_body, &mut _s);
                    _s
                });
            _s
        });
    _s
}quote! {
3210            /// Read an R `data.frame` directly into a `Vec<Self>` (sequential).
3211            ///
3212            /// Each column is materialised out of R (NA-aware, ALTREP-materialising)
3213            /// and the rows are assembled by transposing column-major into row-major.
3214            /// Column-expansion fields are regrouped and nested-struct fields are
3215            /// read from their `<field>_`-prefixed sub-frame. Returns `Err` with a
3216            /// descriptive message if a column is missing, mis-typed, or ragged.
3217            ///
3218            /// This is the one-call `SEXP → Vec<Self>` reader; the same conversion is also
3219            /// reachable via the boundary-crossing [`FromDataFrame`] trait as
3220            /// `Vec::<Self>::from_dataframe(&df)`.
3221            ///
3222            /// [`FromDataFrame`]: ::miniextendr_api::dataframe::FromDataFrame
3223            pub fn try_from_dataframe(
3224                sexp: ::miniextendr_api::SEXP,
3225            ) -> ::core::result::Result<::std::vec::Vec<Self>, ::std::string::String> {
3226                let __view = ::miniextendr_api::dataframe::DataFrame::from_sexp(sexp)
3227                    .map_err(|e| e.to_string())?;
3228                let __nrow = __view.nrow();
3229                #(#extracts)*
3230                #(#seq_decls)*
3231                let mut __rows: ::std::vec::Vec<Self> = ::std::vec::Vec::with_capacity(__nrow);
3232                for #seq_counter in 0..__nrow {
3233                    __rows.push(Self { #(#seq_builds),* });
3234                }
3235                ::core::result::Result::Ok(__rows)
3236            }
3237
3238            // api-side rayon gate — see the #1117 note on `from_rows_par` above.
3239            ::miniextendr_api::__dataframe_row_when_rayon! {
3240                /// Read an R `data.frame` directly into a `Vec<Self>` (parallel).
3241                ///
3242                /// Mirrors [`Self::try_from_dataframe`] but assembles rows off the R
3243                /// thread via rayon. Safety: all SEXP access (column extraction, ALTREP
3244                /// materialisation, nested sub-frame reads) happens up front on the
3245                /// R/worker thread; the `into_par_iter()` region touches only
3246                /// pre-extracted owned data and makes no R API calls.
3247                pub fn try_from_dataframe_par(
3248                    sexp: ::miniextendr_api::SEXP,
3249                ) -> ::core::result::Result<::std::vec::Vec<Self>, ::std::string::String> {
3250                    #par_body
3251                }
3252            }
3253        }
3254    } else {
3255        TokenStream::new()
3256    };
3257    // endregion
3258
3259    // region: ColumnarFrame impl on the companion (from_rows / into_rows / from_rows_par)
3260    //
3261    // The pure-Rust columnar verbs live on the `ColumnarFrame` trait, not as inherent
3262    // methods: `from_rows` (= the `From<Vec<Row>>` impl), `into_rows` (= the companion's
3263    // `IntoIterator`, for row-iterable shapes) and the `from_rows_par` override, which
3264    // picks the parallel fill where the row shape allows one.
3265    let df_methods = {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::ToTokens::to_tokens(&impl_generics, &mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "miniextendr_api");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "dataframe");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "ColumnarFrame");
    ::quote::__private::push_lt(&mut _s);
    ::quote::ToTokens::to_tokens(&row_name, &mut _s);
    ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_ident(&mut _s, "for");
    ::quote::ToTokens::to_tokens(&df_name, &mut _s);
    ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
    ::quote::ToTokens::to_tokens(&where_clause, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "from_rows");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "rows");
                    ::quote::__private::push_colon(&mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "std");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "vec");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Vec");
                    ::quote::__private::push_lt(&mut _s);
                    ::quote::ToTokens::to_tokens(&row_name, &mut _s);
                    ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
                    ::quote::__private::push_gt(&mut _s);
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Self");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "rows");
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "into");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        ::quote::__private::TokenStream::new());
                    _s
                });
            ::quote::ToTokens::to_tokens(&from_rows_par_method, &mut _s);
            _s
        });
    _s
}quote! {
3266        impl #impl_generics ::miniextendr_api::dataframe::ColumnarFrame<#row_name #ty_generics>
3267            for #df_name #ty_generics #where_clause
3268        {
3269            fn from_rows(rows: ::std::vec::Vec<#row_name #ty_generics>) -> Self {
3270                rows.into()
3271            }
3272
3273            #from_rows_par_method
3274        }
3275    };
3276
3277    // The row type carries the one-call SEXP readers (when reader-capable) plus a hidden
3278    // `to_dataframe`. The documented rows↔companion verbs live on `ColumnarFrame` / `From` /
3279    // `IntoIterator`; `to_dataframe` is retained `#[doc(hidden)]` because the struct-flatten
3280    // write path builds a nested companion via `Inner::to_dataframe(..)` without naming the
3281    // inner companion type (its name may be customised with `#[dataframe(name = ..)]`).
3282    let row_methods = {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::ToTokens::to_tokens(&impl_generics, &mut _s);
    ::quote::ToTokens::to_tokens(&row_name, &mut _s);
    ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
    ::quote::ToTokens::to_tokens(&where_clause, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_pound(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Bracket,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "doc");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "hidden");
                            _s
                        });
                    _s
                });
            ::quote::__private::push_ident(&mut _s, "pub");
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "to_dataframe");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "rows");
                    ::quote::__private::push_colon(&mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "std");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "vec");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Vec");
                    ::quote::__private::push_lt(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Self");
                    ::quote::__private::push_gt(&mut _s);
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::ToTokens::to_tokens(&df_name, &mut _s);
            ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "rows");
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "into");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        ::quote::__private::TokenStream::new());
                    _s
                });
            ::quote::ToTokens::to_tokens(&reader_methods, &mut _s);
            _s
        });
    _s
}quote! {
3283        impl #impl_generics #row_name #ty_generics #where_clause {
3284            #[doc(hidden)]
3285            pub fn to_dataframe(rows: ::std::vec::Vec<Self>) -> #df_name #ty_generics {
3286                rows.into()
3287            }
3288
3289            #reader_methods
3290        }
3291    };
3292
3293    // Marker trait impl: struct type implements DataFrameRow via IntoDataFrame chain.
3294    let marker_impl = {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::ToTokens::to_tokens(&impl_generics, &mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "miniextendr_api");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "markers");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "DataFrameRow");
    ::quote::__private::push_ident(&mut _s, "for");
    ::quote::ToTokens::to_tokens(&row_name, &mut _s);
    ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
    ::quote::ToTokens::to_tokens(&where_clause, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        ::quote::__private::TokenStream::new());
    _s
}quote! {
3295        impl #impl_generics ::miniextendr_api::markers::DataFrameRow
3296            for #row_name #ty_generics #where_clause {}
3297    };
3298
3299    // DataFramePayloadFields impl: exposes FIELDS (all resolved column names) and TAG
3300    // (the #[dataframe(tag = "...")] value, or "") for compile-time collision detection
3301    // by outer DataFrameRow enums that nest this type as a struct-flattened field.
3302    let payload_fields_impl = {
3303        // Collect all column names: flat_cols + struct_col base names.
3304        let mut field_names: Vec<String> =
3305            flat_cols.iter().map(|fc| fc.col_name_str.clone()).collect();
3306        for sc in &struct_cols {
3307            field_names.push(sc.col_name_str.clone());
3308        }
3309        let tag_str = attrs.tag.as_deref().unwrap_or("");
3310        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::ToTokens::to_tokens(&impl_generics, &mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "miniextendr_api");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "markers");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "DataFramePayloadFields");
    ::quote::__private::push_ident(&mut _s, "for");
    ::quote::ToTokens::to_tokens(&row_name, &mut _s);
    ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
    ::quote::ToTokens::to_tokens(&where_clause, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "const");
            ::quote::__private::push_ident(&mut _s, "FIELDS");
            ::quote::__private::push_colon(&mut _s);
            ::quote::__private::push_and(&mut _s);
            ::quote::__private::push_lifetime(&mut _s, "\'static");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Bracket,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_lifetime(&mut _s, "\'static");
                    ::quote::__private::push_ident(&mut _s, "str");
                    _s
                });
            ::quote::__private::push_eq(&mut _s);
            ::quote::__private::push_and(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Bracket,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    {
                        use ::quote::__private::ext::*;
                        let mut _first = true;
                        let has_iter = ::quote::__private::HasIterator::<false>;
                        #[allow(unused_mut)]
                        let (mut field_names, i) = field_names.quote_into_iter();
                        let has_iter = has_iter | i;
                        <_ as
                                ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                        while true {
                            let field_names =
                                match field_names.next() {
                                    Some(_x) => ::quote::__private::RepInterp(_x),
                                    None => break,
                                };
                            if !_first { ::quote::__private::push_comma(&mut _s); }
                            _first = false;
                            ::quote::ToTokens::to_tokens(&field_names, &mut _s);
                        }
                    }
                    _s
                });
            ::quote::__private::push_semi(&mut _s);
            ::quote::__private::push_ident(&mut _s, "const");
            ::quote::__private::push_ident(&mut _s, "TAG");
            ::quote::__private::push_colon(&mut _s);
            ::quote::__private::push_and(&mut _s);
            ::quote::__private::push_lifetime(&mut _s, "\'static");
            ::quote::__private::push_ident(&mut _s, "str");
            ::quote::__private::push_eq(&mut _s);
            ::quote::ToTokens::to_tokens(&tag_str, &mut _s);
            ::quote::__private::push_semi(&mut _s);
            _s
        });
    _s
}quote! {
3311            impl #impl_generics ::miniextendr_api::markers::DataFramePayloadFields
3312                for #row_name #ty_generics #where_clause
3313            {
3314                const FIELDS: &'static [&'static str] = &[#(#field_names),*];
3315                const TAG: &'static str = #tag_str;
3316            }
3317        }
3318    };
3319
3320    // Compile-time assertions for struct-flattened fields (#485): each inner
3321    // type must implement `DataFrameRow`, otherwise users get a confusing
3322    // error pointing at the `to_dataframe` call site instead of the field.
3323    let struct_assertions: Vec<TokenStream> = struct_cols
3324        .iter()
3325        .map(|sc| {
3326            let inner_ty = &sc.inner_ty;
3327            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "const");
    ::quote::__private::push_underscore(&mut _s);
    ::quote::__private::push_colon(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        ::quote::__private::TokenStream::new());
    ::quote::__private::push_eq(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s,
                "_assert_inner_is_dataframe_row");
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_ident(&mut _s, "T");
            ::quote::__private::push_colon(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "markers");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "DataFrameRow");
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                ::quote::__private::TokenStream::new());
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "_do_assert");
            ::quote::ToTokens::to_tokens(&impl_generics, &mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                ::quote::__private::TokenStream::new());
            ::quote::ToTokens::to_tokens(&where_clause, &mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s,
                        "_assert_inner_is_dataframe_row");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_lt(&mut _s);
                    ::quote::ToTokens::to_tokens(&inner_ty, &mut _s);
                    ::quote::__private::push_gt(&mut _s);
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        ::quote::__private::TokenStream::new());
                    ::quote::__private::push_semi(&mut _s);
                    _s
                });
            _s
        });
    ::quote::__private::push_semi(&mut _s);
    _s
}quote! {
3328                const _: () = {
3329                    fn _assert_inner_is_dataframe_row<T: ::miniextendr_api::markers::DataFrameRow>() {}
3330                    fn _do_assert #impl_generics () #where_clause {
3331                        _assert_inner_is_dataframe_row::<#inner_ty>();
3332                    }
3333                };
3334            }
3335        })
3336        .collect();
3337
3338    // region: DataFrameRowConvert on Row — orphan-rule bridge for the public verbs
3339    //
3340    // The derive cannot write `impl IntoDataFrame for Vec<Row>` directly: the orphan rule
3341    // forbids it (both `IntoDataFrame` and `Vec` are foreign in the user crate, and `Row` is
3342    // only *covered* inside `Vec<_>`). Instead it implements the local `DataFrameRowConvert`
3343    // marker on the local `Row`; miniextendr_api's blanket
3344    // `impl<T: DataFrameRowConvert> IntoDataFrame/FromDataFrame for Vec<T>` then gives users the
3345    // public verbs `rows.into_dataframe()?` / `Vec::<Row>::from_dataframe(&df)?`. The methods
3346    // delegate to the companion engine (`to_dataframe` → `ColumnSource::into_dataframe`), the
3347    // merged parallel builder (#777 `from_rows_par`) and reader (#765 `try_from_dataframe[_par]`),
3348    // converting the reader's bare `String` error into the unified `DataFrameError`.
3349
3350    // The parallel build goes through `from_rows_par` when the derive overrides it for this
3351    // shape; otherwise it is the sequential transposition.
3352    let has_par_builder = !from_rows_par_method.is_empty();
3353    let rows_into_dataframe_par_body = if has_par_builder {
3354        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "miniextendr_api");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "convert");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "ColumnSource");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "into_dataframe");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_lt(&mut _s);
            ::quote::ToTokens::to_tokens(&df_name, &mut _s);
            ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
            ::quote::__private::push_ident(&mut _s, "as");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "dataframe");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "ColumnarFrame");
            ::quote::__private::push_lt(&mut _s);
            ::quote::ToTokens::to_tokens(&row_name, &mut _s);
            ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
            ::quote::__private::push_comma(&mut _s);
            ::quote::__private::push_shr(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "from_rows_par");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "rows");
                    _s
                });
            ::quote::__private::push_comma(&mut _s);
            _s
        });
    _s
}quote! {
3355            ::miniextendr_api::convert::ColumnSource::into_dataframe(
3356                <#df_name #ty_generics as ::miniextendr_api::dataframe::ColumnarFrame<
3357                    #row_name #ty_generics,
3358                >>::from_rows_par(rows),
3359            )
3360        }
3361    } else {
3362        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "Self");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "rows_into_dataframe");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "rows");
            _s
        });
    _s
}quote! { Self::rows_into_dataframe(rows) }
3363    };
3364
3365    // Readers are overridden for every reader-capable struct shape (scalar,
3366    // column-expansion, struct-flatten — see `struct_reader` / `try_from_dataframe`).
3367    // Other shapes use the trait default (`None`), surfaced by the blanket as a
3368    // clear `DataFrameError`.
3369    let reader_overrides = if struct_reader {
3370        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "fn");
    ::quote::__private::push_ident(&mut _s, "rows_from_dataframe");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "df");
            ::quote::__private::push_colon(&mut _s);
            ::quote::__private::push_and(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "dataframe");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "DataFrame");
            ::quote::__private::push_comma(&mut _s);
            _s
        });
    ::quote::__private::push_rarrow(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "option");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Option");
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "core");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "result");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Result");
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "std");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "vec");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Vec");
    ::quote::__private::push_lt(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Self");
    ::quote::__private::push_gt(&mut _s);
    ::quote::__private::push_comma(&mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "miniextendr_api");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "dataframe");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "DataFrameError");
    ::quote::__private::push_comma(&mut _s);
    ::quote::__private::push_shr(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "core");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "option");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Option");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Some");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_lt(&mut _s);
                    ::quote::ToTokens::to_tokens(&row_name, &mut _s);
                    ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
                    ::quote::__private::push_gt(&mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s,
                        "try_from_dataframe");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "df");
                            ::quote::__private::push_dot(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "as_sexp");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                ::quote::__private::TokenStream::new());
                            _s
                        });
                    ::quote::__private::push_dot(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "map_err");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "dataframe");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "DataFrameError");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "Conversion");
                            _s
                        });
                    ::quote::__private::push_comma(&mut _s);
                    _s
                });
            _s
        });
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "miniextendr_api");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "__dataframe_row_when_rayon");
    ::quote::__private::push_bang(&mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s,
                "rows_from_dataframe_par");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "df");
                    ::quote::__private::push_colon(&mut _s);
                    ::quote::__private::push_and(&mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "miniextendr_api");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "dataframe");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "DataFrame");
                    ::quote::__private::push_comma(&mut _s);
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "core");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "option");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Option");
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "core");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "result");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Result");
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "std");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "vec");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Vec");
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Self");
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_comma(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "dataframe");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "DataFrameError");
            ::quote::__private::push_comma(&mut _s);
            ::quote::__private::push_shr(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "core");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "option");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Option");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Some");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_lt(&mut _s);
                            ::quote::ToTokens::to_tokens(&row_name, &mut _s);
                            ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
                            ::quote::__private::push_gt(&mut _s);
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s,
                                "try_from_dataframe_par");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_ident(&mut _s, "df");
                                    ::quote::__private::push_dot(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "as_sexp");
                                    ::quote::__private::push_group(&mut _s,
                                        ::quote::__private::Delimiter::Parenthesis,
                                        ::quote::__private::TokenStream::new());
                                    _s
                                });
                            ::quote::__private::push_dot(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "map_err");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "miniextendr_api");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "dataframe");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "DataFrameError");
                                    ::quote::__private::push_colon2(&mut _s);
                                    ::quote::__private::push_ident(&mut _s, "Conversion");
                                    _s
                                });
                            ::quote::__private::push_comma(&mut _s);
                            _s
                        });
                    _s
                });
            _s
        });
    _s
}quote! {
3371            fn rows_from_dataframe(
3372                df: &::miniextendr_api::dataframe::DataFrame,
3373            ) -> ::core::option::Option<::core::result::Result<
3374                ::std::vec::Vec<Self>,
3375                ::miniextendr_api::dataframe::DataFrameError,
3376            >> {
3377                ::core::option::Option::Some(
3378                    <#row_name #ty_generics>::try_from_dataframe(df.as_sexp())
3379                        .map_err(::miniextendr_api::dataframe::DataFrameError::Conversion),
3380                )
3381            }
3382
3383            ::miniextendr_api::__dataframe_row_when_rayon! {
3384                fn rows_from_dataframe_par(
3385                    df: &::miniextendr_api::dataframe::DataFrame,
3386                ) -> ::core::option::Option<::core::result::Result<
3387                    ::std::vec::Vec<Self>,
3388                    ::miniextendr_api::dataframe::DataFrameError,
3389                >> {
3390                    ::core::option::Option::Some(
3391                        <#row_name #ty_generics>::try_from_dataframe_par(df.as_sexp())
3392                            .map_err(::miniextendr_api::dataframe::DataFrameError::Conversion),
3393                    )
3394                }
3395            }
3396        }
3397    } else {
3398        TokenStream::new()
3399    };
3400
3401    let datarow_convert_impl = {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "impl");
    ::quote::ToTokens::to_tokens(&impl_generics, &mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "miniextendr_api");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "dataframe");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "DataFrameRowConvert");
    ::quote::__private::push_ident(&mut _s, "for");
    ::quote::ToTokens::to_tokens(&row_name, &mut _s);
    ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
    ::quote::ToTokens::to_tokens(&where_clause, &mut _s);
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "fn");
            ::quote::__private::push_ident(&mut _s, "rows_into_dataframe");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "rows");
                    ::quote::__private::push_colon(&mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "std");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "vec");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Vec");
                    ::quote::__private::push_lt(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Self");
                    ::quote::__private::push_gt(&mut _s);
                    ::quote::__private::push_comma(&mut _s);
                    _s
                });
            ::quote::__private::push_rarrow(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "core");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "result");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Result");
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "dataframe");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "DataFrame");
            ::quote::__private::push_comma(&mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "dataframe");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "DataFrameError");
            ::quote::__private::push_comma(&mut _s);
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "miniextendr_api");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "convert");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "ColumnSource");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "into_dataframe");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_lt(&mut _s);
                            ::quote::ToTokens::to_tokens(&df_name, &mut _s);
                            ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
                            ::quote::__private::push_ident(&mut _s, "as");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "core");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "convert");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "From");
                            ::quote::__private::push_lt(&mut _s);
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "std");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "vec");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "Vec");
                            ::quote::__private::push_lt(&mut _s);
                            ::quote::ToTokens::to_tokens(&row_name, &mut _s);
                            ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
                            ::quote::__private::push_gt(&mut _s);
                            ::quote::__private::push_comma(&mut _s);
                            ::quote::__private::push_shr(&mut _s);
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "from");
                            ::quote::__private::push_group(&mut _s,
                                ::quote::__private::Delimiter::Parenthesis,
                                {
                                    let mut _s = ::quote::__private::TokenStream::new();
                                    ::quote::__private::push_ident(&mut _s, "rows");
                                    _s
                                });
                            ::quote::__private::push_comma(&mut _s);
                            _s
                        });
                    _s
                });
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "miniextendr_api");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s,
                "__dataframe_row_when_rayon");
            ::quote::__private::push_bang(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "fn");
                    ::quote::__private::push_ident(&mut _s,
                        "rows_into_dataframe_par");
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Parenthesis,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::__private::push_ident(&mut _s, "rows");
                            ::quote::__private::push_colon(&mut _s);
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "std");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "vec");
                            ::quote::__private::push_colon2(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "Vec");
                            ::quote::__private::push_lt(&mut _s);
                            ::quote::__private::push_ident(&mut _s, "Self");
                            ::quote::__private::push_gt(&mut _s);
                            ::quote::__private::push_comma(&mut _s);
                            _s
                        });
                    ::quote::__private::push_rarrow(&mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "core");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "result");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "Result");
                    ::quote::__private::push_lt(&mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "miniextendr_api");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "dataframe");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "DataFrame");
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "miniextendr_api");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "dataframe");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "DataFrameError");
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_gt(&mut _s);
                    ::quote::__private::push_group(&mut _s,
                        ::quote::__private::Delimiter::Brace,
                        {
                            let mut _s = ::quote::__private::TokenStream::new();
                            ::quote::ToTokens::to_tokens(&rows_into_dataframe_par_body,
                                &mut _s);
                            _s
                        });
                    _s
                });
            ::quote::ToTokens::to_tokens(&reader_overrides, &mut _s);
            _s
        });
    _s
}quote! {
3402        impl #impl_generics ::miniextendr_api::dataframe::DataFrameRowConvert
3403            for #row_name #ty_generics #where_clause
3404        {
3405            fn rows_into_dataframe(
3406                rows: ::std::vec::Vec<Self>,
3407            ) -> ::core::result::Result<
3408                ::miniextendr_api::dataframe::DataFrame,
3409                ::miniextendr_api::dataframe::DataFrameError,
3410            > {
3411                ::miniextendr_api::convert::ColumnSource::into_dataframe(
3412                    <#df_name #ty_generics as ::core::convert::From<
3413                        ::std::vec::Vec<#row_name #ty_generics>,
3414                    >>::from(rows),
3415                )
3416            }
3417
3418            ::miniextendr_api::__dataframe_row_when_rayon! {
3419                fn rows_into_dataframe_par(
3420                    rows: ::std::vec::Vec<Self>,
3421                ) -> ::core::result::Result<
3422                    ::miniextendr_api::dataframe::DataFrame,
3423                    ::miniextendr_api::dataframe::DataFrameError,
3424                > {
3425                    #rows_into_dataframe_par_body
3426                }
3427            }
3428
3429            #reader_overrides
3430        }
3431    };
3432    // endregion
3433
3434    Ok({
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::ToTokens::to_tokens(&dataframe_struct, &mut _s);
    ::quote::ToTokens::to_tokens(&into_dataframe_impl, &mut _s);
    ::quote::ToTokens::to_tokens(&from_vec_impl, &mut _s);
    ::quote::ToTokens::to_tokens(&df_methods, &mut _s);
    ::quote::ToTokens::to_tokens(&parallel_columns_item, &mut _s);
    ::quote::ToTokens::to_tokens(&into_iterator_impl, &mut _s);
    ::quote::ToTokens::to_tokens(&row_methods, &mut _s);
    ::quote::ToTokens::to_tokens(&marker_impl, &mut _s);
    ::quote::ToTokens::to_tokens(&payload_fields_impl, &mut _s);
    ::quote::ToTokens::to_tokens(&datarow_convert_impl, &mut _s);
    {
        use ::quote::__private::ext::*;
        let has_iter = ::quote::__private::HasIterator::<false>;
        #[allow(unused_mut)]
        let (mut struct_assertions, i) = struct_assertions.quote_into_iter();
        let has_iter = has_iter | i;
        <_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
        while true {
            let struct_assertions =
                match struct_assertions.next() {
                    Some(_x) => ::quote::__private::RepInterp(_x),
                    None => break,
                };
            ::quote::ToTokens::to_tokens(&struct_assertions, &mut _s);
        }
    }
    _s
}quote! {
3435        #dataframe_struct
3436        #into_dataframe_impl
3437        #from_vec_impl
3438        #df_methods
3439        #parallel_columns_item
3440        #into_iterator_impl
3441        #row_methods
3442        #marker_impl
3443        #payload_fields_impl
3444        #datarow_convert_impl
3445        #(#struct_assertions)*
3446    })
3447    // endregion
3448}
3449// endregion
3450
3451// region: Enum align path
3452
3453/// A resolved column in the unified schema across all enum variants.
3454///
3455/// Tracks the column name, element type, which variants contribute to this column,
3456/// and whether the type was coerced to `String` due to cross-variant type conflicts
3457/// (when `#[dataframe(conflicts = "string")]` is active).
3458pub(super) struct ResolvedColumn {
3459    /// Column name in the companion struct / data frame.
3460    pub(super) col_name: syn::Ident,
3461    /// Element type (used as `Vec<Option<#ty>>`).
3462    /// When `string_coerced` is true, this is always `String`.
3463    pub(super) ty: syn::Type,
3464    /// Indices of variants that contain this field.
3465    pub(super) present_in: Vec<usize>,
3466    /// Whether this column was coerced to `String` due to type conflicts.
3467    /// When true, values are converted via `ToString::to_string()` at push time.
3468    pub(super) string_coerced: bool,
3469    /// Whether this column should be emitted as an R factor (via `as_factor` attribute).
3470    /// When `true`, `into_data_frame` wraps the `Vec<Option<T>>` in `FactorOptionVec<T>`
3471    /// before calling `IntoR::into_sexp`, using the `UnitEnumFactor` blanket impl.
3472    pub(super) is_factor: bool,
3473}
3474
3475/// Accumulates unique columns for an enum-to-dataframe unified schema.
3476///
3477/// As columns are registered from each variant's fields, the registry detects
3478/// duplicates and validates type consistency. When `coerce_to_string` is enabled,
3479/// type conflicts are resolved by coercing to `String`; otherwise they produce errors.
3480pub(super) struct ColumnRegistry<'a> {
3481    /// The ordered list of resolved columns in the schema.
3482    pub(super) columns: Vec<ResolvedColumn>,
3483    /// Maps column name strings to their index in `columns` for O(1) dedup lookup.
3484    pub(super) col_index: std::collections::HashMap<String, usize>,
3485    /// Whether to coerce type-conflicting columns to `String` instead of erroring.
3486    pub(super) coerce_to_string: bool,
3487    /// Cached `String` type AST node, used as the coercion target type.
3488    pub(super) string_ty: &'a syn::Type,
3489}
3490
3491impl<'a> ColumnRegistry<'a> {
3492    /// Create a new empty column registry.
3493    fn new(coerce_to_string: bool, string_ty: &'a syn::Type) -> Self {
3494        Self {
3495            columns: Vec::new(),
3496            col_index: std::collections::HashMap::new(),
3497            coerce_to_string,
3498            string_ty,
3499        }
3500    }
3501
3502    /// Register a single column in the schema, or merge with an existing column.
3503    ///
3504    /// If a column with the same name already exists, validates that the types match.
3505    /// On type conflict: coerces to `String` (if `coerce_to_string` is true) or
3506    /// returns `Err`. The `variant_idx` is appended to the column's `present_in` list.
3507    fn register(
3508        &mut self,
3509        col_name: &str,
3510        col_ty: &syn::Type,
3511        variant_idx: usize,
3512        variant_name: &syn::Ident,
3513        error_span: Span,
3514    ) -> syn::Result<()> {
3515        if let Some(&idx) = self.col_index.get(col_name) {
3516            let existing = &self.columns[idx];
3517            if !existing.string_coerced && existing.ty != *col_ty {
3518                if self.coerce_to_string {
3519                    self.columns[idx].ty = self.string_ty.clone();
3520                    self.columns[idx].string_coerced = true;
3521                } else {
3522                    return Err(syn::Error::new(
3523                        error_span,
3524                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("type conflict for field `{0}`: variant `{1}` has a different type than a previous variant; use `#[dataframe(conflicts = \"string\")]` to coerce all conflicting fields to String",
                col_name, variant_name))
    })format!(
3525                            "type conflict for field `{}`: variant `{}` has a different type \
3526                             than a previous variant; \
3527                             use `#[dataframe(conflicts = \"string\")]` to coerce all conflicting fields to String",
3528                            col_name, variant_name
3529                        ),
3530                    ));
3531                }
3532            }
3533            self.columns[idx].present_in.push(variant_idx);
3534        } else {
3535            let idx = self.columns.len();
3536            self.columns.push(ResolvedColumn {
3537                col_name: crate::naming::name_ident(col_name),
3538                ty: col_ty.clone(),
3539                present_in: ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [variant_idx]))vec![variant_idx],
3540                string_coerced: false,
3541                is_factor: false,
3542            });
3543            self.col_index.insert(col_name.to_string(), idx);
3544        }
3545        Ok(())
3546    }
3547
3548    /// Like `register`, but marks the column as a factor column (`is_factor = true`).
3549    ///
3550    /// Used for fields annotated with `#[dataframe(as_factor)]`. The companion struct
3551    /// field type stays `Vec<Option<T>>`, but `into_data_frame` wraps it in
3552    /// `FactorOptionVec<T>` (using the `UnitEnumFactor` blanket `IntoR` impl).
3553    pub(super) fn register_factor(
3554        &mut self,
3555        col_name: &str,
3556        col_ty: &syn::Type,
3557        variant_idx: usize,
3558        variant_name: &syn::Ident,
3559        error_span: Span,
3560    ) -> syn::Result<()> {
3561        self.register(col_name, col_ty, variant_idx, variant_name, error_span)?;
3562        if let Some(&idx) = self.col_index.get(col_name) {
3563            self.columns[idx].is_factor = true;
3564        }
3565        Ok(())
3566    }
3567}
3568
3569/// Describes the shape of an enum variant's fields.
3570#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for VariantShape { }
#[automatically_derived]
impl ::core::clone::Clone for VariantShape {
    #[inline]
    fn clone(&self) -> Self { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for VariantShape { }Copy, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for VariantShape { }
#[automatically_derived]
impl ::core::cmp::PartialEq for VariantShape {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        ::core::intrinsics::discriminant_value(self) ==
            ::core::intrinsics::discriminant_value(other)
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for VariantShape { }Eq)]
3571pub(super) enum VariantShape {
3572    /// `Variant { field: Type, ... }`
3573    Named,
3574    /// `Variant(Type, ...)`
3575    Tuple,
3576    /// `Variant` (no fields)
3577    Unit,
3578}
3579
3580/// A resolved enum field ready for codegen -- either a single column or expanded
3581/// from an array/Vec into multiple suffixed columns.
3582///
3583/// This is the enum-path counterpart of [`ResolvedField`] (used for structs).
3584/// Each variant carries both the binding name (for destructure patterns) and the
3585/// original Rust field name (for error reporting and named-variant patterns).
3586pub(super) enum EnumResolvedField {
3587    /// Single column contribution.
3588    Single(Box<EnumSingleFieldData>),
3589    /// Expanded from [T; N].
3590    ExpandedFixed(Box<EnumExpandedFixedData>),
3591    /// Expanded from `Vec<T>` with pinned width.
3592    ExpandedVec(Box<EnumExpandedVecData>),
3593    /// Auto-expanded `Vec<T>`/`Box<[T]>`: column count determined at runtime.
3594    AutoExpandVec(Box<EnumAutoExpandVecData>),
3595    /// `HashMap<K,V>` or `BTreeMap<K,V>` → two parallel list-columns: `<field>_keys`, `<field>_values`.
3596    Map(Box<EnumMapFieldData>),
3597    /// Struct field whose inner type implements `DataFrameRow` → flattened `<base>_<inner_col>` columns.
3598    Struct(Box<EnumStructFieldData>),
3599}
3600
3601impl EnumResolvedField {
3602    /// Binding name used in destructure patterns.
3603    pub(super) fn binding(&self) -> &syn::Ident {
3604        match self {
3605            Self::Single(data) => &data.binding,
3606            Self::ExpandedFixed(data) => &data.binding,
3607            Self::ExpandedVec(data) => &data.binding,
3608            Self::AutoExpandVec(data) => &data.binding,
3609            Self::Map(data) => &data.binding,
3610            Self::Struct(data) => &data.binding,
3611        }
3612    }
3613
3614    /// Original Rust field name.
3615    pub(super) fn rust_name(&self) -> &syn::Ident {
3616        match self {
3617            Self::Single(data) => &data.rust_name,
3618            Self::ExpandedFixed(data) => &data.rust_name,
3619            Self::ExpandedVec(data) => &data.rust_name,
3620            Self::AutoExpandVec(data) => &data.rust_name,
3621            Self::Map(data) => &data.rust_name,
3622            Self::Struct(data) => &data.rust_name,
3623        }
3624    }
3625}
3626
3627/// Data for [`EnumResolvedField::Single`].
3628pub(super) struct EnumSingleFieldData {
3629    /// Column name in the schema.
3630    pub(super) col_name: syn::Ident,
3631    /// Binding name used in destructure pattern.
3632    pub(super) binding: syn::Ident,
3633    /// Original Rust field name (for named variants).
3634    pub(super) rust_name: syn::Ident,
3635    /// Column type stored in the companion Vec: the field's Rust type, also
3636    /// when `needs_into_list` is set (the companion holds no R objects).
3637    pub(super) ty: syn::Type,
3638    /// Whether the column is built by converting each value via `.into_list()`
3639    /// when the frame is assembled (`into_option_list_column` /
3640    /// `into_list_column`), rather than through `IntoR` for the whole `Vec`.
3641    ///
3642    /// Set to `true` only for struct-typed fields (`FieldTypeKind::Struct`)
3643    /// that carry `#[dataframe(as_list)]`.
3644    pub(super) needs_into_list: bool,
3645    /// Whether the field should be emitted as an R factor column.
3646    ///
3647    /// Set to `true` for fields annotated with `#[dataframe(as_factor)]`.
3648    /// The companion struct field type is `Vec<Option<T>>` (unchanged), but
3649    /// `into_data_frame` wraps it in `FactorOptionVec<T>` to use the
3650    /// `UnitEnumFactor`-based blanket `IntoR` impl.
3651    pub(super) is_factor: bool,
3652}
3653
3654/// Data for [`EnumResolvedField::ExpandedFixed`].
3655pub(super) struct EnumExpandedFixedData {
3656    /// Base column name.
3657    pub(super) base_name: String,
3658    /// Binding name.
3659    pub(super) binding: syn::Ident,
3660    /// Original Rust field name.
3661    pub(super) rust_name: syn::Ident,
3662    /// Element type.
3663    pub(super) elem_ty: syn::Type,
3664    /// Array length.
3665    pub(super) len: usize,
3666    /// The field is `&[T; N]`: its elements are cloned out, not moved.
3667    pub(super) borrowed: bool,
3668}
3669
3670/// Data for [`EnumResolvedField::ExpandedVec`].
3671pub(super) struct EnumExpandedVecData {
3672    /// Base column name.
3673    pub(super) base_name: String,
3674    /// Binding name.
3675    pub(super) binding: syn::Ident,
3676    /// Original Rust field name.
3677    pub(super) rust_name: syn::Ident,
3678    /// Element type.
3679    pub(super) elem_ty: syn::Type,
3680    /// Pinned width.
3681    pub(super) width: usize,
3682    /// The field is `&[T]`: its elements are cloned out, not moved.
3683    pub(super) borrowed: bool,
3684}
3685
3686/// Data for [`EnumResolvedField::AutoExpandVec`].
3687pub(super) struct EnumAutoExpandVecData {
3688    /// Base column name.
3689    pub(super) base_name: String,
3690    /// Binding name.
3691    pub(super) binding: syn::Ident,
3692    /// Original Rust field name.
3693    pub(super) rust_name: syn::Ident,
3694    /// Element type.
3695    pub(super) elem_ty: syn::Type,
3696    /// Container type for companion struct (`Vec<T>` or `Box<[T]>`).
3697    pub(super) container_ty: syn::Type,
3698    /// The field is `&[T]`: its elements are cloned out, not moved.
3699    pub(super) borrowed: bool,
3700}
3701
3702/// Data for [`EnumResolvedField::Map`].
3703///
3704/// A `HashMap<K,V>` or `BTreeMap<K,V>` field expands to two parallel list-columns:
3705/// `<base_name>_keys: Vec<Option<Vec<K>>>` and `<base_name>_values: Vec<Option<Vec<V>>>`.
3706/// Absent-variant rows get `None` in both columns. Key order follows the map's own
3707/// iteration order: `BTreeMap` yields sorted keys, `HashMap` yields non-deterministic order.
3708/// Both are produced via `into_iter().unzip()` which guarantees pairwise alignment.
3709pub(super) struct EnumMapFieldData {
3710    /// Base column name (field name or `rename` override).
3711    pub(super) base_name: String,
3712    /// Binding name used in destructure pattern.
3713    pub(super) binding: syn::Ident,
3714    /// Original Rust field name.
3715    pub(super) rust_name: syn::Ident,
3716    /// Key type K.
3717    pub(super) key_ty: syn::Type,
3718    /// Value type V.
3719    pub(super) val_ty: syn::Type,
3720    /// Full original field type (`HashMap<K, V>` / `BTreeMap<K, V>`). The reader
3721    /// regroups the `_keys`/`_values` list-columns and `collect()`s back into this
3722    /// exact map type — both `HashMap` and `BTreeMap` implement `FromIterator<(K, V)>`.
3723    pub(super) map_ty: syn::Type,
3724}
3725
3726/// Data for [`EnumResolvedField::Struct`].
3727///
3728/// A field whose inner type implements `DataFrameRow` expands to `<base_name>_<inner_col>`
3729/// prefixed columns — one output column per column emitted by the inner type's companion
3730/// DataFrame. Absent-variant rows produce `None` in every prefixed column.
3731///
3732/// The companion struct holds `Vec<Option<Inner>>` (not `Vec<Inner>`). The `into_data_frame`
3733/// method collects present rows into a dense `Vec<Inner>` (tracking presence indices),
3734/// calls `Inner::to_dataframe(present_rows)`, extracts named column SEXPs, and scatters
3735/// them back to the full row count with `None`-fill for absent rows.
3736pub(super) struct EnumStructFieldData {
3737    /// Base name for column prefixing (field name or `rename` override).
3738    pub(super) base_name: String,
3739    /// Binding name used in destructure pattern.
3740    pub(super) binding: syn::Ident,
3741    /// Original Rust field name.
3742    pub(super) rust_name: syn::Ident,
3743    /// Inner struct type (used for the compile-time DataFrameRow assertion and codegen).
3744    pub(super) inner_ty: syn::Type,
3745}
3746
3747/// Parsed and resolved information about a single enum variant for DataFrame codegen.
3748///
3749/// Contains the variant's name, shape (named/tuple/unit), resolved fields (after
3750/// applying `#[dataframe(...)]` attributes and type classification), and any
3751/// skipped field names (needed for complete destructure patterns in named variants).
3752pub(super) struct VariantInfo {
3753    /// Variant name.
3754    pub(super) name: syn::Ident,
3755    /// Shape of this variant.
3756    pub(super) shape: VariantShape,
3757    /// Resolved fields (after applying field attrs + type classification).
3758    pub(super) fields: Vec<EnumResolvedField>,
3759    /// Original Rust field names (for named variants) — needed for skipped fields in destructure.
3760    pub(super) skipped_fields: Vec<syn::Ident>,
3761}
3762// endregion
3763
3764// region: Enum-specific expansion (in sub-module)
3765
3766mod enum_expansion;
3767use enum_expansion::derive_enum_dataframe;
3768// endregion
3769
3770// region: tests
3771#[cfg(test)]
3772mod tests {
3773    use super::*;
3774
3775    /// Stringify the derive output (whitespace-normalised) for substring assertions.
3776    fn expand(input: DeriveInput) -> String {
3777        derive_dataframe_row(input).unwrap().to_string()
3778    }
3779
3780    #[test]
3781    fn struct_as_factor_is_one_readable_column() {
3782        let input: DeriveInput = syn::parse_quote! {
3783            struct Row {
3784                #[dataframe(as_factor, rename = "direction")]
3785                dir: Direction,
3786            }
3787        };
3788        let syn::Data::Struct(data) = &input.data else {
3789            unreachable!()
3790        };
3791        let resolved = resolve_struct_field(data.fields.iter().next().unwrap(), 0, false)
3792            .unwrap()
3793            .unwrap();
3794        assert!(matches!(&resolved, ResolvedField::Single(_)));
3795        assert!(field_reader_capable(&resolved));
3796        let code = expand(input);
3797        assert!(code.contains("FactorVec"));
3798        assert!(code.contains("Self :: try_from_dataframe (sexp)"));
3799    }
3800
3801    #[test]
3802    fn struct_as_factor_rejects_non_enum_shapes_at_the_field() {
3803        for ty in [quote! { i32 }, quote! { Vec<i32> }, quote! { [i32; 2] }] {
3804            let input = syn::parse_quote! {
3805                struct Row { #[dataframe(as_factor)] value: #ty }
3806            };
3807            let error = derive_dataframe_row(input).unwrap_err().to_string();
3808            assert!(error.contains("`as_factor` is only valid"), "{error}");
3809        }
3810    }
3811
3812    /// `Option<scalar>` struct fields are a single NA-able column (#1437): the
3813    /// derive accepts them, keeps the full `Option<T>` as the companion element
3814    /// type, and still emits the readers (the reader gate already knew the shape).
3815    #[test]
3816    fn option_scalar_struct_field_is_single_nullable_column() {
3817        let code = expand(syn::parse_quote! {
3818            #[derive(DataFrameRow)]
3819            struct Obs {
3820                id: i32,
3821                weight: Option<f64>,
3822                label: Option<String>,
3823                flag: Option<bool>,
3824            }
3825        });
3826        assert!(code.contains("weight"), "column kept, got:\n{code}");
3827        assert!(
3828            code.contains("Option < f64 >"),
3829            "companion stores Option<f64>, got:\n{code}"
3830        );
3831        assert!(code.contains("fn try_from_dataframe"));
3832        assert!(code.contains("fn try_from_dataframe_par"));
3833    }
3834
3835    #[test]
3836    fn nullable_raw_columns_explain_the_missing_na_representation() {
3837        for ty in [
3838            quote! { Option<u8> },
3839            quote! { ::core::option::Option<::core::primitive::u8> },
3840            quote! { std::option::Option<std::primitive::u8> },
3841        ] {
3842            let input = syn::parse_quote! { struct Row { bytes: #ty } };
3843            let error = derive_dataframe_row(input).unwrap_err().to_string();
3844            assert!(error.contains("raw vectors have no NA value"), "{error}");
3845            assert!(error.contains("Option<u16>"), "{error}");
3846            assert!(error.contains("Option<i32>"), "{error}");
3847        }
3848        for ty in [
3849            quote! { u8 },
3850            quote! { Option<u16> },
3851            quote! { Option<i32> },
3852        ] {
3853            let input = syn::parse_quote! { struct Row { bytes: #ty } };
3854            assert!(derive_dataframe_row(input).is_ok());
3855        }
3856    }
3857
3858    /// Every shape that pads a `u8` column with NA is rejected at the field;
3859    /// shapes that never need NA cells still derive (#2025).
3860    #[test]
3861    fn padded_raw_columns_name_the_field() {
3862        for field in [
3863            quote! { #[dataframe(width = 2)] bytes: Vec<u8> },
3864            quote! { #[dataframe(expand)] bytes: Vec<u8> },
3865            quote! { #[dataframe(expand)] bytes: Box<[::core::primitive::u8]> },
3866        ] {
3867            let input = syn::parse_quote! { struct Row { #field } };
3868            let error = derive_dataframe_row(input).unwrap_err().to_string();
3869            assert!(error.contains("pads shorter rows with NA"), "{error}");
3870            assert!(error.contains("raw vectors have no NA value"), "{error}");
3871        }
3872        for variant in [
3873            quote! { Bytes { byte: u8 } },
3874            quote! { Bytes(::core::primitive::u8) },
3875            quote! { Bytes { byte: Option<u8> } },
3876            quote! { Bytes([u8; 2]) },
3877            quote! { Bytes { #[dataframe(width = 2)] bytes: Vec<u8> } },
3878            quote! { Bytes(#[dataframe(expand)] Vec<u8>) },
3879        ] {
3880            let input = syn::parse_quote! {
3881                #[dataframe(tag = "kind")]
3882                enum Row { #variant, Empty }
3883            };
3884            let error = derive_dataframe_row(input).unwrap_err().to_string();
3885            assert!(
3886                error.contains("NA in rows of the other variants"),
3887                "{error}"
3888            );
3889            assert!(!error.contains("Use `u8`"), "{error}");
3890        }
3891        for input in [
3892            syn::parse_quote! { struct Row { byte: u8, pair: [u8; 2], bytes: Vec<u8> } },
3893            syn::parse_quote! {
3894                #[dataframe(tag = "kind")]
3895                enum Row { Bytes { bytes: Vec<u8> }, Empty }
3896            },
3897        ] {
3898            assert!(derive_dataframe_row(input).is_ok());
3899        }
3900    }
3901
3902    /// The #484 footgun stays closed: `Option` around a map / struct / collection
3903    /// is still rejected, now with a hint naming the supported scalar shape.
3904    #[test]
3905    fn option_non_scalar_struct_field_still_rejected() {
3906        for field_ty in [
3907            quote::quote!(Option<HashMap<String, i32>>),
3908            quote::quote!(Option<Inner>),
3909            quote::quote!(Option<Vec<f64>>),
3910        ] {
3911            let input: DeriveInput = syn::parse_quote! {
3912                #[derive(DataFrameRow)]
3913                struct Row {
3914                    id: i32,
3915                    payload: #field_ty,
3916                }
3917            };
3918            let err = derive_dataframe_row(input)
3919                .expect_err("Option<non-scalar> must be rejected")
3920                .to_string();
3921            assert!(
3922                err.contains("does not support `Option<…>`")
3923                    && err.contains("supported only around a scalar"),
3924                "message must name the supported shape, got: {err}"
3925            );
3926        }
3927    }
3928
3929    /// Enum variant fields already become `Option<T>` columns (absent for the
3930    /// other variants), so an `Option<scalar>` field there is rejected with a
3931    /// pointer to the bare scalar instead of failing on `Vec<Option<Option<T>>>`.
3932    /// A qualified payload gets the same message, not the generic wrapper one.
3933    #[test]
3934    fn option_scalar_enum_variant_field_rejected() {
3935        for note_ty in [
3936            quote::quote!(Option<String>),
3937            quote::quote!(::core::option::Option<::std::string::String>),
3938        ] {
3939            let input: DeriveInput = syn::parse_quote! {
3940                #[derive(DataFrameRow)]
3941                #[dataframe(tag = "kind")]
3942                enum Event {
3943                    Click { x: f64, note: #note_ty },
3944                    Key { code: i32 },
3945                }
3946            };
3947            let err = derive_dataframe_row(input)
3948                .expect_err("Option<scalar> in enum variant must be rejected")
3949                .to_string();
3950            assert!(
3951                err.contains("already become `Option<T>` columns"),
3952                "got: {err}"
3953            );
3954        }
3955    }
3956
3957    /// A qualified scalar classifies like its bare name (#2036): a leading `::`
3958    /// or a path prefix keeps the field a reader scalar and an `Option<…>`
3959    /// payload, so struct and enum rows keep both readers.
3960    #[test]
3961    fn qualified_scalar_fields_keep_readers() {
3962        let code = expand(syn::parse_quote! {
3963            #[derive(DataFrameRow)]
3964            struct Obs {
3965                id: ::core::primitive::i32,
3966                label: ::std::string::String,
3967                note: ::core::option::Option<::alloc::string::String>,
3968                weight: Option<std::primitive::f64>,
3969                relative: Option<std::string::String>,
3970                #[dataframe(width = 2)]
3971                pinned: Vec<::std::string::String>,
3972                keyed: BTreeMap<::core::primitive::i32, ::std::string::String>,
3973            }
3974        });
3975        assert!(code.contains("fn try_from_dataframe ("), "got:\n{code}");
3976        assert!(code.contains("fn try_from_dataframe_par ("), "got:\n{code}");
3977
3978        let code = expand(syn::parse_quote! {
3979            #[derive(DataFrameRow)]
3980            #[dataframe(tag = "kind")]
3981            enum Event {
3982                Named { label: ::std::string::String, pair: [::core::primitive::f64; 2] },
3983                Keyed { keyed: BTreeMap<::std::string::String, std::primitive::i32> },
3984                Empty,
3985            }
3986        });
3987        assert!(code.contains("fn try_from_dataframe ("), "got:\n{code}");
3988        assert!(code.contains("fn try_from_dataframe_par ("), "got:\n{code}");
3989    }
3990
3991    /// Borrowed expansions write columns, but owned R columns cannot recreate
3992    /// their borrows. Check each shape independently so one unsupported field
3993    /// cannot mask another shape's accidentally generated reader (#2028).
3994    #[test]
3995    fn borrowed_expansions_have_no_struct_or_enum_reader() {
3996        for field in [
3997            quote! { values: &'a [f64; 2] },
3998            quote! { #[dataframe(width = 2)] values: &'a [f64] },
3999            quote! { #[dataframe(expand)] values: &'a [f64] },
4000        ] {
4001            for input in [
4002                syn::parse_quote! { struct Row<'a> { #field } },
4003                syn::parse_quote! {
4004                    #[dataframe(tag = "kind")]
4005                    enum Row<'a> { Values { #field }, Empty }
4006                },
4007            ] {
4008                let tokens = derive_dataframe_row(input).unwrap();
4009                syn::parse2::<syn::File>(tokens.clone()).unwrap();
4010                let code = tokens.to_string();
4011                assert!(!code.contains("fn try_from_dataframe"), "{code}");
4012                assert!(!code.contains("fn from_dataframe_rows"), "{code}");
4013            }
4014        }
4015    }
4016
4017    /// Scalar named struct: the baseline `try_from_dataframe_par` shape (#765).
4018    /// Both the sequential and parallel readers must be emitted, and the parallel
4019    /// one must drive a `into_par_iter()` row-assembly region.
4020    #[test]
4021    fn scalar_struct_gets_parallel_reader() {
4022        let code = expand(syn::parse_quote! {
4023            #[derive(DataFrameRow)]
4024            struct Measurement {
4025                time: f64,
4026                value: f64,
4027            }
4028        });
4029        assert!(code.contains("fn try_from_dataframe"));
4030        assert!(code.contains("fn try_from_dataframe_par"));
4031        assert!(code.contains("into_par_iter"));
4032    }
4033
4034    /// `[T; N]` fixed-array expansion field (#782/#808): the reader regroups the
4035    /// `pos_1`/`pos_2` columns back into the array inside the parallel loop, with
4036    /// zero SEXP access in `into_par_iter` (the invariant #764 protects).
4037    #[test]
4038    fn fixed_array_struct_gets_parallel_reader() {
4039        let code = expand(syn::parse_quote! {
4040            #[derive(DataFrameRow)]
4041            struct Point {
4042                #[dataframe(rename = "pos")]
4043                pos: [f64; 2],
4044            }
4045        });
4046        assert!(code.contains("fn try_from_dataframe_par"));
4047        assert!(code.contains("into_par_iter"));
4048        // Regrouped from the suffixed expansion columns.
4049        assert!(code.contains("pos_1"));
4050        assert!(code.contains("pos_2"));
4051    }
4052
4053    /// `Vec<T>` + `width = N` expansion field (#782/#808): the reader flattens the
4054    /// `scores_1`/`scores_2` Option columns per row back into the vec.
4055    #[test]
4056    fn pinned_vec_struct_gets_parallel_reader() {
4057        let code = expand(syn::parse_quote! {
4058            #[derive(DataFrameRow)]
4059            struct Scored {
4060                #[dataframe(width = 2)]
4061                scores: Vec<i32>,
4062            }
4063        });
4064        assert!(code.contains("fn try_from_dataframe_par"));
4065        assert!(code.contains("into_par_iter"));
4066        assert!(code.contains("scores_1"));
4067        assert!(code.contains("scores_2"));
4068    }
4069
4070    /// `Vec<T>` + `expand` auto-expansion field (#782/#808): the reader discovers
4071    /// `tags_<i>` columns at runtime and flattens per row. Still a true parallel
4072    /// reader (the column discovery happens on the R thread, up front).
4073    #[test]
4074    fn auto_expand_struct_gets_parallel_reader() {
4075        let code = expand(syn::parse_quote! {
4076            #[derive(DataFrameRow)]
4077            struct Tagged {
4078                #[dataframe(expand)]
4079                tags: Vec<i32>,
4080            }
4081        });
4082        assert!(code.contains("fn try_from_dataframe_par"));
4083        assert!(code.contains("into_par_iter"));
4084    }
4085
4086    /// Struct-flatten field (#485/#808): the struct still gets readers, but the
4087    /// parallel variant deliberately delegates to the sequential one to avoid
4088    /// imposing `Inner: Clone` for by-index parallel assembly (#764 design note).
4089    #[test]
4090    fn struct_flatten_par_delegates_to_sequential() {
4091        let code = expand(syn::parse_quote! {
4092            #[derive(DataFrameRow)]
4093            struct Outer {
4094                id: i32,
4095                inner: Inner,
4096            }
4097        });
4098        assert!(code.contains("fn try_from_dataframe"));
4099        assert!(code.contains("fn try_from_dataframe_par"));
4100        // The `_par` body delegates rather than running its own `into_par_iter`.
4101        assert!(code.contains("Self :: try_from_dataframe (sexp)"));
4102    }
4103
4104    /// Tagged enum companion (#807/#816): enums now get full readers too, including
4105    /// a parallel per-row tag-dispatch loop. Documents that the #764 "no reader at
4106    /// all today" framing for enums is now stale.
4107    #[test]
4108    fn tagged_enum_gets_parallel_reader() {
4109        let code = expand(syn::parse_quote! {
4110            #[derive(DataFrameRow)]
4111            #[dataframe(tag = "_type")]
4112            enum Event {
4113                Click { x: i32, y: i32 },
4114                Key { code: i32 },
4115            }
4116        });
4117        assert!(code.contains("fn try_from_dataframe"));
4118        assert!(code.contains("fn try_from_dataframe_par"));
4119        assert!(code.contains("into_par_iter"));
4120    }
4121
4122    /// Struct-path `HashMap<String, V>` map column (#764): the list-of-named-lists
4123    /// column reads back whole via `Vec<map>: TryFromSexp` on the R thread, so the
4124    /// struct gets both readers (it shares the scalar `pull_col` path — zero SEXP
4125    /// access inside `into_par_iter`). Flips the pre-#764 lock-in test from #920.
4126    #[test]
4127    fn struct_with_string_keyed_map_field_gets_parallel_reader() {
4128        let code = expand(syn::parse_quote! {
4129            #[derive(DataFrameRow)]
4130            struct Config {
4131                opts: ::std::collections::HashMap<String, i32>,
4132            }
4133        });
4134        assert!(code.contains("fn try_from_dataframe"));
4135        assert!(code.contains("fn try_from_dataframe_par"));
4136        assert!(code.contains("into_par_iter"));
4137    }
4138
4139    /// `BTreeMap<String, Option<scalar>>` is also reader-capable: the
4140    /// `Vec<map>: TryFromSexp` impl is generic over `V: TryFromSexp`, and
4141    /// `Option<scalar>` qualifies (NULL list elements → `None`).
4142    #[test]
4143    fn struct_with_btreemap_option_value_gets_reader() {
4144        let code = expand(syn::parse_quote! {
4145            #[derive(DataFrameRow)]
4146            struct Config {
4147                opts: ::std::collections::BTreeMap<String, Option<f64>>,
4148            }
4149        });
4150        assert!(code.contains("fn try_from_dataframe"));
4151        assert!(code.contains("fn try_from_dataframe_par"));
4152    }
4153
4154    /// Non-`String` bare-scalar map keys (#919): the struct gets parallel `_keys`/`_values`
4155    /// list-columns and both readers. The write side uses `Vec<Vec<K>>/Vec<Vec<V>>: IntoR`
4156    /// (VECSXP of typed vectors); the read side zips them back into the map type per row.
4157    #[test]
4158    fn struct_with_non_string_keyed_map_gets_parallel_reader() {
4159        let code = expand(syn::parse_quote! {
4160            #[derive(DataFrameRow)]
4161            struct Config {
4162                opts: ::std::collections::HashMap<i32, f64>,
4163            }
4164        });
4165        assert!(
4166            code.contains("fn try_from_dataframe"),
4167            "non-String bare-scalar map keys should produce a reader via _keys/_values columns"
4168        );
4169        assert!(
4170            code.contains("fn try_from_dataframe_par"),
4171            "non-String bare-scalar map keys should produce a parallel reader"
4172        );
4173        assert!(
4174            code.contains("opts_keys"),
4175            "non-String map field `opts` should expand to `opts_keys` column"
4176        );
4177        assert!(
4178            code.contains("opts_values"),
4179            "non-String map field `opts` should expand to `opts_values` column"
4180        );
4181    }
4182
4183    /// Same as above but using an unqualified path `std::collections::BTreeMap` (no
4184    /// leading `::`) — path form used in actual rpkg fixtures.
4185    #[test]
4186    fn struct_with_btreemap_int_key_unqualified_path() {
4187        let code = expand(syn::parse_quote! {
4188            #[derive(DataFrameRow)]
4189            struct Tally {
4190                id: i32,
4191                tally: std::collections::BTreeMap<i32, f64>,
4192            }
4193        });
4194        assert!(
4195            code.contains("tally_keys"),
4196            "unqualified std::collections::BTreeMap<i32, f64> must expand to tally_keys"
4197        );
4198        assert!(
4199            code.contains("fn try_from_dataframe"),
4200            "unqualified BTreeMap<i32, f64> should produce a reader"
4201        );
4202    }
4203
4204    /// Float-keyed maps (`f32`/`f64`) are rejected with a clear error.
4205    #[test]
4206    #[should_panic]
4207    fn struct_with_float_keyed_map_is_rejected() {
4208        let _code = expand(syn::parse_quote! {
4209            #[derive(DataFrameRow)]
4210            struct Config {
4211                opts: ::std::collections::HashMap<f64, i32>,
4212            }
4213        });
4214    }
4215
4216    /// Custom-hasher maps (`HashMap<K, V, S>`) are rejected from the reader path:
4217    /// the `Vec<HashMap<String, V>>: TryFromSexp` impl only covers the default
4218    /// hasher, so emitting a reader would not compile.
4219    #[test]
4220    fn struct_with_custom_hasher_map_has_no_reader() {
4221        let code = expand(syn::parse_quote! {
4222            #[derive(DataFrameRow)]
4223            struct Config {
4224                opts: ::std::collections::HashMap<String, i32, MyHasher>,
4225            }
4226        });
4227        assert!(
4228            !code.contains("fn try_from_dataframe"),
4229            "custom-hasher maps lack `Vec<map>: TryFromSexp`; the reader must stay gated out"
4230        );
4231    }
4232}
4233// endregion