1use proc_macro2::TokenStream;
24use quote::{format_ident, quote};
25use syn::parse::{Parse, ParseStream};
26use syn::punctuated::Punctuated;
27use syn::{Attribute, Ident, Token, Type, TypePath, Visibility};
28
29pub struct TypedDataframeInput {
31 pub attrs: Vec<Attribute>,
33 pub vis: Visibility,
35 pub name: Ident,
37 pub fields: Vec<TypedDataframeField>,
39 pub allow_extra: bool,
42}
43
44pub struct TypedDataframeField {
46 pub attrs: Vec<Attribute>,
48 pub name: Ident,
50 pub elem_ty: Type,
52 pub optional: bool,
54}
55
56impl Parse for TypedDataframeInput {
57 fn parse(input: ParseStream) -> syn::Result<Self> {
58 let allow_extra = if input.peek(::syn::token::AtToken![@]) {
60 input.parse::<::syn::token::AtToken![@]>()?;
61 let mode: Ident = input.parse()?;
62 if mode != "exact" {
63 return Err(syn::Error::new_spanned(
64 mode,
65 "expected `exact` after @; use `@exact;` for strict mode",
66 ));
67 }
68 input.parse::<::syn::token::SemiToken![;]>()?;
69 false
70 } else {
71 true
72 };
73
74 let attrs = input.call(Attribute::parse_outer)?;
76
77 let vis: Visibility = input.parse()?;
79
80 let name: Ident = input.parse()?;
82
83 let content;
85 match ::syn::__private::parse_braces(&input) {
::syn::__private::Ok(braces) => {
content = braces.content;
_ = content;
braces.token
}
::syn::__private::Err(error) => { return ::syn::__private::Err(error); }
};syn::braced!(content in input);
86
87 let fields_punct: Punctuated<TypedDataframeField, ::syn::token::CommaToken![,]> =
88 Punctuated::parse_terminated(&content)?;
89 let fields: Vec<TypedDataframeField> = fields_punct.into_iter().collect();
90
91 if fields.is_empty() {
92 return Err(syn::Error::new(
93 name.span(),
94 "typed_dataframe! requires at least one column declaration",
95 ));
96 }
97
98 Ok(TypedDataframeInput {
99 attrs,
100 vis,
101 name,
102 fields,
103 allow_extra,
104 })
105 }
106}
107
108impl Parse for TypedDataframeField {
109 fn parse(input: ParseStream) -> syn::Result<Self> {
110 let attrs = input.call(Attribute::parse_outer)?;
111 let name: Ident = input.parse()?;
112 input.parse::<::syn::token::ColonToken![:]>()?;
113 let ty: Type = input.parse()?;
114
115 let (elem_ty, optional) = match unwrap_option(&ty) {
117 Some(inner) => (inner, true),
118 None => (ty, false),
119 };
120
121 Ok(TypedDataframeField {
122 attrs,
123 name,
124 elem_ty,
125 optional,
126 })
127 }
128}
129
130fn unwrap_option(ty: &Type) -> Option<Type> {
132 let Type::Path(TypePath { qself: None, path }) = ty else {
133 return None;
134 };
135 let segment = path.segments.last()?;
138 if segment.ident != "Option" {
139 return None;
140 }
141 let syn::PathArguments::AngleBracketed(args) = &segment.arguments else {
142 return None;
143 };
144 if args.args.len() != 1 {
145 return None;
146 }
147 let syn::GenericArgument::Type(inner) = args.args.first()? else {
148 return None;
149 };
150 Some(inner.clone())
151}
152
153pub fn expand_typed_dataframe(input: TypedDataframeInput) -> TokenStream {
156 let TypedDataframeInput {
157 attrs,
158 vis,
159 name,
160 fields,
161 allow_extra,
162 } = input;
163
164 let struct_name_str = name.to_string();
165
166 let col_fields = fields.iter().map(|f| {
168 let col_ident = match ::quote::__private::IdentFragmentAdapter(&crate::naming::unraw(&f.name))
{
arg =>
::quote::__private::mk_ident(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}_col", arg))
}), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("{}_col", crate::naming::unraw(&f.name));
169 if f.optional {
170 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&col_ident, &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, "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, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "SEXP");
::quote::__private::push_gt(&mut _s);
_s
}quote! { #col_ident: ::std::option::Option<::miniextendr_api::SEXP> }
171 } else {
172 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&col_ident, &mut _s);
::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");
_s
}quote! { #col_ident: ::miniextendr_api::SEXP }
173 }
174 });
175
176 let accessors = fields.iter().map(|f| {
177 let method_ident = &f.name;
178 let col_ident = match ::quote::__private::IdentFragmentAdapter(&crate::naming::unraw(&f.name))
{
arg =>
::quote::__private::mk_ident(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}_col", arg))
}), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("{}_col", crate::naming::unraw(&f.name));
179 let elem_ty = &f.elem_ty;
180 let method_attrs = &f.attrs;
181 if f.optional {
182 {
let mut _s = ::quote::__private::TokenStream::new();
{
use ::quote::__private::ext::*;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut method_attrs, i) = method_attrs.quote_into_iter();
let has_iter = has_iter | i;
<_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let method_attrs =
match method_attrs.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::ToTokens::to_tokens(&method_attrs, &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, "pub");
::quote::__private::push_ident(&mut _s, "fn");
::quote::ToTokens::to_tokens(&method_ident, &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_ident(&mut _s, "self");
_s
});
::quote::__private::push_rarrow(&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, "option");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "Option");
::quote::__private::push_lt(&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();
::quote::ToTokens::to_tokens(&elem_ty, &mut _s);
_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_ident(&mut _s, "self");
::quote::__private::push_dot(&mut _s);
::quote::ToTokens::to_tokens(&col_ident, &mut _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, "col");
::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::__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, "self");
::quote::__private::push_dot(&mut _s);
::quote::__private::push_ident(&mut _s, "nrow");
::quote::__private::push_semi(&mut _s);
::quote::__private::push_ident(&mut _s, "let");
::quote::__private::push_ident(&mut _s, "ptr");
::quote::__private::push_eq(&mut _s);
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&elem_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, "RNativeType");
::quote::__private::push_gt(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "dataptr_mut");
::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
});
::quote::__private::push_ident(&mut _s, "as");
::quote::__private::push_star(&mut _s);
::quote::__private::push_ident(&mut _s, "const");
::quote::ToTokens::to_tokens(&elem_ty, &mut _s);
::quote::__private::push_semi(&mut _s);
::quote::__private::push_ident(&mut _s, "if");
::quote::__private::push_ident(&mut _s, "len");
::quote::__private::push_eq_eq(&mut _s);
::quote::__private::parse(&mut _s, "0");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_and(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
::quote::__private::TokenStream::new());
_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_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "std");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "slice");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "from_raw_parts");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "ptr");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_ident(&mut _s, "len");
_s
});
_s
});
_s
});
_s
});
_s
});
_s
}quote! {
183 #(#method_attrs)*
184 #[inline]
185 pub fn #method_ident(&self) -> ::std::option::Option<&[#elem_ty]> {
186 self.#col_ident.map(|col| unsafe {
187 let len = self.nrow;
188 let ptr = <#elem_ty as ::miniextendr_api::RNativeType>::dataptr_mut(col)
189 as *const #elem_ty;
190 if len == 0 { &[] } else { ::std::slice::from_raw_parts(ptr, len) }
191 })
192 }
193 }
194 } else {
195 {
let mut _s = ::quote::__private::TokenStream::new();
{
use ::quote::__private::ext::*;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut method_attrs, i) = method_attrs.quote_into_iter();
let has_iter = has_iter | i;
<_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let method_attrs =
match method_attrs.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::ToTokens::to_tokens(&method_attrs, &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, "pub");
::quote::__private::push_ident(&mut _s, "fn");
::quote::ToTokens::to_tokens(&method_ident, &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_ident(&mut _s, "self");
_s
});
::quote::__private::push_rarrow(&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();
::quote::ToTokens::to_tokens(&elem_ty, &mut _s);
_s
});
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::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, "len");
::quote::__private::push_eq(&mut _s);
::quote::__private::push_ident(&mut _s, "self");
::quote::__private::push_dot(&mut _s);
::quote::__private::push_ident(&mut _s, "nrow");
::quote::__private::push_semi(&mut _s);
::quote::__private::push_ident(&mut _s, "let");
::quote::__private::push_ident(&mut _s, "ptr");
::quote::__private::push_eq(&mut _s);
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&elem_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, "RNativeType");
::quote::__private::push_gt(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "dataptr_mut");
::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_ident, &mut _s);
_s
});
::quote::__private::push_ident(&mut _s, "as");
::quote::__private::push_star(&mut _s);
::quote::__private::push_ident(&mut _s, "const");
::quote::ToTokens::to_tokens(&elem_ty, &mut _s);
::quote::__private::push_semi(&mut _s);
::quote::__private::push_ident(&mut _s, "if");
::quote::__private::push_ident(&mut _s, "len");
::quote::__private::push_eq_eq(&mut _s);
::quote::__private::parse(&mut _s, "0");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_and(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
::quote::__private::TokenStream::new());
_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_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "std");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "slice");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "from_raw_parts");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "ptr");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_ident(&mut _s, "len");
_s
});
_s
});
_s
});
_s
});
_s
}quote! {
196 #(#method_attrs)*
197 #[inline]
198 pub fn #method_ident(&self) -> &[#elem_ty] {
199 unsafe {
200 let len = self.nrow;
201 let ptr = <#elem_ty as ::miniextendr_api::RNativeType>::dataptr_mut(self.#col_ident)
202 as *const #elem_ty;
203 if len == 0 { &[] } else { ::std::slice::from_raw_parts(ptr, len) }
204 }
205 }
206 }
207 }
208 });
209
210 let validation_locals = fields.iter().map(|f| {
212 let col_ident = match ::quote::__private::IdentFragmentAdapter(&crate::naming::unraw(&f.name))
{
arg =>
::quote::__private::mk_ident(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}_col", arg))
}), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("{}_col", crate::naming::unraw(&f.name));
213 let name_str = crate::naming::ident_name(&f.name);
214 let elem_ty = &f.elem_ty;
215 if f.optional {
216 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "let");
::quote::ToTokens::to_tokens(&col_ident, &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, "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, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "SEXP");
::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, "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::ToTokens::to_tokens(&name_str, &mut _s);
_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, "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_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "std");
::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_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, "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, "col");
_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, "actual");
::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, "SexpExt");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "type_of");
::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");
_s
});
::quote::__private::push_semi(&mut _s);
::quote::__private::push_ident(&mut _s, "let");
::quote::__private::push_ident(&mut _s, "expected");
::quote::__private::push_eq(&mut _s);
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&elem_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, "RNativeType");
::quote::__private::push_gt(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "SEXP_TYPE");
::quote::__private::push_semi(&mut _s);
::quote::__private::push_ident(&mut _s, "if");
::quote::__private::push_ident(&mut _s, "actual");
::quote::__private::push_ne(&mut _s);
::quote::__private::push_ident(&mut _s, "expected");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "__errs");
::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, "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 `{}`: expected {} ({:?}), got {:?}\"");
::quote::__private::push_comma(&mut _s);
::quote::ToTokens::to_tokens(&name_str, &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, "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(&elem_ty, &mut _s);
_s
});
::quote::__private::push_comma(&mut _s);
::quote::__private::push_ident(&mut _s, "expected");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_ident(&mut _s, "actual");
::quote::__private::push_comma(&mut _s);
_s
});
_s
});
::quote::__private::push_semi(&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, "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");
_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_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "std");
::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, "col");
_s
});
_s
});
_s
});
_s
});
_s
});
::quote::__private::push_semi(&mut _s);
_s
}quote! {
217 let #col_ident: ::std::option::Option<::miniextendr_api::SEXP> = {
218 match view.column_raw(#name_str) {
219 ::std::option::Option::None => ::std::option::Option::None,
220 ::std::option::Option::Some(col) => {
221 let actual = ::miniextendr_api::SexpExt::type_of(&col);
222 let expected = <#elem_ty as ::miniextendr_api::RNativeType>::SEXP_TYPE;
223 if actual != expected {
224 __errs.push(::std::format!(
225 "column `{}`: expected {} ({:?}), got {:?}",
226 #name_str,
227 ::std::stringify!(#elem_ty),
228 expected,
229 actual,
230 ));
231 ::std::option::Option::None
232 } else {
233 ::std::option::Option::Some(col)
234 }
235 }
236 }
237 };
238 }
239 } else {
240 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "let");
::quote::ToTokens::to_tokens(&col_ident, &mut _s);
::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_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, "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::ToTokens::to_tokens(&name_str, &mut _s);
_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, "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, "__errs");
::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, "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,
"\"missing required column `{}` (expected {} / {:?})\"");
::quote::__private::push_comma(&mut _s);
::quote::ToTokens::to_tokens(&name_str, &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, "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(&elem_ty, &mut _s);
_s
});
::quote::__private::push_comma(&mut _s);
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&elem_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, "RNativeType");
::quote::__private::push_gt(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "SEXP_TYPE");
::quote::__private::push_comma(&mut _s);
_s
});
_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, "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());
_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, "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, "col");
_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, "actual");
::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, "SexpExt");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "type_of");
::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");
_s
});
::quote::__private::push_semi(&mut _s);
::quote::__private::push_ident(&mut _s, "let");
::quote::__private::push_ident(&mut _s, "expected");
::quote::__private::push_eq(&mut _s);
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&elem_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, "RNativeType");
::quote::__private::push_gt(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "SEXP_TYPE");
::quote::__private::push_semi(&mut _s);
::quote::__private::push_ident(&mut _s, "if");
::quote::__private::push_ident(&mut _s, "actual");
::quote::__private::push_ne(&mut _s);
::quote::__private::push_ident(&mut _s, "expected");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "__errs");
::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, "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 `{}`: expected {} ({:?}), got {:?}\"");
::quote::__private::push_comma(&mut _s);
::quote::ToTokens::to_tokens(&name_str, &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, "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(&elem_ty, &mut _s);
_s
});
::quote::__private::push_comma(&mut _s);
::quote::__private::push_ident(&mut _s, "expected");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_ident(&mut _s, "actual");
::quote::__private::push_comma(&mut _s);
_s
});
_s
});
::quote::__private::push_semi(&mut _s);
_s
});
::quote::__private::push_ident(&mut _s, "col");
_s
});
_s
});
_s
});
::quote::__private::push_semi(&mut _s);
_s
}quote! {
241 let #col_ident: ::miniextendr_api::SEXP = {
242 match view.column_raw(#name_str) {
243 ::std::option::Option::None => {
244 __errs.push(::std::format!(
245 "missing required column `{}` (expected {} / {:?})",
246 #name_str,
247 ::std::stringify!(#elem_ty),
248 <#elem_ty as ::miniextendr_api::RNativeType>::SEXP_TYPE,
249 ));
250 ::miniextendr_api::SEXP::nil()
251 }
252 ::std::option::Option::Some(col) => {
253 let actual = ::miniextendr_api::SexpExt::type_of(&col);
254 let expected = <#elem_ty as ::miniextendr_api::RNativeType>::SEXP_TYPE;
255 if actual != expected {
256 __errs.push(::std::format!(
257 "column `{}`: expected {} ({:?}), got {:?}",
258 #name_str,
259 ::std::stringify!(#elem_ty),
260 expected,
261 actual,
262 ));
263 }
264 col
265 }
266 }
267 };
268 }
269 }
270 });
271
272 let col_idents = fields
273 .iter()
274 .map(|f| match ::quote::__private::IdentFragmentAdapter(&crate::naming::unraw(&f.name))
{
arg =>
::quote::__private::mk_ident(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}_col", arg))
}), ::quote::__private::Option::None.or(arg.span())),
}format_ident!("{}_col", crate::naming::unraw(&f.name)));
275 let col_idents_for_struct = col_idents.clone();
276
277 let declared_names: Vec<String> = fields
278 .iter()
279 .map(|f| crate::naming::ident_name(&f.name))
280 .collect();
281 let declared_count = fields.len();
282 let allow_extra_check = if allow_extra {
283 ::quote::__private::TokenStream::new();quote! {}
284 } else {
285 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "const");
::quote::__private::push_ident(&mut _s, "__DECLARED");
::quote::__private::push_colon(&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();
::quote::__private::push_and(&mut _s);
::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 declared_names, i) =
declared_names.quote_into_iter();
let has_iter = has_iter | i;
<_ as
::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let declared_names =
match declared_names.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
if !_first { ::quote::__private::push_comma(&mut _s); }
_first = false;
::quote::ToTokens::to_tokens(&declared_names, &mut _s);
}
}
_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, "__extras");
::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, "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, "for");
::quote::__private::push_ident(&mut _s, "col_name");
::quote::__private::push_ident(&mut _s, "in");
::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_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "if");
::quote::__private::push_bang(&mut _s);
::quote::__private::push_ident(&mut _s, "__DECLARED");
::quote::__private::push_dot(&mut _s);
::quote::__private::push_ident(&mut _s, "contains");
::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_name");
::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_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "__extras");
::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, "col_name");
::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
});
_s
});
::quote::__private::push_ident(&mut _s, "if");
::quote::__private::push_bang(&mut _s);
::quote::__private::push_ident(&mut _s, "__extras");
::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, "__errs");
::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, "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,
"\"unexpected extra columns: {:?}\"");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_ident(&mut _s, "__extras");
_s
});
_s
});
::quote::__private::push_semi(&mut _s);
_s
});
_s
}quote! {
286 const __DECLARED: &[&str] = &[#( #declared_names ),*];
288 let mut __extras: ::std::vec::Vec<::std::string::String> = ::std::vec::Vec::new();
289 for col_name in view.names() {
290 if !__DECLARED.contains(&col_name.as_str()) {
291 __extras.push(col_name.to_string());
292 }
293 }
294 if !__extras.is_empty() {
295 __errs.push(::std::format!(
296 "unexpected extra columns: {:?}",
297 __extras
298 ));
299 }
300 }
301 };
302
303 {
let mut _s = ::quote::__private::TokenStream::new();
{
use ::quote::__private::ext::*;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut attrs, i) = attrs.quote_into_iter();
let has_iter = has_iter | i;
<_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let attrs =
match attrs.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::ToTokens::to_tokens(&attrs, &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, "allow");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "non_snake_case");
_s
});
_s
});
::quote::ToTokens::to_tokens(&vis, &mut _s);
::quote::__private::push_ident(&mut _s, "struct");
::quote::ToTokens::to_tokens(&name, &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, "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);
::quote::__private::push_ident(&mut _s, "nrow");
::quote::__private::push_colon(&mut _s);
::quote::__private::push_ident(&mut _s, "usize");
::quote::__private::push_comma(&mut _s);
{
use ::quote::__private::ext::*;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut col_fields, i) = col_fields.quote_into_iter();
let has_iter = has_iter | i;
<_ as
::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let col_fields =
match col_fields.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::ToTokens::to_tokens(&col_fields, &mut _s);
::quote::__private::push_comma(&mut _s);
}
}
_s
});
::quote::__private::push_ident(&mut _s, "impl");
::quote::ToTokens::to_tokens(&name, &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\" Number of rows in the underlying data.frame.\"");
_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, "pub");
::quote::__private::push_ident(&mut _s, "fn");
::quote::__private::push_ident(&mut _s, "nrow");
::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, "usize");
::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, "nrow");
_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\" Number of declared columns.\"");
_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, "pub");
::quote::__private::push_ident(&mut _s, "fn");
::quote::__private::push_ident(&mut _s, "ncol");
::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, "usize");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&declared_count, &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, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::parse(&mut _s,
"r\" The backing SEXP (preserves the data.frame class attribute).\"");
_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, "pub");
::quote::__private::push_ident(&mut _s, "fn");
::quote::__private::push_ident(&mut _s, "as_sexp");
::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_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_ident(&mut _s, "self");
::quote::__private::push_dot(&mut _s);
::quote::__private::push_ident(&mut _s, "sexp");
_s
});
{
use ::quote::__private::ext::*;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut accessors, i) = accessors.quote_into_iter();
let has_iter = has_iter | i;
<_ as
::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let accessors =
match accessors.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::ToTokens::to_tokens(&accessors, &mut _s);
}
}
_s
});
::quote::__private::push_ident(&mut _s, "impl");
::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_ident(&mut _s, "for");
::quote::ToTokens::to_tokens(&name, &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, "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, "SexpError");
::quote::__private::push_semi(&mut _s);
::quote::__private::push_ident(&mut _s, "fn");
::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, "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, "std");
::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_ident(&mut _s, "Self");
::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, "from_r");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "SexpError");
::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, "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, "SexpExt");
::quote::__private::push_ident(&mut _s, "as");
::quote::__private::push_underscore(&mut _s);
::quote::__private::push_semi(&mut _s);
::quote::__private::push_ident(&mut _s, "if");
::quote::__private::push_bang(&mut _s);
::quote::__private::push_ident(&mut _s, "sexp");
::quote::__private::push_dot(&mut _s);
::quote::__private::push_ident(&mut _s, "is_data_frame");
::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, "std");
::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, "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, "SexpError");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "InvalidValue");
::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,
"\"{}: expected a data.frame, got {:?}\"");
::quote::__private::push_comma(&mut _s);
::quote::ToTokens::to_tokens(&struct_name_str, &mut _s);
::quote::__private::push_comma(&mut _s);
::quote::__private::push_ident(&mut _s, "sexp");
::quote::__private::push_dot(&mut _s);
::quote::__private::push_ident(&mut _s, "type_of");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
::quote::__private::TokenStream::new());
::quote::__private::push_comma(&mut _s);
_s
});
_s
});
_s
});
::quote::__private::push_semi(&mut _s);
_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_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, "SexpError");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "InvalidValue");
::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(&struct_name_str, &mut _s);
::quote::__private::push_comma(&mut _s);
::quote::__private::push_ident(&mut _s, "e");
_s
});
_s
});
_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);
::quote::__private::push_ident(&mut _s, "let");
::quote::__private::push_ident(&mut _s, "mut");
::quote::__private::push_ident(&mut _s, "__errs");
::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, "new");
::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 validation_locals, i) =
validation_locals.quote_into_iter();
let has_iter = has_iter | i;
<_ as
::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let validation_locals =
match validation_locals.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::ToTokens::to_tokens(&validation_locals, &mut _s);
}
}
::quote::ToTokens::to_tokens(&allow_extra_check, &mut _s);
::quote::__private::push_ident(&mut _s, "if");
::quote::__private::push_bang(&mut _s);
::quote::__private::push_ident(&mut _s, "__errs");
::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, "std");
::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, "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, "SexpError");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "InvalidValue");
::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(&struct_name_str, &mut _s);
::quote::__private::push_comma(&mut _s);
::quote::__private::push_ident(&mut _s, "__errs");
::quote::__private::push_dot(&mut _s);
::quote::__private::push_ident(&mut _s, "join");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::parse(&mut _s, "\"; \"");
_s
});
_s
});
_s
});
_s
});
::quote::__private::push_semi(&mut _s);
_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, "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::ToTokens::to_tokens(&name, &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, "sexp");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_ident(&mut _s, "nrow");
::quote::__private::push_comma(&mut _s);
{
use ::quote::__private::ext::*;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut col_idents_for_struct, i) =
col_idents_for_struct.quote_into_iter();
let has_iter = has_iter | i;
<_ as
::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let col_idents_for_struct =
match col_idents_for_struct.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::ToTokens::to_tokens(&col_idents_for_struct,
&mut _s);
::quote::__private::push_comma(&mut _s);
}
}
_s
});
_s
});
_s
});
_s
});
_s
}quote! {
304 #(#attrs)*
305 #[allow(non_snake_case)]
306 #vis struct #name {
307 sexp: ::miniextendr_api::SEXP,
308 nrow: usize,
309 #( #col_fields, )*
310 }
311
312 impl #name {
313 #[inline]
315 pub fn nrow(&self) -> usize { self.nrow }
316
317 #[inline]
319 pub fn ncol(&self) -> usize { #declared_count }
320
321 #[inline]
323 pub fn as_sexp(&self) -> ::miniextendr_api::SEXP { self.sexp }
324
325 #( #accessors )*
326 }
327
328 impl ::miniextendr_api::from_r::TryFromSexp for #name {
329 type Error = ::miniextendr_api::from_r::SexpError;
330
331 fn try_from_sexp(
332 sexp: ::miniextendr_api::SEXP,
333 ) -> ::std::result::Result<Self, ::miniextendr_api::from_r::SexpError> {
334 use ::miniextendr_api::SexpExt as _;
335
336 if !sexp.is_data_frame() {
338 return ::std::result::Result::Err(
339 ::miniextendr_api::from_r::SexpError::InvalidValue(
340 ::std::format!(
341 "{}: expected a data.frame, got {:?}",
342 #struct_name_str,
343 sexp.type_of(),
344 )
345 )
346 );
347 }
348
349 let view = ::miniextendr_api::dataframe::DataFrame::from_sexp(sexp)
351 .map_err(|e| ::miniextendr_api::from_r::SexpError::InvalidValue(
352 ::std::format!("{}: {}", #struct_name_str, e)
353 ))?;
354 let nrow = view.nrow();
355
356 let mut __errs: ::std::vec::Vec<::std::string::String> =
358 ::std::vec::Vec::new();
359
360 #( #validation_locals )*
361
362 #allow_extra_check
363
364 if !__errs.is_empty() {
365 return ::std::result::Result::Err(
366 ::miniextendr_api::from_r::SexpError::InvalidValue(
367 ::std::format!(
368 "{}: {}",
369 #struct_name_str,
370 __errs.join("; ")
371 )
372 )
373 );
374 }
375
376 ::std::result::Result::Ok(#name {
377 sexp,
378 nrow,
379 #( #col_idents_for_struct, )*
380 })
381 }
382 }
383 }
384}
385
386#[cfg(test)]
387mod tests {
388 use super::*;
389
390 #[test]
391 fn test_parse_basic() {
392 let input: TypedDataframeInput = syn::parse_quote! {
393 pub TheophDf {
394 subject: i32,
395 weight: f64,
396 }
397 };
398 assert_eq!(input.name.to_string(), "TheophDf");
399 assert_eq!(input.fields.len(), 2);
400 assert_eq!(input.fields[0].name.to_string(), "subject");
401 assert!(!input.fields[0].optional);
402 assert!(input.allow_extra);
403 }
404
405 #[test]
406 fn test_parse_optional() {
407 let input: TypedDataframeInput = syn::parse_quote! {
408 pub Df { x: i32, y: Option<f64> }
409 };
410 assert!(!input.fields[0].optional);
411 assert!(input.fields[1].optional);
412 }
413
414 #[test]
415 fn test_parse_exact_mode() {
416 let input: TypedDataframeInput = syn::parse_quote! {
417 @exact;
418 pub Df { x: i32 }
419 };
420 assert!(!input.allow_extra);
421 }
422
423 #[test]
424 fn test_parse_with_doc_attrs() {
425 let input: TypedDataframeInput = syn::parse_quote! {
426 pub TheophDf {
428 subject: i32,
430 }
431 };
432 assert!(!input.attrs.is_empty());
433 assert!(!input.fields[0].attrs.is_empty());
434 }
435
436 #[test]
437 fn test_parse_empty_fails() {
438 let result: syn::Result<TypedDataframeInput> = syn::parse2(quote! {
439 pub Df {}
440 });
441 assert!(result.is_err());
442 }
443}