Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for recursive types in struct #451

Open
CinchBlue opened this issue Aug 22, 2023 · 4 comments
Open

Add support for recursive types in struct #451

CinchBlue opened this issue Aug 22, 2023 · 4 comments
Labels
enhancement Java/JNI Case specific only for Java/JNI interface generation

Comments

@CinchBlue
Copy link

CinchBlue commented Aug 22, 2023

If you have a lib.rs and a java_glue.rs.in, this will not work:

// lib.rs
mod java_glue;

pub enum RecursiveEnum {
    Null,
    S
}

#[derive(Debug, Clone, Default)]
pub struct Lol {
    pub s: String,
}


#[derive(Debug, Clone, Default)]
pub struct RecursiveFoo {
    pub s: String,
    pub child: Vec<RecursiveFoo>,
}

impl RecursiveFoo {
    pub fn new(s: String, child: Vec<RecursiveFoo>) -> Self {
        Self { s, child }
    }
}
// java_glue.rs.in
use crate::*;
use jni_sys::*;
foreign_class!(class Lol {
    self_type Lol;
    constructor  Lol::default() -> Lol;
});

foreign_class!(class RecursiveFoo {
    self_type RecursiveFoo;
    constructor  RecursiveFoo::new(s: String, child: Vec<RecursiveFoo>) -> RecursiveFoo;
});

You will get an error like:

error: failed to run custom build command for `lol2_lib_android2 v0.1.0 (/Users/austin/work/android.debug/my_repo/lol/lib_android2)`

Caused by:
  process didn't exit successfully: `/Users/austin/work/android.debug/lol/target/release/build/lol_lib_android2-e0e77b6c90dc0964/build-script-build` (exit status: 101)
  --- stderr
  error in android bindings: src/java_glue.rs.in
  parsing of android bindings: src/java_glue.rs.in failed
  error: Do not know conversion from Java type to such rust type 'Vec < RecursiveFoo >'
      constructor  RecursiveFoo::new(s: String, child: Vec<RecursiveFoo>) -> RecursiveFoo;
                                                       ^^^^^^^^^^^^^^^^^

  At android bindings: src/java_glue.rs.in:10:53
  thread 'main' panicked at 'explicit panic', /Users/austin/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flapigen-0.6.0/src/error.rs:88:5
  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: Recipe `build-android-lib2` failed with exit code 101

but this type is acceptable to Rust if you compile without the build script.

@CinchBlue
Copy link
Author

CinchBlue commented Aug 22, 2023

it also does not work if you use Option<Box<RecursiveFoo>> instead:

// lib.rs
mod java_glue;

pub enum RecursiveEnum {
    Null,
    S
}

#[derive(Debug, Clone, Default)]
pub struct Lol {
    pub s: String,
}


#[derive(Debug, Clone, Default)]
pub struct RecursiveFoo {
    pub s: String,
    pub child: Option<Box<RecursiveFoo>>,
}

impl RecursiveFoo {
    pub fn new(s: String, child: Option<Box<RecursiveFoo>>) -> Self {
        Self { s, child }
    }
}
// java_glue.rs.in
use crate::*;
use jni_sys::*;
foreign_class!(class Lol {
    self_type Lol;
    constructor  Lol::default() -> Lol;
});

foreign_class!(class RecursiveFoo {
    self_type RecursiveFoo;
    constructor  RecursiveFoo::new(s: String, child: Option<Box<RecursiveFoo>>,) -> RecursiveFoo;
});
error: failed to run custom build command for `lol_lib_android2 v0.1.0 (/Users/austin/work/android.debug/my_repo/lol/lib_android2)`

Caused by:
  process didn't exit successfully: `/Users/austin/work/android.debug/my_repo/target/release/build/lol_lib_android2-e0e77b6c90dc0964/build-script-build` (exit status: 101)
  --- stdout
  cargo:warning=mapping types: type Box < RecursiveFoo > unknown
  cargo:warning=mapping types: type Box < RecursiveFoo > unknown

  --- stderr
  error in android bindings: src/java_glue.rs.in
  parsing of android bindings: src/java_glue.rs.in failed
  error: Do not know conversion from Java type to such rust type 'Option < Box < RecursiveFoo > >'
      constructor  RecursiveFoo::new(s: String, child: Option<Box<RecursiveFoo>>,) -> RecursiveFoo;
                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^

  At android bindings: src/java_glue.rs.in:10:53
  thread 'main' panicked at 'explicit panic', /Users/austin/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flapigen-0.6.0/src/error.rs:88:5
  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: Recipe `build-android-lib2` failed with exit code 101

@CinchBlue
Copy link
Author

I see that there is some sort of generic type map within the library -- but I don't have insight into what is happening. How are these type conversions being caught, and why do other Vec<T> work?

@Dushistov Dushistov added the Java/JNI Case specific only for Java/JNI interface generation label Aug 23, 2023
@Dushistov
Copy link
Owner

How are these type conversions being caught, and why do other Vec work?

Other works, because of usage of generic mapping T <-> Java is possible only after parsing of foreign_class!,
so inside foreign_class! it is possible only use &self type and equivalent &T type.

@CinchBlue
Copy link
Author

This isn't theoretically impossible right? Is there some way I can help implement this? What is needed?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Java/JNI Case specific only for Java/JNI interface generation
Projects
None yet
Development

No branches or pull requests

2 participants