Skip to content

Commit 86ac53f

Browse files
committed
query structure
1 parent 2b58526 commit 86ac53f

14 files changed

Lines changed: 165 additions & 37 deletions

File tree

prebindgen-ext/src/jni/jni_ext.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4151,6 +4151,27 @@ fn struct_input_body(
41514151
let java_path = handle_field_fqn(ext, h).replace('.', "/");
41524152
let sig = format!("L{};", java_path);
41534153
let tmp_ident = format_ident!("__{}_jobj", fname_ident);
4154+
// Struct fields are owned, so a non-`Option` handle field owns
4155+
// its native object: decode by consuming (`Box::from_raw` → owned
4156+
// `T`), mirroring `struct_output_body`'s `Box::into_raw`. The
4157+
// borrow converter would yield `OwnedObject<T>`, which can't
4158+
// populate an owned field. `Option<_>` handle fields keep the
4159+
// niche-aware converter (jlong 0 ⇒ `None`).
4160+
let field_ty = &field.ty;
4161+
let field_is_option = matches!(
4162+
field_ty,
4163+
syn::Type::Path(p) if p.path.segments.last()
4164+
.map(|s| s.ident == "Option").unwrap_or(false)
4165+
);
4166+
let decode = if field_is_option {
4167+
quote! { let #fname_ident = #field_conv(env, &#raw_ident)?; }
4168+
} else {
4169+
quote! {
4170+
let #fname_ident: #field_ty = unsafe {
4171+
*std::boxed::Box::from_raw(#raw_ident as *mut #field_ty)
4172+
};
4173+
}
4174+
};
41544175
field_preludes.push(quote! {
41554176
let #tmp_ident: jni::objects::JObject = env.get_field(v, #camel, #sig)
41564177
.and_then(|val| val.l())
@@ -4162,7 +4183,7 @@ fn struct_input_body(
41624183
.and_then(|val| val.j())
41634184
.map_err(|e| <__JniErr as ::core::convert::From<String>>::from(format!(#err_prefix, e)))?
41644185
};
4165-
let #fname_ident = #field_conv(env, &#raw_ident)?;
4186+
#decode
41664187
});
41674188
field_init.push(quote!(#fname_ident));
41684189
continue;

zenoh-flat-jni/build.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,13 @@ fn main() {
200200
.package("query")
201201
.ptr_class(pq!(ZQueryable))
202202
.ptr_class(pq!(ZQuerier))
203+
.enum_class(pq!(ReplyKeyExpr))
203204
.ptr_class(pq!(ZQuery))
204205
.class_fun(pq!(z_query_reply_success))
205206
.class_fun(pq!(z_query_reply_error))
206207
.class_fun(pq!(z_query_reply_delete))
208+
.class_fun(pq!(query_take))
209+
.data_class(pq!(Query))
207210
.into_sources(
208211
pq!(ZBytes),
209212
[

zenoh-flat-jni/generated-kotlin/io/zenoh/jni/JNINative.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import io.zenoh.jni.config.ZZenohId
1313
import io.zenoh.jni.keyexpr.KeyExpr
1414
import io.zenoh.jni.keyexpr.SetIntersectionLevel
1515
import io.zenoh.jni.keyexpr.ZKeyExpr
16+
import io.zenoh.jni.query.Query
1617
import io.zenoh.jni.scouting.ZScout
1718

1819
internal object JNINative {
@@ -80,6 +81,7 @@ internal object JNINative {
8081
external fun keyexprJoin(a: Any, b: String): KeyExpr
8182
external fun keyexprRelationTo(a: Any, b: Any): Int
8283
external fun keyexprTryFrom(s: String): KeyExpr
84+
external fun queryTake(query: Long): Query
8385
external fun scout(whatami: Int, config: Long, callback: HelloCallback, onClose: Callback): Long
8486
external fun tryInitZenohLogsFromEnv()
8587
external fun zConfigDefault(): Long
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Auto-generated by JniExt — do not edit by hand.
2+
package io.zenoh.jni.query
3+
4+
import io.zenoh.jni.bytes.Encoding
5+
import io.zenoh.jni.bytes.ZBytes
6+
import io.zenoh.jni.keyexpr.KeyExpr
7+
8+
public data class Query(
9+
val keyExpr: KeyExpr,
10+
val parameters: String,
11+
val payload: ZBytes?,
12+
val encoding: Encoding?,
13+
val attachment: ZBytes?,
14+
val acceptsReplies: ReplyKeyExpr,
15+
val query: ZQuery,
16+
) : AutoCloseable {
17+
override fun close() {
18+
query.close()
19+
}
20+
21+
public companion object {
22+
}
23+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Auto-generated by JniExt — do not edit by hand.
2+
package io.zenoh.jni.query
3+
4+
/** JVM-side surface for the native Rust `ReplyKeyExpr` enum. */
5+
public enum class ReplyKeyExpr(public val value: Int) {
6+
ANY(0),
7+
MATCHING_QUERY(1);
8+
9+
public companion object {
10+
@JvmStatic
11+
public fun fromInt(value: Int): ReplyKeyExpr = entries.first { it.value == value }
12+
}
13+
}

zenoh-flat-jni/generated-kotlin/io/zenoh/jni/query/ZQuery.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,19 @@ public class ZQuery(initialPtr: Long) : AutoCloseable {
154154
}
155155
}
156156

157+
@Throws(JniBindingError::class)
158+
public fun queryTake(): Query {
159+
synchronized(this) {
160+
val query_ptr = this.ptr
161+
if (query_ptr == 0L) throw JniBindingError("Operation on a closed native handle.")
162+
return try {
163+
JNINative.queryTake(query_ptr)
164+
} finally {
165+
ptr = 0L
166+
}
167+
}
168+
}
169+
157170
public companion object {
158171
@JvmStatic
159172
external fun freePtr(ptr: Long)

zenoh-flat-jni/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use zenoh_flat::SetIntersectionLevel;
66
use zenoh_flat::CongestionControl;
77
use zenoh_flat::Priority;
88
use zenoh_flat::Reliability;
9+
use zenoh_flat::ReplyKeyExpr;
910

1011
// Generated by build.rs into OUT_DIR.
1112
include!(concat!(env!("OUT_DIR"), "/zenoh_flat_jni.rs"));

zenoh-flat/src/keyexpr/keyexpr.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ impl From<zenoh::key_expr::SetIntersectionLevel> for SetIntersectionLevel {
2929
}
3030

3131
#[prebindgen]
32+
#[derive(Clone)]
3233
pub struct KeyExpr {
3334
pub key_expr_string: String,
3435
pub key_expr_native: Option<ZKeyExpr>,

zenoh-flat/src/query/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
pub(crate) mod query;
2+
pub(crate) mod reply_key_expr;
13
pub(crate) mod z_query;
24

5+
pub use query::*;
6+
pub use reply_key_expr::*;
37
pub use z_query::*;

zenoh-flat/src/query/query.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
use crate::{Encoding, KeyExpr, ReplyKeyExpr, ZBytes, ZQuery};
2+
use prebindgen_proc_macro::prebindgen;
3+
4+
/// Data-class twin of [`ZQuery`]. Carries decoded query fields plus the
5+
/// live [`ZQuery`] handle, which the binding uses to reply.
6+
#[prebindgen]
7+
pub struct Query {
8+
pub key_expr: KeyExpr,
9+
pub parameters: String,
10+
pub payload: Option<ZBytes>,
11+
pub encoding: Option<Encoding>,
12+
pub attachment: Option<ZBytes>,
13+
pub accepts_replies: ReplyKeyExpr,
14+
pub query: ZQuery,
15+
}
16+
17+
impl From<ZQuery> for Query {
18+
fn from(q: ZQuery) -> Self {
19+
Query {
20+
key_expr: KeyExpr::from(q.key_expr().clone()),
21+
parameters: q.parameters().to_string(),
22+
payload: q.payload().map(|p| ZBytes::from(p.clone())),
23+
encoding: q.encoding().map(Encoding::from),
24+
attachment: q.attachment().map(|a| ZBytes::from(a.clone())),
25+
accepts_replies: q.accepts_replies().into(),
26+
query: q,
27+
}
28+
}
29+
}
30+
31+
/// Consume an opaque [`ZQuery`] handle and repack it into the decoded
32+
/// [`Query`] data class (re-embedding the same native query for replies).
33+
#[prebindgen]
34+
pub fn query_take(query: ZQuery) -> Query {
35+
Query::from(query)
36+
}

0 commit comments

Comments
 (0)