1use proc_macro2::TokenStream;
44use quote::quote;
45use syn::{Data, DeriveInput, Fields, Type};
46
47struct Newtype {
49 inner: Type,
50 named_field: Option<syn::Ident>,
52}
53
54impl Newtype {
55 fn wrap(&self, val: &TokenStream) -> TokenStream {
57 match &self.named_field {
58 Some(field) => {
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();
::quote::ToTokens::to_tokens(&field, &mut _s);
::quote::__private::push_colon(&mut _s);
::quote::ToTokens::to_tokens(&val, &mut _s);
_s
});
_s
}quote! { Self { #field: #val } },
59 None => {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "Self");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&val, &mut _s);
_s
});
_s
}quote! { Self(#val) },
60 }
61 }
62
63 fn unwrap(&self, binding: &TokenStream) -> TokenStream {
65 match &self.named_field {
66 Some(field) => {
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&binding, &mut _s);
::quote::__private::push_dot(&mut _s);
::quote::ToTokens::to_tokens(&field, &mut _s);
_s
}quote! { #binding.#field },
67 None => {
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&binding, &mut _s);
::quote::__private::push_dot(&mut _s);
::quote::__private::parse(&mut _s, "0");
_s
}quote! { #binding.0 },
68 }
69 }
70}
71
72fn parse_newtype(input: &DeriveInput) -> syn::Result<Newtype> {
73 let data = match &input.data {
74 Data::Struct(data) => data,
75 _ => {
76 return Err(syn::Error::new_spanned(
77 &input.ident,
78 "this derive only works on single-field newtype structs",
79 ));
80 }
81 };
82 match &data.fields {
83 Fields::Unnamed(fields) if fields.unnamed.len() == 1 => Ok(Newtype {
84 inner: fields.unnamed.first().unwrap().ty.clone(),
85 named_field: None,
86 }),
87 Fields::Named(fields) if fields.named.len() == 1 => {
88 let field = fields.named.first().unwrap();
89 Ok(Newtype {
90 inner: field.ty.clone(),
91 named_field: Some(field.ident.clone().unwrap()),
92 })
93 }
94 _ => Err(syn::Error::new_spanned(
95 &input.ident,
96 "this derive requires a struct with exactly one field",
97 )),
98 }
99}
100
101fn where_with(base: &Option<syn::WhereClause>, extra: &[TokenStream]) -> TokenStream {
104 let mut preds: Vec<TokenStream> = base
105 .iter()
106 .flat_map(|w| w.predicates.iter().map(|p| {
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&p, &mut _s);
_s
}quote! { #p }))
107 .collect();
108 preds.extend(extra.iter().cloned());
109 {
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),* }
110}
111
112#[derive(#[automatically_derived]
impl ::core::default::Default for TryFromSexpOptions {
#[inline]
fn default() -> Self {
TryFromSexpOptions { validate: ::core::default::Default::default() }
}
}Default)]
114struct TryFromSexpOptions {
115 validate: Option<syn::Path>,
117}
118
119fn parse_try_from_sexp_options(input: &DeriveInput) -> syn::Result<TryFromSexpOptions> {
123 let mut options = TryFromSexpOptions::default();
124 for attr in input
125 .attrs
126 .iter()
127 .filter(|a| a.path().is_ident("try_from_sexp"))
128 {
129 attr.parse_nested_meta(|meta| {
130 if meta.path.is_ident("validate") {
131 if options.validate.is_some() {
132 return Err(meta.error("duplicate `validate` in `#[try_from_sexp(...)]`"));
133 }
134 options.validate = Some(meta.value()?.parse()?);
135 Ok(())
136 } else {
137 Err(meta.error(
138 "unknown `#[try_from_sexp(...)]` key; the only key is `validate = path::to::check`",
139 ))
140 }
141 })?;
142 }
143 if let Data::Struct(data) = &input.data {
144 for field in &data.fields {
145 if let Some(attr) = field
146 .attrs
147 .iter()
148 .find(|a| a.path().is_ident("try_from_sexp"))
149 {
150 return Err(syn::Error::new_spanned(
151 attr,
152 "`#[try_from_sexp(...)]` goes on the struct, not on its field",
153 ));
154 }
155 }
156 }
157 Ok(options)
158}
159
160pub fn derive_try_from_sexp(input: DeriveInput) -> syn::Result<TokenStream> {
166 let nt = parse_newtype(&input)?;
167 let options = parse_try_from_sexp_options(&input)?;
168 let inner = &nt.inner;
169 let name = &input.ident;
170 let (impl_generics, ty_generics, _) = input.generics.split_for_impl();
171 let base_where = &input.generics.where_clause;
172
173 let wrap_val = nt.wrap(&{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "val");
_s
}quote! { val });
174 let wrap_inner = nt.wrap(&{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "inner");
_s
}quote! { inner });
175 let field = nt.unwrap(&{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "self");
_s
}quote! { self });
176 let inner_converts = {
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&inner, &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, "TryFromSexp");
_s
}quote! { #inner: ::miniextendr_api::TryFromSexp };
177 let inner_try_from = {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&inner, &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, "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, "sexp");
_s
});
_s
}quote! { <#inner as ::miniextendr_api::TryFromSexp>::try_from_sexp(sexp) };
178 let inner_try_from_unchecked = {
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_lt(&mut _s);
::quote::ToTokens::to_tokens(&inner, &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, "TryFromSexp");
::quote::__private::push_gt(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s,
"try_from_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, "sexp");
_s
});
_s
});
_s
}quote! {
179 unsafe { <#inner as ::miniextendr_api::TryFromSexp>::try_from_sexp_unchecked(sexp) }
180 };
181
182 let (from_where, error, try_from, try_from_unchecked, check_sexp) = match &options.validate {
186 None => (
187 where_with(base_where, &[inner_converts]),
188 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&inner, &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, "TryFromSexp");
::quote::__private::push_gt(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "Error");
_s
}quote! { <#inner as ::miniextendr_api::TryFromSexp>::Error },
189 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&inner_try_from, &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, "val");
::quote::__private::push_or(&mut _s);
::quote::ToTokens::to_tokens(&wrap_val, &mut _s);
_s
});
_s
}quote! { #inner_try_from.map(|val| #wrap_val) },
190 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&inner_try_from_unchecked, &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, "val");
::quote::__private::push_or(&mut _s);
::quote::ToTokens::to_tokens(&wrap_val, &mut _s);
_s
});
_s
}quote! { #inner_try_from_unchecked.map(|val| #wrap_val) },
191 TokenStream::new(),
192 ),
193 Some(validate) => {
194 let check = {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_lt(&mut _s);
::quote::__private::push_ident(&mut _s, "Self");
::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, "TryFromSexpElement");
::quote::__private::push_gt(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "check_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_question(&mut _s);
::quote::__private::push_semi(&mut _s);
_s
}quote! {
195 <Self as ::miniextendr_api::TryFromSexpElement>::check_sexp(sexp)?;
196 };
197 (
198 where_with(
199 base_where,
200 &[
201 inner_converts,
202 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&inner, &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, "TryFromSexp");
::quote::__private::push_gt(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "Error");
::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, "convert");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "Into");
::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, "from_r");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "SexpError");
::quote::__private::push_gt(&mut _s);
_s
}quote! {
203 <#inner as ::miniextendr_api::TryFromSexp>::Error:
204 ::core::convert::Into<::miniextendr_api::from_r::SexpError>
205 },
206 ],
207 ),
208 {
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");
_s
}quote! { ::miniextendr_api::from_r::SexpError },
209 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&check, &mut _s);
::quote::ToTokens::to_tokens(&inner_try_from, &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, "val");
::quote::__private::push_or(&mut _s);
::quote::ToTokens::to_tokens(&wrap_val, &mut _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_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");
_s
});
_s
}quote! {
210 #check
211 #inner_try_from.map(|val| #wrap_val).map_err(::core::convert::Into::into)
212 },
213 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&check, &mut _s);
::quote::ToTokens::to_tokens(&inner_try_from_unchecked, &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, "val");
::quote::__private::push_or(&mut _s);
::quote::ToTokens::to_tokens(&wrap_val, &mut _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_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");
_s
});
_s
}quote! {
214 #check
215 #inner_try_from_unchecked.map(|val| #wrap_val).map_err(::core::convert::Into::into)
216 },
217 {
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, "inline");
_s
});
::quote::__private::push_ident(&mut _s, "fn");
::quote::__private::push_ident(&mut _s, "check_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, "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_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
::quote::__private::TokenStream::new());
::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::ToTokens::to_tokens(&validate, &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, "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_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");
_s
});
_s
});
_s
}quote! {
218 #[inline]
219 fn check_sexp(
220 sexp: ::miniextendr_api::SEXP,
221 ) -> ::core::result::Result<(), ::miniextendr_api::from_r::SexpError> {
222 #validate(sexp).map_err(::core::convert::Into::into)
223 }
224 },
225 )
226 }
227 };
228
229 let expectation = expectation_const(inner);
234 Ok({
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_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, "TryFromSexp");
::quote::__private::push_ident(&mut _s, "for");
::quote::ToTokens::to_tokens(&name, &mut _s);
::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
::quote::ToTokens::to_tokens(&from_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, "Error");
::quote::__private::push_eq(&mut _s);
::quote::ToTokens::to_tokens(&error, &mut _s);
::quote::__private::push_semi(&mut _s);
::quote::__private::push_ident(&mut _s, "const");
::quote::__private::push_ident(&mut _s, "NATIVE_BORROW");
::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, "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, "from_r");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "NativeBorrow");
::quote::__private::push_gt(&mut _s);
::quote::__private::push_eq(&mut _s);
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&inner, &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, "TryFromSexp");
::quote::__private::push_gt(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "NATIVE_BORROW");
::quote::__private::push_semi(&mut _s);
::quote::__private::push_ident(&mut _s, "const");
::quote::__private::push_ident(&mut _s, "CHARACTER_ONLY");
::quote::__private::push_colon(&mut _s);
::quote::__private::push_ident(&mut _s, "bool");
::quote::__private::push_eq(&mut _s);
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&inner, &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, "TryFromSexp");
::quote::__private::push_gt(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "CHARACTER_ONLY");
::quote::__private::push_semi(&mut _s);
::quote::__private::push_ident(&mut _s, "const");
::quote::__private::push_ident(&mut _s, "__MX_EXPECTATION");
::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, "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_lifetime(&mut _s, "\'static");
::quote::__private::push_ident(&mut _s, "str");
::quote::__private::push_gt(&mut _s);
::quote::__private::push_eq(&mut _s);
::quote::ToTokens::to_tokens(&expectation, &mut _s);
::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, "__mx_has_na");
::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, "bool");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&inner, &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, "TryFromSexp");
::quote::__private::push_gt(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "__mx_has_na");
::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(&field, &mut _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, "inline");
_s
});
::quote::__private::push_ident(&mut _s, "fn");
::quote::__private::push_ident(&mut _s, "__mx_input_has_na");
::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, "input");
::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::__private::push_rarrow(&mut _s);
::quote::__private::push_ident(&mut _s, "bool");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&inner, &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, "TryFromSexp");
::quote::__private::push_gt(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s,
"__mx_input_has_na");
::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(&field, &mut _s);
::quote::__private::push_comma(&mut _s);
::quote::__private::push_ident(&mut _s, "input");
_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, "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");
_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_ident(&mut _s, "Self");
::quote::__private::push_comma(&mut _s);
::quote::ToTokens::to_tokens(&error, &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(&try_from, &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, "inline");
_s
});
::quote::__private::push_ident(&mut _s, "unsafe");
::quote::__private::push_ident(&mut _s, "fn");
::quote::__private::push_ident(&mut _s,
"try_from_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, "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");
_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_ident(&mut _s, "Self");
::quote::__private::push_comma(&mut _s);
::quote::ToTokens::to_tokens(&error, &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(&try_from_unchecked, &mut _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, "automatically_derived");
_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, "TryFromSexpElement");
::quote::__private::push_ident(&mut _s, "for");
::quote::ToTokens::to_tokens(&name, &mut _s);
::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
::quote::ToTokens::to_tokens(&base_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, "Inner");
::quote::__private::push_eq(&mut _s);
::quote::ToTokens::to_tokens(&inner, &mut _s);
::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, "from_inner");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "inner");
::quote::__private::push_colon(&mut _s);
::quote::ToTokens::to_tokens(&inner, &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(&wrap_inner, &mut _s);
_s
});
::quote::ToTokens::to_tokens(&check_sexp, &mut _s);
_s
});
_s
}quote! {
235 #[automatically_derived]
236 impl #impl_generics ::miniextendr_api::TryFromSexp for #name #ty_generics #from_where {
237 type Error = #error;
238 const NATIVE_BORROW: ::core::option::Option<::miniextendr_api::from_r::NativeBorrow> =
239 <#inner as ::miniextendr_api::TryFromSexp>::NATIVE_BORROW;
240 const CHARACTER_ONLY: bool = <#inner as ::miniextendr_api::TryFromSexp>::CHARACTER_ONLY;
241 const __MX_EXPECTATION: ::core::option::Option<&'static str> = #expectation;
242 #[inline]
243 fn __mx_has_na(&self) -> bool {
244 <#inner as ::miniextendr_api::TryFromSexp>::__mx_has_na(&#field)
245 }
246 #[inline]
247 fn __mx_input_has_na(&self, input: ::miniextendr_api::SEXP) -> bool {
248 <#inner as ::miniextendr_api::TryFromSexp>::__mx_input_has_na(&#field, input)
249 }
250 #[inline]
251 fn try_from_sexp(sexp: ::miniextendr_api::SEXP) -> ::core::result::Result<Self, #error> {
252 #try_from
253 }
254 #[inline]
255 unsafe fn try_from_sexp_unchecked(sexp: ::miniextendr_api::SEXP) -> ::core::result::Result<Self, #error> {
256 #try_from_unchecked
257 }
258 }
259
260 #[automatically_derived]
261 impl #impl_generics ::miniextendr_api::TryFromSexpElement for #name #ty_generics #base_where {
262 type Inner = #inner;
263 #[inline]
264 fn from_inner(inner: #inner) -> Self {
265 #wrap_inner
266 }
267 #check_sexp
268 }
269 })
270}
271
272fn expectation_const(inner: &Type) -> TokenStream {
279 match crate::r_preconditions::conversion_expectation(inner, false) {
280 Some(expected) => {
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(&expected, &mut _s);
_s
});
_s
}quote! { ::core::option::Option::Some(#expected) },
281 None => {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&inner, &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, "TryFromSexp");
::quote::__private::push_gt(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "__MX_EXPECTATION");
_s
}quote! { <#inner as ::miniextendr_api::TryFromSexp>::__MX_EXPECTATION },
282 }
283}
284
285pub fn derive_is_na(input: DeriveInput) -> syn::Result<TokenStream> {
287 let nt = parse_newtype(&input)?;
288 let inner = &nt.inner;
289 let name = &input.ident;
290 let (impl_generics, ty_generics, _) = input.generics.split_for_impl();
291 let is_na_where = where_with(
292 &input.generics.where_clause,
293 &[
294 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&inner, &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, "IsNA");
_s
}quote! { #inner: ::miniextendr_api::IsNA },
295 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "Self");
::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, "RNativeType");
_s
}quote! { Self: ::miniextendr_api::RNativeType },
296 ],
297 );
298 let value = nt.unwrap(&{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "self");
_s
}quote! { self });
299
300 Ok({
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_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, "IsNA");
::quote::__private::push_ident(&mut _s, "for");
::quote::ToTokens::to_tokens(&name, &mut _s);
::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
::quote::ToTokens::to_tokens(&is_na_where, &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, "inline");
_s
});
::quote::__private::push_ident(&mut _s, "fn");
::quote::__private::push_ident(&mut _s, "is_na");
::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, "bool");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&inner, &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, "IsNA");
::quote::__private::push_gt(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "is_na");
::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(&value, &mut _s);
_s
});
_s
});
_s
});
_s
}quote! {
301 #[automatically_derived]
302 impl #impl_generics ::miniextendr_api::IsNA for #name #ty_generics #is_na_where {
303 #[inline]
304 fn is_na(&self) -> bool {
305 <#inner as ::miniextendr_api::IsNA>::is_na(&#value)
306 }
307 }
308 })
309}
310
311pub fn derive_into_r(input: DeriveInput) -> syn::Result<TokenStream> {
314 let nt = parse_newtype(&input)?;
315 let inner = &nt.inner;
316 let name = &input.ident;
317 let (impl_generics, ty_generics, _) = input.generics.split_for_impl();
318 let base_where = &input.generics.where_clause;
319
320 let unwrap_self = nt.unwrap(&{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "self");
_s
}quote! { self });
321 let unwrap_v = nt.unwrap(&{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "v");
_s
}quote! { v });
322 let into_where = where_with(base_where, &[{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&inner, &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, "IntoR");
_s
}quote! { #inner: ::miniextendr_api::IntoR }]);
323 let vec_elem_where = where_with(
326 base_where,
327 &[{
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(&inner, &mut _s);
::quote::__private::push_gt(&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, "IntoR");
_s
}quote! { ::std::vec::Vec<#inner>: ::miniextendr_api::IntoR }],
328 );
329
330 Ok({
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_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, "IntoR");
::quote::__private::push_ident(&mut _s, "for");
::quote::ToTokens::to_tokens(&name, &mut _s);
::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
::quote::ToTokens::to_tokens(&into_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, "Error");
::quote::__private::push_eq(&mut _s);
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&inner, &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, "IntoR");
::quote::__private::push_gt(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "Error");
::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_lt(&mut _s);
::quote::ToTokens::to_tokens(&inner, &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, "IntoR");
::quote::__private::push_gt(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "Error");
::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_lt(&mut _s);
::quote::ToTokens::to_tokens(&inner, &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, "IntoR");
::quote::__private::push_gt(&mut _s);
::quote::__private::push_colon2(&mut _s);
::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::ToTokens::to_tokens(&unwrap_self, &mut _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, "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_lt(&mut _s);
::quote::ToTokens::to_tokens(&inner, &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, "IntoR");
::quote::__private::push_gt(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "Error");
::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, "unsafe");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&inner, &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, "IntoR");
::quote::__private::push_gt(&mut _s);
::quote::__private::push_colon2(&mut _s);
::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::ToTokens::to_tokens(&unwrap_self, &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, "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_lt(&mut _s);
::quote::ToTokens::to_tokens(&inner, &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, "IntoR");
::quote::__private::push_gt(&mut _s);
::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::ToTokens::to_tokens(&unwrap_self, &mut _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, "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_ident(&mut _s, "unsafe");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&inner, &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, "IntoR");
::quote::__private::push_gt(&mut _s);
::quote::__private::push_colon2(&mut _s);
::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::ToTokens::to_tokens(&unwrap_self, &mut _s);
_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, "automatically_derived");
_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, "IntoRNewtype");
::quote::__private::push_ident(&mut _s, "for");
::quote::ToTokens::to_tokens(&name, &mut _s);
::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
::quote::ToTokens::to_tokens(&base_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, "Inner");
::quote::__private::push_eq(&mut _s);
::quote::ToTokens::to_tokens(&inner, &mut _s);
::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, "into_inner");
::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::ToTokens::to_tokens(&inner, &mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&unwrap_self, &mut _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, "automatically_derived");
_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, "IntoRVecElement");
::quote::__private::push_ident(&mut _s, "for");
::quote::ToTokens::to_tokens(&name, &mut _s);
::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
::quote::ToTokens::to_tokens(&vec_elem_where, &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, "inline");
_s
});
::quote::__private::push_ident(&mut _s, "fn");
::quote::__private::push_ident(&mut _s, "elements_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, "values");
::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::__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_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(&inner, &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, "IntoR");
::quote::__private::push_gt(&mut _s);
::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, "values");
::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, "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::ToTokens::to_tokens(&unwrap_v, &mut _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(&inner, &mut _s);
::quote::__private::push_shr(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
::quote::__private::TokenStream::new());
_s
});
_s
});
_s
});
_s
}quote! {
331 #[automatically_derived]
332 impl #impl_generics ::miniextendr_api::IntoR for #name #ty_generics #into_where {
333 type Error = <#inner as ::miniextendr_api::IntoR>::Error;
334 #[inline]
335 fn try_into_sexp(self) -> ::core::result::Result<::miniextendr_api::SEXP, <#inner as ::miniextendr_api::IntoR>::Error> {
336 <#inner as ::miniextendr_api::IntoR>::try_into_sexp(#unwrap_self)
337 }
338 #[inline]
339 unsafe fn try_into_sexp_unchecked(self) -> ::core::result::Result<::miniextendr_api::SEXP, <#inner as ::miniextendr_api::IntoR>::Error> {
340 unsafe { <#inner as ::miniextendr_api::IntoR>::try_into_sexp_unchecked(#unwrap_self) }
341 }
342 #[inline]
343 fn into_sexp(self) -> ::miniextendr_api::SEXP {
344 <#inner as ::miniextendr_api::IntoR>::into_sexp(#unwrap_self)
345 }
346 #[inline]
347 unsafe fn into_sexp_unchecked(self) -> ::miniextendr_api::SEXP {
348 unsafe { <#inner as ::miniextendr_api::IntoR>::into_sexp_unchecked(#unwrap_self) }
349 }
350 }
351
352 #[automatically_derived]
353 impl #impl_generics ::miniextendr_api::IntoRNewtype for #name #ty_generics #base_where {
354 type Inner = #inner;
355 #[inline]
356 fn into_inner(self) -> #inner {
357 #unwrap_self
358 }
359 }
360
361 #[automatically_derived]
362 impl #impl_generics ::miniextendr_api::IntoRVecElement for #name #ty_generics #vec_elem_where {
363 #[inline]
364 fn elements_into_sexp(values: ::std::vec::Vec<Self>) -> ::miniextendr_api::SEXP {
365 <::std::vec::Vec<#inner> as ::miniextendr_api::IntoR>::into_sexp(
366 values.into_iter().map(|v| #unwrap_v).collect::<::std::vec::Vec<#inner>>()
367 )
368 }
369 }
370 })
371}
372
373#[cfg(test)]
374mod tests {
375 #[test]
381 fn try_from_sexp_derive_validate_emits_the_check() {
382 let validated = super::derive_try_from_sexp(syn::parse_quote! {
383 #[try_from_sexp(validate = checks::plain_number)]
384 struct Duration(f64);
385 })
386 .unwrap()
387 .to_string();
388 assert!(
389 validated.contains(
390 "fn check_sexp (sexp : :: miniextendr_api :: SEXP ,) -> :: core :: result :: Result < () , :: miniextendr_api :: from_r :: SexpError > { checks :: plain_number (sexp) . map_err (:: core :: convert :: Into :: into) }"
391 ),
392 "{validated}"
393 );
394 assert!(
395 validated.contains("type Error = :: miniextendr_api :: from_r :: SexpError ;"),
396 "{validated}"
397 );
398 assert!(
399 validated.contains(
400 "< f64 as :: miniextendr_api :: TryFromSexp > :: Error : :: core :: convert :: Into < :: miniextendr_api :: from_r :: SexpError >"
401 ),
402 "{validated}"
403 );
404 let check = "< Self as :: miniextendr_api :: TryFromSexpElement > :: check_sexp (sexp) ? ;";
406 assert_eq!(validated.matches(check).count(), 2, "{validated}");
407
408 let plain = super::derive_try_from_sexp(syn::parse_quote! { struct Duration(f64); })
409 .unwrap()
410 .to_string();
411 assert!(!plain.contains("check_sexp"), "{plain}");
412 assert!(
413 plain.contains("type Error = < f64 as :: miniextendr_api :: TryFromSexp > :: Error ;"),
414 "{plain}"
415 );
416 }
417
418 #[test]
420 fn try_from_sexp_derive_rejects_bad_options() {
421 let error = |input: syn::DeriveInput| {
422 super::derive_try_from_sexp(input)
423 .expect_err("the options should be refused")
424 .to_string()
425 };
426 assert!(
427 error(syn::parse_quote! {
428 #[try_from_sexp(check = plain_number)]
429 struct Duration(f64);
430 })
431 .contains("unknown `#[try_from_sexp(...)]` key")
432 );
433 assert!(
434 error(syn::parse_quote! {
435 #[try_from_sexp(validate = a, validate = b)]
436 struct Duration(f64);
437 })
438 .contains("duplicate `validate`")
439 );
440 assert!(
441 error(syn::parse_quote! {
442 struct Duration(#[try_from_sexp(validate = a)] f64);
443 })
444 .contains("goes on the struct")
445 );
446 }
447
448 #[test]
452 fn try_from_sexp_derive_forwards_no_na() {
453 for (input, field) in [
454 (syn::parse_quote! { struct Table(DataFrame); }, "self . 0"),
455 (
456 syn::parse_quote! { struct Table { value: DataFrame } },
457 "self . value",
458 ),
459 ] {
460 let out = super::derive_try_from_sexp(input).unwrap().to_string();
461 let forward = |call: &str| {
462 format!("< DataFrame as :: miniextendr_api :: TryFromSexp > :: {call}")
463 };
464 assert!(out.contains("fn __mx_has_na (& self) -> bool"), "{out}");
465 assert!(
466 out.contains(&forward(&format!("__mx_has_na (& {field})"))),
467 "{out}"
468 );
469 assert!(
470 out.contains(
471 "fn __mx_input_has_na (& self , input : :: miniextendr_api :: SEXP) -> bool"
472 ),
473 "{out}"
474 );
475 assert!(
476 out.contains(&forward(&format!("__mx_input_has_na (& {field} , input)"))),
477 "{out}"
478 );
479 }
480 }
481
482 #[test]
486 fn try_from_sexp_derive_declares_the_inner_expectation() {
487 let expectation = |input: syn::DeriveInput| {
488 let out = super::derive_try_from_sexp(input).unwrap().to_string();
489 let start = out
490 .find("const __MX_EXPECTATION")
491 .unwrap_or_else(|| panic!("no expectation constant: {out}"));
492 let end = start + out[start..].find(';').unwrap();
493 out[start..end].trim_end().to_string()
494 };
495 let declares = |text: &str| {
496 format!(
497 "const __MX_EXPECTATION : :: core :: option :: Option < & 'static str > = \
498 :: core :: option :: Option :: Some ({text:?})"
499 )
500 };
501 assert_eq!(
502 expectation(syn::parse_quote! { struct Dose(AsNumeric); }),
503 declares("a single number")
504 );
505 assert_eq!(
506 expectation(syn::parse_quote! { struct Numbers { values: AsNumericVec } }),
507 declares("numeric")
508 );
509 assert_eq!(
510 expectation(syn::parse_quote! { struct Table(DataFrame); }),
511 declares("a data frame")
512 );
513 for (input, inner) in [
514 (syn::parse_quote! { struct Wrapped(Table); }, "Table"),
515 (syn::parse_quote! { struct Id(Uuid); }, "Uuid"),
516 (syn::parse_quote! { struct Any<T>(T); }, "T"),
517 ] {
518 assert_eq!(
519 expectation(input),
520 format!(
521 "const __MX_EXPECTATION : :: core :: option :: Option < & 'static str > = \
522 < {inner} as :: miniextendr_api :: TryFromSexp > :: __MX_EXPECTATION"
523 )
524 );
525 }
526 }
527}