+ /// Constructs a reference to the given type, possibly tweaking the type if relevant to make it
+ /// convertable to C.
+ pub fn create_ownable_reference(&self, t: &syn::Type, generics: Option<&GenericTypes>) -> Option<syn::Type> {
+ let default_value = Some(syn::Type::Reference(syn::TypeReference {
+ and_token: syn::Token!(&)(Span::call_site()), lifetime: None, mutability: None,
+ elem: Box::new(t.clone()) }));
+ match generics.resolve_type(t) {
+ syn::Type::Path(p) => {
+ if let Some(resolved_path) = self.maybe_resolve_path(&p.path, generics) {
+ if resolved_path != "Vec" { return default_value; }
+ if p.path.segments.len() != 1 { unimplemented!(); }
+ let only_seg = p.path.segments.iter().next().unwrap();
+ if let syn::PathArguments::AngleBracketed(args) = &only_seg.arguments {
+ if args.args.len() != 1 { unimplemented!(); }
+ let inner_arg = args.args.iter().next().unwrap();
+ if let syn::GenericArgument::Type(ty) = &inner_arg {
+ let mut can_create = self.c_type_has_inner(&ty);
+ if let syn::Type::Path(inner) = ty {
+ if inner.path.segments.len() == 1 &&
+ format!("{}", inner.path.segments[0].ident) == "Vec" {
+ can_create = true;
+ }
+ }
+ if !can_create { return default_value; }
+ if let Some(inner_ty) = self.create_ownable_reference(&ty, generics) {
+ return Some(syn::Type::Reference(syn::TypeReference {
+ and_token: syn::Token![&](Span::call_site()),
+ lifetime: None,
+ mutability: None,
+ elem: Box::new(syn::Type::Slice(syn::TypeSlice {
+ bracket_token: syn::token::Bracket { span: Span::call_site() },
+ elem: Box::new(inner_ty)
+ }))
+ }));
+ } else { return default_value; }
+ } else { unimplemented!(); }
+ } else { unimplemented!(); }
+ } else { return None; }
+ },
+ _ => default_value,
+ }
+ }
+