use prebindgen_registry::Conversions;
use super::{trait_impl::WrapperShape, *};
fn decoded_vec_satisfies(referent: &prebindgen_registry::flat::TypeRef) -> bool {
matches!(
referent.kind(),
prebindgen_registry::flat::TypeKind::Slice(_) | prebindgen_registry::flat::TypeKind::Vec(_)
)
}
fn is_unsized_spelling(ty: &prebindgen_registry::flat::TypeRef) -> bool {
matches!(ty.kind(), prebindgen_registry::flat::TypeKind::Slice(_))
}
impl Declarations {
pub(crate) fn select_input_type(
&self,
ty: &prebindgen_registry::flat::TypeRef,
registry: &impl Conversions<KotlinMeta>,
emit: &prebindgen_registry::Emit,
) -> Option<ConverterImpl<KotlinMeta>> {
let produced = crate::jni::trait_impl::Produced::Reading(ty);
if let Some(c) = self.input_terminal(ty, registry, emit) {
return Some(c);
}
if let Some(inner) = ty.optional_inner() {
if let Some(target) = inner.borrow_target() {
let mutable = inner.is_exclusive_borrow();
if let Some(mut c) = self.input_wrapper_shape(
WrapperShape::OptionRef { mutable },
&produced,
target,
registry,
emit,
) {
c.subs = vec![target.key()];
return Some(c);
}
}
if inner.borrow_target().is_some() && !ty.erased_wrappers().is_empty() {
return None;
}
if let Some(mut c) =
self.input_wrapper_shape(WrapperShape::Optional, &produced, inner, registry, emit)
{
c.subs = vec![inner.key()];
return Some(c);
}
return None;
}
if let Some(elem) = ty.sequence_elem().filter(|_| !is_unsized_spelling(ty)) {
if let Some(mut c) =
self.input_wrapper_shape(WrapperShape::Sequence, &produced, elem, registry, emit)
{
c.subs = vec![elem.key()];
return Some(c);
}
return None;
}
if let prebindgen_registry::flat::TypeKind::Ref { mutable, .. } = ty.unwrapped().kind() {
let inner = ty.borrow_target().expect("a borrow");
if !*mutable && decoded_vec_satisfies(inner) {
if let Some(elem) = inner.sequence_elem() {
let elem_ty = emit.spell(elem);
let produced = crate::jni::trait_impl::Produced::Composed(
syn::parse_quote!(Vec<#elem_ty>),
);
if let Some(mut c) = self.input_wrapper_shape(
WrapperShape::Sequence,
&produced,
elem,
registry,
emit,
) {
c.subs = vec![elem.key()];
return Some(c);
}
return None;
}
}
let mutable = ty.is_exclusive_borrow();
if let Some(mut c) = self.input_wrapper_shape(
WrapperShape::Borrow { mutable },
&produced,
inner,
registry,
emit,
) {
c.subs = vec![inner.key()];
return Some(c);
}
}
self.input_transparent_bridge(ty, registry, emit)
}
pub(crate) fn select_output_type(
&self,
ty: &prebindgen_registry::flat::TypeRef,
registry: &impl Conversions<KotlinMeta>,
emit: &prebindgen_registry::Emit,
) -> Option<ConverterImpl<KotlinMeta>> {
let produced = crate::jni::trait_impl::Produced::Reading(ty);
if let Some(c) = self.output_terminal(ty, registry, emit) {
return Some(c);
}
if let Some((ok, err)) = fallible_parts(ty, emit) {
if let Some(c) = self.result_peel(ty, &ok, &err, registry, emit) {
return Some(c);
}
}
if let Some(inner) = ty.optional_inner() {
if let Some(mut c) =
self.output_wrapper_shape(WrapperShape::Optional, &produced, inner, registry, emit)
{
c.subs = vec![inner.key()];
return Some(c);
}
return None;
}
if let Some(elem) = ty.sequence_elem().filter(|_| !is_unsized_spelling(ty)) {
if let Some(mut c) =
self.output_wrapper_shape(WrapperShape::Sequence, &produced, elem, registry, emit)
{
c.subs = vec![elem.key()];
return Some(c);
}
return None;
}
if let prebindgen_registry::flat::TypeKind::Ref { mutable, .. } = ty.unwrapped().kind() {
let inner = ty.borrow_target().expect("a borrow");
if !*mutable && decoded_vec_satisfies(inner) {
if let Some(elem) = inner.sequence_elem() {
return self.output_slice(elem, registry, emit);
}
}
let mutable = ty.is_exclusive_borrow();
if let Some(mut c) = self.output_wrapper_shape(
WrapperShape::Borrow { mutable },
&produced,
inner,
registry,
emit,
) {
c.subs = vec![inner.key()];
return Some(c);
}
}
self.output_transparent_bridge(ty, registry, emit)
}
}
fn fallible_parts(
ty: &prebindgen_registry::flat::TypeRef,
emit: &prebindgen_registry::Emit,
) -> Option<(syn::Type, syn::Type)> {
let (ok, err) = ty.fallible_parts()?;
let (ok, err) = (emit.spell(ok), emit.spell(err));
Some((syn::parse_quote!(#ok), syn::parse_quote!(#err)))
}