miniextendr_macros/
type_inspect.rs1pub(crate) fn nth_type_argument(seg: &syn::PathSegment, n: usize) -> Option<&syn::Type> {
5 if let syn::PathArguments::AngleBracketed(ab) = &seg.arguments {
6 let mut count = 0;
7 for arg in ab.args.iter() {
8 if let syn::GenericArgument::Type(ty) = arg {
9 if count == n {
10 return Some(ty);
11 }
12 count += 1;
13 }
14 }
15 }
16 None
17}
18
19pub(crate) fn first_type_argument(seg: &syn::PathSegment) -> Option<&syn::Type> {
21 nth_type_argument(seg, 0)
22}
23
24pub(crate) fn second_type_argument(seg: &syn::PathSegment) -> Option<&syn::Type> {
26 nth_type_argument(seg, 1)
27}
28
29#[inline]
31pub(crate) fn is_sexp_type(ty: &syn::Type) -> bool {
32 matches!(ty, syn::Type::Path(p) if p
33 .path
34 .segments
35 .last()
36 .map(|s| s.ident == "SEXP")
37 .unwrap_or(false))
38}
39
40#[inline]
51pub(crate) fn is_main_thread_bound_input(ty: &syn::Type) -> bool {
52 const MAIN_THREAD_BOUND: &[&str] = &[
53 "SEXP",
54 "AltrepSexp",
55 "RDVector",
56 "RDMatrix",
57 "RndVec",
58 "RndMat",
59 "ProtectedStrVec",
60 ];
61 matches!(ty, syn::Type::Path(p) if p
62 .path
63 .segments
64 .last()
65 .map(|s| MAIN_THREAD_BOUND.contains(&s.ident.to_string().as_str()))
66 .unwrap_or(false))
67}
68
69#[derive(Debug, Clone)]
72pub(crate) enum SeveralOkContainer {
73 Vec,
75 BoxedSlice,
77 Array(usize),
79 BorrowedSlice,
81}
82
83pub(crate) fn classify_several_ok_container(
89 ty: &syn::Type,
90) -> Option<(SeveralOkContainer, &syn::Type)> {
91 match ty {
92 syn::Type::Path(tp) => {
94 let seg = tp.path.segments.last()?;
95 if seg.ident == "Vec" {
96 let inner = first_type_argument(seg)?;
97 return Some((SeveralOkContainer::Vec, inner));
98 }
99 if seg.ident == "Box"
101 && let syn::PathArguments::AngleBracketed(ab) = &seg.arguments
102 {
103 for arg in &ab.args {
104 if let syn::GenericArgument::Type(syn::Type::Slice(s)) = arg {
105 return Some((SeveralOkContainer::BoxedSlice, s.elem.as_ref()));
106 }
107 }
108 }
109 None
110 }
111 syn::Type::Array(arr) => {
113 if let syn::Expr::Lit(syn::ExprLit {
114 lit: syn::Lit::Int(n),
115 ..
116 }) = &arr.len
117 {
118 let n = n.base10_parse::<usize>().ok()?;
119 return Some((SeveralOkContainer::Array(n), arr.elem.as_ref()));
120 }
121 None
122 }
123 syn::Type::Reference(r) => {
125 if let syn::Type::Slice(s) = r.elem.as_ref() {
126 return Some((SeveralOkContainer::BorrowedSlice, s.elem.as_ref()));
127 }
128 None
129 }
130 _ => None,
131 }
132}