diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 39e3832b..57b6d95f 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -9,9 +9,6 @@ on:
- cron: "0 6 * * 1-5"
workflow_dispatch:
-env:
- CARGO_TERM_COLOR: always
-
jobs:
build:
name: Build on ${{ matrix.os }}
@@ -23,43 +20,21 @@ jobs:
steps:
- uses: actions/checkout@v4
+ with:
+ submodules: recursive
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 11
- - name: Install Rust toolchain
- run: |
- rustup show
- rustup component add rustfmt clippy
-
- - name: Cargo Format
- working-directory: zenoh-jni
- run: cargo fmt --all --check
-
- - name: Clippy Check without Cargo.lock
- working-directory: zenoh-jni
- run: |
- rm Cargo.lock
- cargo clippy --all-targets --all-features -- -D warnings
- git restore Cargo.lock
-
- - name: Check for feature leaks
- working-directory: zenoh-jni
- run: cargo test --no-default-features
-
- - name: Build Zenoh-JNI
- working-directory: zenoh-jni
- run: cargo build
-
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
with:
gradle-version: 8.12.1
- name: Gradle Test
- run: gradle jvmTest --info
+ run: gradle jvmTest --info -Pzenoh.useLocalJniRuntime=true
markdown_lint:
runs-on: ubuntu-latest
diff --git a/.github/workflows/publish-android.yml b/.github/workflows/publish-android.yml
index f3317b25..b0a646f3 100644
--- a/.github/workflows/publish-android.yml
+++ b/.github/workflows/publish-android.yml
@@ -17,9 +17,6 @@ on:
required: false
default: true
-env:
- CARGO_TERM_COLOR: always
-
jobs:
publish_android_package:
name: Publish Android package
@@ -37,25 +34,6 @@ jobs:
distribution: temurin
java-version: 11
- - uses: nttld/setup-ndk@v1
- id: setup-ndk
- with:
- ndk-version: r26
- add-to-path: false
- link-to-sdk: true
-
- - name: Install Rust toolchain
- run: |
- rustup show
- rustup component add rustfmt clippy
-
- - name: Setup Rust toolchains
- run: |
- rustup target add armv7-linux-androideabi
- rustup target add i686-linux-android
- rustup target add aarch64-linux-android
- rustup target add x86_64-linux-android
-
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
with:
diff --git a/.github/workflows/publish-jvm.yml b/.github/workflows/publish-jvm.yml
index b77ab842..9b961d8c 100644
--- a/.github/workflows/publish-jvm.yml
+++ b/.github/workflows/publish-jvm.yml
@@ -17,127 +17,9 @@ on:
required: false
default: true
-env:
- CARGO_TERM_COLOR: always
- JNI_LIB_PATHS: jni-libs # Edit on the inner build.gradle.kts file as well.
-
jobs:
- builds:
- name: Build for ${{ matrix.job.target }} on ${{ matrix.job.os }}
- if: ${{ !(github.event.inputs.build == 'false') }}
- runs-on: ${{ matrix.job.os }}
- strategy:
- fail-fast: false
- matrix:
- job:
- # In order to load any added target at runtime, editing the Zenoh class under jvmMain is required.
- - {
- target: x86_64-unknown-linux-gnu,
- arch: amd64,
- os: ubuntu-latest,
- build-cmd: "cargo",
- }
- - {
- target: aarch64-unknown-linux-gnu,
- arch: arm64,
- os: ubuntu-latest,
- build-cmd: "cross",
- }
- - {
- target: x86_64-apple-darwin,
- arch: darwin,
- os: macos-latest,
- build-cmd: "cargo",
- }
- - {
- target: aarch64-apple-darwin,
- arch: darwin,
- os: macos-latest,
- build-cmd: "cargo",
- }
- - {
- target: x86_64-pc-windows-msvc,
- arch: win64,
- os: windows-latest,
- build-cmd: "cargo",
- }
- - {
- target: aarch64-pc-windows-msvc,
- arch: arm64,
- os: windows-latest,
- build-cmd: "cargo",
- }
- steps:
- - name: Checkout source code
- uses: actions/checkout@v4
- with:
- ref: ${{ inputs.branch }}
-
- - name: Install prerequisites
- shell: bash
- run: |
- case ${{ matrix.job.target }} in
- *-linux-gnu*) cargo +stable install cargo-deb --locked ;;
- esac
-
- case ${{ matrix.job.target }} in
- aarch64-unknown-linux-gnu)
- sudo apt-get -y update
- sudo apt-get -y install gcc-aarch64-linux-gnu
- ;;
- esac
-
- cargo +stable install cross --locked
-
- - name: Install Rust toolchain
- run: |
- rustup show
- rustup target add ${{ matrix.job.target }}
-
- - name: Build
- run: ${{ matrix.job.build-cmd }} build --release --bins --lib --features=${{ github.event.inputs.features}} --target=${{ matrix.job.target }} --manifest-path zenoh-jni/Cargo.toml
-
- - name: Packaging
- id: package
- shell: bash
- run: |
- TARGET=${{ matrix.job.target }}
- MAIN_PKG_NAME="${GITHUB_WORKSPACE}/${TARGET}.zip"
-
- case ${TARGET} in
- *linux*)
- cd "zenoh-jni/target/${TARGET}/release/"
- echo "Packaging ${MAIN_PKG_NAME}:"
- zip ${MAIN_PKG_NAME} libzenoh_jni.so
- cd -
- echo "MAIN_PKG_NAME=${MAIN_PKG_NAME}" >> $GITHUB_OUTPUT
- ;;
- *apple*)
- cd "zenoh-jni/target/${TARGET}/release/"
- echo "Packaging ${MAIN_PKG_NAME}:"
- zip ${MAIN_PKG_NAME} libzenoh_jni.dylib
- cd -
- echo "MAIN_PKG_NAME=${MAIN_PKG_NAME}" >> $GITHUB_OUTPUT
- ;;
- *windows*)
- cd "zenoh-jni/target/${TARGET}/release/"
- echo "Packaging ${MAIN_PKG_NAME}:"
- 7z -y a "${MAIN_PKG_NAME}" zenoh_jni.dll
- cd -
- echo "MAIN_PKG_NAME=${MAIN_PKG_NAME}" >> $GITHUB_OUTPUT
- ;;
- esac
-
- - name: "Upload packages"
- uses: actions/upload-artifact@v4
- with:
- name: ${{ matrix.job.target }}
- path: |
- ${{ steps.package.outputs.MAIN_PKG_NAME }}
-
publish_jvm_package:
name: Publish JVM package
- needs: builds
permissions:
contents: read
packages: write
@@ -148,14 +30,6 @@ jobs:
with:
ref: ${{ inputs.branch }}
- - name: Create resources destination
- run: mkdir ${{env.JNI_LIB_PATHS}}
-
- - name: Download result of previous builds
- uses: actions/download-artifact@v4
- with:
- path: ${{env.JNI_LIB_PATHS}}
-
- uses: actions/setup-java@v4
with:
distribution: temurin
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index e874c778..fa5b5906 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -106,15 +106,3 @@ jobs:
with:
live-run: ${{ inputs.live-run || false }}
branch: ${{ needs.tag.outputs.branch }}
-
- publish-github:
- needs: [tag, publish-android, publish-jvm]
- runs-on: macos-latest
- steps:
- - uses: eclipse-zenoh/ci/publish-crates-github@main
- with:
- repo: ${{ github.repository }}
- live-run: ${{ inputs.live-run || false }}
- version: ${{ needs.tag.outputs.version }}
- branch: ${{ needs.tag.outputs.branch }}
- github-token: ${{ secrets.BOT_TOKEN_WORKFLOW }}
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 00000000..bc8a07b6
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,4 @@
+[submodule "zenoh-java"]
+ path = zenoh-java
+ url = https://github.com/eclipse-zenoh/zenoh-java.git
+ branch = common-jni
diff --git a/README.md b/README.md
index 6b5ee063..468254fa 100644
--- a/README.md
+++ b/README.md
@@ -118,7 +118,6 @@ For the moment, the library targets the following platforms:
Basically:
-- Rust ([Installation guide](https://doc.rust-lang.org/cargo/getting-started/installation.html))
- Kotlin ([Installation guide](https://kotlinlang.org/docs/getting-started.html#backend))
- Gradle ([Installation guide](https://gradle.org/install/))
@@ -126,6 +125,8 @@ and in case of targetting Android you'll also need:
- Android SDK ([Installation guide](https://developer.android.com/about/versions/11/setup-sdk))
+> **Note:** zenoh-kotlin no longer builds its own native JNI library. The native runtime is provided by [zenoh-jni-runtime](https://github.com/eclipse-zenoh/zenoh-java), which is a published Maven artifact that zenoh-kotlin depends on automatically. No Rust toolchain is required to build or publish zenoh-kotlin using the default (Maven) path. A Rust toolchain is only needed when using the [local submodule path](#running-the-tests) with `-Pzenoh.useLocalJniRuntime=true`.
+
##
JVM
To publish a library for a JVM project into Maven local, run
@@ -134,11 +135,7 @@ To publish a library for a JVM project into Maven local, run
gradle publishJvmPublicationToMavenLocal
```
-This will first, trigger the compilation of Zenoh-JNI, and second publish the library into maven local, containing the native library
-as a resource that will be loaded during runtime.
-
-:warning: The native library will be compiled against the default rustup target on your machine, so although it may work fine
-for you on your desktop, the generated publication may not be working on another computer with a different operating system and/or a different cpu architecture.
+This publishes the zenoh-kotlin library to Maven local. The published artifact declares a dependency on `zenoh-jni-runtime`, which provides the native JNI binaries and is published separately by the [zenoh-java](https://github.com/eclipse-zenoh/zenoh-java) project.
Once we have published the package, we should be able to find it under `~/.m2/repository/org/eclipse/zenoh/zenoh-kotlin-jvm/1.1.1`.
@@ -157,40 +154,13 @@ dependencies {
##
Android
-In order to use these bindings in a native Android project, what we will do is to build them as an Android NDK Library,
-publishing it into Maven local for us to be able to easily import it in our project.
-
-It is required to have the [NDK (native development kit)](https://developer.android.com/ndk) installed, since we are going to compile Zenoh JNI for multiple
-android native targets. The currently used NDK version is **26.0.10792818**.
-It can be set up by using Android Studio (go to `Preferences > Languages & Frameworks > Android SDK > SDK Tools`, tick `Show Package Details` and pick the right NDK version),
-or alternatively it can be found [here](https://developer.android.com/ndk/downloads).
-
-The native platforms we are going to target are the following ones:
-
-- x86
-- x86_64
-- arm
-- arm64
-
-Therefore, if they are not yet already added to the Rust toolchain, run:
-
-```bash
-rustup target add armv7-linux-androideabi; \
-rustup target add i686-linux-android; \
-rustup target add aarch64-linux-android; \
-rustup target add x86_64-linux-android
-```
-
-to install them.
-
-So, in order to publish the library onto Maven Local, run:
+In order to use these bindings in a native Android project, publish them into Maven local:
```bash
gradle -Pandroid=true publishAndroidReleasePublicationToMavenLocal
```
-This will first trigger the compilation of the Zenoh-JNI for the previously mentioned targets, and secondly will
-publish the library, containing the native binaries.
+This publishes the zenoh-kotlin-android artifact to Maven local. The published artifact declares a dependency on `zenoh-jni-runtime`, which provides the prebuilt native JNI binaries for Android ABIs (x86, x86_64, arm, arm64). The native binaries are published separately by the [zenoh-java](https://github.com/eclipse-zenoh/zenoh-java) project — no Rust toolchain or NDK cross-compilation is required.
You should now be able to see the package under `~/.m2/repository/org/eclipse/zenoh/zenoh-kotlin-android/1.1.1`.
@@ -226,13 +196,25 @@ gradle dokkaGenerate
## Running the tests
-To run the tests, run:
+zenoh-kotlin supports two modes for providing the native JNI runtime during tests:
+
+### Default mode (published Maven artifact)
+
+By default, tests resolve `zenoh-jni-runtime` from Maven Central. No local submodule or Rust toolchain is needed:
```bash
gradle jvmTest
```
-This will compile the native library on debug mode (if not already available) and run the tests afterward against the JVM target.
+### Local submodule mode (opt-in)
+
+For local integration testing against the `zenoh-java` submodule (included under `zenoh-java/`), pass the `zenoh.useLocalJniRuntime` property. This substitutes the Maven dependency with a local composite build of the submodule:
+
+```bash
+gradle jvmTest -Pzenoh.useLocalJniRuntime=true
+```
+
+> **Note:** The local submodule path builds `zenoh-jni-runtime` from source and requires a Rust toolchain (see [rustup.rs](https://rustup.rs)) as well as the Cargo toolchain configured for the target platform. The submodule's Gradle build handles the Rust compilation step automatically once the toolchain is installed.
## Logging
diff --git a/build.gradle.kts b/build.gradle.kts
index 6ea68a7d..6888c637 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -18,8 +18,7 @@ buildscript {
}
dependencies {
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.0")
- classpath("org.mozilla.rust-android-gradle:plugin:0.9.6")
- classpath("com.android.tools.build:gradle:7.4.2")
+classpath("com.android.tools.build:gradle:7.4.2")
classpath("com.gradleup.shadow:shadow-gradle-plugin:9.0.0-beta6")
}
}
@@ -28,8 +27,7 @@ plugins {
id("com.android.library") version "7.4.2" apply false
id("org.jetbrains.kotlin.android") version "1.9.10" apply false
id("org.jetbrains.kotlin.multiplatform") version "1.9.0" apply false
- id("org.mozilla.rust-android-gradle.rust-android") version "0.9.6" apply false
- id("org.jetbrains.dokka") version "2.0.0" apply false
+id("org.jetbrains.dokka") version "2.0.0" apply false
id("com.adarshr.test-logger") version "3.2.0" apply false
kotlin("plugin.serialization") version "1.9.0" apply false
id("io.github.gradle-nexus.publish-plugin") version "2.0.0"
diff --git a/ci/scripts/bump-and-tag.bash b/ci/scripts/bump-and-tag.bash
index 5b5f7ee4..d02e2e45 100644
--- a/ci/scripts/bump-and-tag.bash
+++ b/ci/scripts/bump-and-tag.bash
@@ -5,27 +5,11 @@ set -xeo pipefail
readonly live_run=${LIVE_RUN:-false}
# Release number
readonly version=${VERSION:?input VERSION is required}
-# Dependencies' pattern
-readonly bump_deps_pattern=${BUMP_DEPS_PATTERN:-''}
-# Dependencies' version
-readonly bump_deps_version=${BUMP_DEPS_VERSION:-''}
-# Dependencies' git branch
-readonly bump_deps_branch=${BUMP_DEPS_BRANCH:-''}
# Git actor name
readonly git_user_name=${GIT_USER_NAME:?input GIT_USER_NAME is required}
# Git actor email
readonly git_user_email=${GIT_USER_EMAIL:?input GIT_USER_EMAIL is required}
-cargo +stable install toml-cli
-
-# NOTE(fuzzypixelz): toml-cli doesn't yet support in-place modification
-# See: https://github.com/gnprice/toml-cli?tab=readme-ov-file#writing-ish-toml-set
-function toml_set_in_place() {
- local tmp=$(mktemp)
- toml set "$1" "$2" "$3" > "$tmp"
- mv "$tmp" "$1"
-}
-
export GIT_AUTHOR_NAME=$git_user_name
export GIT_AUTHOR_EMAIL=$git_user_email
export GIT_COMMITTER_NAME=$git_user_name
@@ -33,32 +17,8 @@ export GIT_COMMITTER_EMAIL=$git_user_email
# Bump Gradle project version
printf '%s' "$version" > version.txt
-# Propagate version change to zenoh-jni
-toml_set_in_place zenoh-jni/Cargo.toml "package.version" "$version"
-
-git commit version.txt zenoh-jni/Cargo.toml -m "chore: Bump version to \`$version\`"
-# Select all package dependencies that match $bump_deps_pattern and bump them to $bump_deps_version
-if [[ "$bump_deps_pattern" != '' ]]; then
- deps=$(toml get zenoh-jni/Cargo.toml dependencies | jq -r "keys[] | select(test(\"$bump_deps_pattern\"))")
- for dep in $deps; do
- if [[ -n $bump_deps_version ]]; then
- toml_set_in_place zenoh-jni/Cargo.toml "dependencies.$dep.version" "$bump_deps_version"
- fi
-
- if [[ -n $bump_deps_branch ]]; then
- toml_set_in_place zenoh-jni/Cargo.toml "dependencies.$dep.branch" "$bump_deps_branch"
- fi
- done
- # Update lockfile
- cargo check --manifest-path zenoh-jni/Cargo.toml
-
- if [[ -n $bump_deps_version || -n $bump_deps_branch ]]; then
- git commit zenoh-jni/Cargo.toml zenoh-jni/Cargo.lock -m "chore: Bump \`$bump_deps_pattern\` dependencies to \`$bump_deps_version\`"
- else
- echo "warn: no changes have been made to any dependencies matching $bump_deps_pattern"
- fi
-fi
+git commit version.txt -m "chore: Bump version to \`$version\`"
if [[ ${live_run} ]]; then
git tag --force "$version" -m "v$version"
diff --git a/examples/build.gradle.kts b/examples/build.gradle.kts
index 4013e0d2..a890df2f 100644
--- a/examples/build.gradle.kts
+++ b/examples/build.gradle.kts
@@ -80,19 +80,9 @@ tasks {
examples.forEach { example ->
register(example, JavaExec::class) {
- dependsOn("CompileZenohJNI")
description = "Run the $example example"
mainClass.set("io.zenoh.${example}Kt")
classpath(sourceSets["main"].runtimeClasspath)
- val zenohPaths = "../zenoh-jni/target/release"
- val defaultJvmArgs = arrayListOf("-Djava.library.path=$zenohPaths")
- jvmArgs(defaultJvmArgs)
}
}
}
-
-tasks.register("CompileZenohJNI") {
- project.exec {
- commandLine("cargo", "build", "--release", "--manifest-path", "../zenoh-jni/Cargo.toml")
- }
-}
diff --git a/gradle.properties b/gradle.properties
index 5c311496..1d7fb9c6 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,2 +1,12 @@
org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled
org.jetbrains.dokka.experimental.gradle.pluginMode.noWarn=true
+
+# Version of zenoh-jni-runtime to depend on (published by zenoh-java).
+# Override in local gradle.properties when you need a different runtime version.
+zenohJniRuntimeVersion=1.9.0
+
+# Set to true to substitute the zenoh-jni-runtime Maven dependency with the local
+# zenoh-java submodule build (useful for local development and testing only).
+# Do NOT enable this for publication — the released artifact must resolve against
+# the already-published runtime owned by zenoh-java.
+zenoh.useLocalJniRuntime=false
diff --git a/rust-toolchain.toml b/rust-toolchain.toml
deleted file mode 100644
index 075062e5..00000000
--- a/rust-toolchain.toml
+++ /dev/null
@@ -1,2 +0,0 @@
-[toolchain]
-channel = "1.93.0"
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 6126e8ce..ed9b889c 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -23,7 +23,23 @@ rootProject.name = "zenoh-kotlin"
include(":zenoh-kotlin")
include(":examples")
-include(":zenoh-jni")
+
+// Include the local zenoh-java submodule only when explicitly requested via the
+// zenoh.useLocalJniRuntime property (local dev/test only — not for publication).
+val useLocalJniRuntime = settings.providers.gradleProperty("zenoh.useLocalJniRuntime")
+ .orNull?.toBoolean() == true
+if (useLocalJniRuntime) {
+ require(file("zenoh-java/settings.gradle.kts").exists()) {
+ "zenoh.useLocalJniRuntime=true was requested but the zenoh-java submodule is not initialized. " +
+ "Run: git submodule update --init --recursive"
+ }
+ includeBuild("zenoh-java") {
+ dependencySubstitution {
+ substitute(module("org.eclipse.zenoh:zenoh-jni-runtime"))
+ .using(project(":zenoh-jni-runtime"))
+ }
+ }
+}
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version("0.4.0")
diff --git a/zenoh-java b/zenoh-java
new file mode 160000
index 00000000..fc47b41f
--- /dev/null
+++ b/zenoh-java
@@ -0,0 +1 @@
+Subproject commit fc47b41f40974af89af6a3885821228ca9c66427
diff --git a/zenoh-jni/Cargo.lock b/zenoh-jni/Cargo.lock
deleted file mode 100644
index bd456c8a..00000000
--- a/zenoh-jni/Cargo.lock
+++ /dev/null
@@ -1,4406 +0,0 @@
-# This file is automatically @generated by Cargo.
-# It is not intended for manual editing.
-version = 3
-
-[[package]]
-name = "adler2"
-version = "2.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
-
-[[package]]
-name = "aes"
-version = "0.8.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0"
-dependencies = [
- "cfg-if",
- "cipher",
- "cpufeatures",
-]
-
-[[package]]
-name = "ahash"
-version = "0.8.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75"
-dependencies = [
- "cfg-if",
- "getrandom 0.3.4",
- "once_cell",
- "version_check",
- "zerocopy",
-]
-
-[[package]]
-name = "aho-corasick"
-version = "1.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
-dependencies = [
- "memchr",
-]
-
-[[package]]
-name = "allocator-api2"
-version = "0.2.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
-
-[[package]]
-name = "android-logd-logger"
-version = "0.4.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0483169d5fac0887f85c2fa8fecfe08669791712d8260de1a6ec30630a62932f"
-dependencies = [
- "bytes",
- "env_logger",
- "lazy_static",
- "libc",
- "log",
- "parking_lot",
- "redox_syscall 0.4.1",
- "thiserror 1.0.69",
- "time",
- "winapi",
-]
-
-[[package]]
-name = "android_system_properties"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "anyhow"
-version = "1.0.102"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
-
-[[package]]
-name = "arc-swap"
-version = "1.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a3a1fd6f75306b68087b831f025c712524bcb19aad54e557b1129cfa0a2b207"
-dependencies = [
- "rustversion",
-]
-
-[[package]]
-name = "array-init"
-version = "2.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3d62b7694a562cdf5a74227903507c56ab2cc8bdd1f781ed5cb4cf9c9f810bfc"
-
-[[package]]
-name = "asn1-rs"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56624a96882bb8c26d61312ae18cb45868e5a9992ea73c58e45c3101e56a1e60"
-dependencies = [
- "asn1-rs-derive",
- "asn1-rs-impl",
- "displaydoc",
- "nom",
- "num-traits",
- "rusticata-macros",
- "thiserror 2.0.18",
- "time",
-]
-
-[[package]]
-name = "asn1-rs-derive"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3109e49b1e4909e9db6515a30c633684d68cdeaa252f215214cb4fa1a5bfee2c"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.117",
- "synstructure",
-]
-
-[[package]]
-name = "asn1-rs-impl"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.117",
-]
-
-[[package]]
-name = "async-std"
-version = "1.12.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d"
-
-[[package]]
-name = "async-trait"
-version = "0.1.89"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.117",
-]
-
-[[package]]
-name = "atty"
-version = "0.2.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
-dependencies = [
- "hermit-abi 0.1.19",
- "libc",
- "winapi",
-]
-
-[[package]]
-name = "autocfg"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
-
-[[package]]
-name = "base64"
-version = "0.22.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
-
-[[package]]
-name = "base64ct"
-version = "1.8.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06"
-
-[[package]]
-name = "bincode"
-version = "1.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "bitflags"
-version = "1.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
-
-[[package]]
-name = "bitflags"
-version = "2.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af"
-dependencies = [
- "serde_core",
-]
-
-[[package]]
-name = "block-buffer"
-version = "0.10.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
-dependencies = [
- "generic-array",
-]
-
-[[package]]
-name = "bumpalo"
-version = "3.20.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb"
-
-[[package]]
-name = "byteorder"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
-
-[[package]]
-name = "bytes"
-version = "1.11.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
-
-[[package]]
-name = "cc"
-version = "1.2.59"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7a4d3ec6524d28a329fc53654bbadc9bdd7b0431f5d65f1a56ffb28a1ee5283"
-dependencies = [
- "find-msvc-tools",
- "shlex",
-]
-
-[[package]]
-name = "cesu8"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
-
-[[package]]
-name = "cfg-if"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
-
-[[package]]
-name = "cfg_aliases"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
-
-[[package]]
-name = "chrono"
-version = "0.4.44"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0"
-dependencies = [
- "iana-time-zone",
- "num-traits",
- "serde",
- "windows-link",
-]
-
-[[package]]
-name = "cipher"
-version = "0.4.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
-dependencies = [
- "crypto-common",
- "inout",
-]
-
-[[package]]
-name = "clap"
-version = "3.2.25"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123"
-dependencies = [
- "atty",
- "bitflags 1.3.2",
- "clap_lex",
- "indexmap 1.9.3",
- "strsim 0.10.0",
- "termcolor",
- "textwrap",
-]
-
-[[package]]
-name = "clap_lex"
-version = "0.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
-dependencies = [
- "os_str_bytes",
-]
-
-[[package]]
-name = "combine"
-version = "4.6.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd"
-dependencies = [
- "bytes",
- "memchr",
-]
-
-[[package]]
-name = "concurrent-queue"
-version = "2.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973"
-dependencies = [
- "crossbeam-utils",
-]
-
-[[package]]
-name = "const-oid"
-version = "0.9.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
-
-[[package]]
-name = "const_format"
-version = "0.2.35"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7faa7469a93a566e9ccc1c73fe783b4a65c274c5ace346038dca9c39fe0030ad"
-dependencies = [
- "const_format_proc_macros",
-]
-
-[[package]]
-name = "const_format_proc_macros"
-version = "0.2.34"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744"
-dependencies = [
- "proc-macro2",
- "quote",
- "unicode-xid",
-]
-
-[[package]]
-name = "core-foundation"
-version = "0.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6"
-dependencies = [
- "core-foundation-sys",
- "libc",
-]
-
-[[package]]
-name = "core-foundation-sys"
-version = "0.8.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
-
-[[package]]
-name = "cpufeatures"
-version = "0.2.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "crc32fast"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
-name = "crossbeam"
-version = "0.8.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8"
-dependencies = [
- "crossbeam-channel",
- "crossbeam-deque",
- "crossbeam-epoch",
- "crossbeam-queue",
- "crossbeam-utils",
-]
-
-[[package]]
-name = "crossbeam-channel"
-version = "0.5.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2"
-dependencies = [
- "crossbeam-utils",
-]
-
-[[package]]
-name = "crossbeam-deque"
-version = "0.8.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51"
-dependencies = [
- "crossbeam-epoch",
- "crossbeam-utils",
-]
-
-[[package]]
-name = "crossbeam-epoch"
-version = "0.9.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
-dependencies = [
- "crossbeam-utils",
-]
-
-[[package]]
-name = "crossbeam-queue"
-version = "0.3.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115"
-dependencies = [
- "crossbeam-utils",
-]
-
-[[package]]
-name = "crossbeam-utils"
-version = "0.8.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
-
-[[package]]
-name = "crypto-common"
-version = "0.1.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
-dependencies = [
- "generic-array",
- "typenum",
-]
-
-[[package]]
-name = "darling"
-version = "0.23.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d"
-dependencies = [
- "darling_core",
- "darling_macro",
-]
-
-[[package]]
-name = "darling_core"
-version = "0.23.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0"
-dependencies = [
- "ident_case",
- "proc-macro2",
- "quote",
- "strsim 0.11.1",
- "syn 2.0.117",
-]
-
-[[package]]
-name = "darling_macro"
-version = "0.23.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d"
-dependencies = [
- "darling_core",
- "quote",
- "syn 2.0.117",
-]
-
-[[package]]
-name = "data-encoding"
-version = "2.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea"
-
-[[package]]
-name = "der"
-version = "0.7.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb"
-dependencies = [
- "const-oid",
- "pem-rfc7468",
- "zeroize",
-]
-
-[[package]]
-name = "der-parser"
-version = "10.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07da5016415d5a3c4dd39b11ed26f915f52fc4e0dc197d87908bc916e51bc1a6"
-dependencies = [
- "asn1-rs",
- "displaydoc",
- "nom",
- "num-bigint",
- "num-traits",
- "rusticata-macros",
-]
-
-[[package]]
-name = "deranged"
-version = "0.5.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c"
-dependencies = [
- "powerfmt",
- "serde_core",
-]
-
-[[package]]
-name = "digest"
-version = "0.10.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
-dependencies = [
- "block-buffer",
- "const-oid",
- "crypto-common",
- "subtle",
-]
-
-[[package]]
-name = "dirs"
-version = "6.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e"
-dependencies = [
- "dirs-sys",
-]
-
-[[package]]
-name = "dirs-sys"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
-dependencies = [
- "libc",
- "option-ext",
- "redox_users",
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "displaydoc"
-version = "0.2.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.117",
-]
-
-[[package]]
-name = "dyn-clone"
-version = "1.0.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555"
-
-[[package]]
-name = "either"
-version = "1.15.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
-
-[[package]]
-name = "env_logger"
-version = "0.10.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580"
-dependencies = [
- "log",
- "regex",
-]
-
-[[package]]
-name = "equivalent"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
-
-[[package]]
-name = "event-listener"
-version = "5.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab"
-dependencies = [
- "concurrent-queue",
- "parking",
- "pin-project-lite",
-]
-
-[[package]]
-name = "fastbloom"
-version = "0.14.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4e7f34442dbe69c60fe8eaf58a8cafff81a1f278816d8ab4db255b3bef4ac3c4"
-dependencies = [
- "getrandom 0.3.4",
- "libm",
- "rand 0.9.2",
- "siphasher",
-]
-
-[[package]]
-name = "fastrand"
-version = "2.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6"
-
-[[package]]
-name = "find-msvc-tools"
-version = "0.1.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
-
-[[package]]
-name = "fixedbitset"
-version = "0.5.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99"
-
-[[package]]
-name = "flate2"
-version = "1.1.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c"
-dependencies = [
- "crc32fast",
- "miniz_oxide",
-]
-
-[[package]]
-name = "flume"
-version = "0.10.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577"
-dependencies = [
- "futures-core",
- "futures-sink",
- "nanorand",
- "pin-project",
- "spin 0.9.8",
-]
-
-[[package]]
-name = "flume"
-version = "0.11.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095"
-dependencies = [
- "futures-core",
- "futures-sink",
- "nanorand",
- "spin 0.9.8",
-]
-
-[[package]]
-name = "foldhash"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
-
-[[package]]
-name = "foldhash"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
-
-[[package]]
-name = "form_urlencoded"
-version = "1.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf"
-dependencies = [
- "percent-encoding",
-]
-
-[[package]]
-name = "futures"
-version = "0.3.32"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d"
-dependencies = [
- "futures-channel",
- "futures-core",
- "futures-executor",
- "futures-io",
- "futures-sink",
- "futures-task",
- "futures-util",
-]
-
-[[package]]
-name = "futures-channel"
-version = "0.3.32"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d"
-dependencies = [
- "futures-core",
- "futures-sink",
-]
-
-[[package]]
-name = "futures-core"
-version = "0.3.32"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d"
-
-[[package]]
-name = "futures-executor"
-version = "0.3.32"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d"
-dependencies = [
- "futures-core",
- "futures-task",
- "futures-util",
-]
-
-[[package]]
-name = "futures-io"
-version = "0.3.32"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718"
-
-[[package]]
-name = "futures-macro"
-version = "0.3.32"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.117",
-]
-
-[[package]]
-name = "futures-sink"
-version = "0.3.32"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893"
-
-[[package]]
-name = "futures-task"
-version = "0.3.32"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393"
-
-[[package]]
-name = "futures-util"
-version = "0.3.32"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6"
-dependencies = [
- "futures-channel",
- "futures-core",
- "futures-io",
- "futures-macro",
- "futures-sink",
- "futures-task",
- "memchr",
- "pin-project-lite",
- "slab",
-]
-
-[[package]]
-name = "generic-array"
-version = "0.14.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
-dependencies = [
- "typenum",
- "version_check",
-]
-
-[[package]]
-name = "getrandom"
-version = "0.2.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
-dependencies = [
- "cfg-if",
- "js-sys",
- "libc",
- "wasi",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "getrandom"
-version = "0.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
-dependencies = [
- "cfg-if",
- "js-sys",
- "libc",
- "r-efi 5.3.0",
- "wasip2",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "getrandom"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555"
-dependencies = [
- "cfg-if",
- "libc",
- "r-efi 6.0.0",
- "wasip2",
- "wasip3",
-]
-
-[[package]]
-name = "git-version"
-version = "0.3.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ad568aa3db0fcbc81f2f116137f263d7304f512a1209b35b85150d3ef88ad19"
-dependencies = [
- "git-version-macro",
-]
-
-[[package]]
-name = "git-version-macro"
-version = "0.3.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53010ccb100b96a67bc32c0175f0ed1426b31b655d562898e57325f81c023ac0"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.117",
-]
-
-[[package]]
-name = "hashbrown"
-version = "0.12.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
-
-[[package]]
-name = "hashbrown"
-version = "0.14.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
-dependencies = [
- "ahash",
- "allocator-api2",
-]
-
-[[package]]
-name = "hashbrown"
-version = "0.15.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
-dependencies = [
- "foldhash 0.1.5",
-]
-
-[[package]]
-name = "hashbrown"
-version = "0.16.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
-dependencies = [
- "allocator-api2",
- "equivalent",
- "foldhash 0.2.0",
-]
-
-[[package]]
-name = "heck"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
-
-[[package]]
-name = "hermit-abi"
-version = "0.1.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "hermit-abi"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
-
-[[package]]
-name = "hex"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
-
-[[package]]
-name = "hmac"
-version = "0.12.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
-dependencies = [
- "digest",
-]
-
-[[package]]
-name = "home"
-version = "0.5.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d"
-dependencies = [
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "http"
-version = "1.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a"
-dependencies = [
- "bytes",
- "itoa",
-]
-
-[[package]]
-name = "httparse"
-version = "1.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
-
-[[package]]
-name = "humantime"
-version = "2.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424"
-
-[[package]]
-name = "iana-time-zone"
-version = "0.1.65"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470"
-dependencies = [
- "android_system_properties",
- "core-foundation-sys",
- "iana-time-zone-haiku",
- "js-sys",
- "log",
- "wasm-bindgen",
- "windows-core",
-]
-
-[[package]]
-name = "iana-time-zone-haiku"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
-dependencies = [
- "cc",
-]
-
-[[package]]
-name = "icu_collections"
-version = "2.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c"
-dependencies = [
- "displaydoc",
- "potential_utf",
- "utf8_iter",
- "yoke",
- "zerofrom",
- "zerovec",
-]
-
-[[package]]
-name = "icu_locale_core"
-version = "2.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29"
-dependencies = [
- "displaydoc",
- "litemap",
- "tinystr",
- "writeable",
- "zerovec",
-]
-
-[[package]]
-name = "icu_normalizer"
-version = "2.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4"
-dependencies = [
- "icu_collections",
- "icu_normalizer_data",
- "icu_properties",
- "icu_provider",
- "smallvec",
- "zerovec",
-]
-
-[[package]]
-name = "icu_normalizer_data"
-version = "2.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38"
-
-[[package]]
-name = "icu_properties"
-version = "2.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de"
-dependencies = [
- "icu_collections",
- "icu_locale_core",
- "icu_properties_data",
- "icu_provider",
- "zerotrie",
- "zerovec",
-]
-
-[[package]]
-name = "icu_properties_data"
-version = "2.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14"
-
-[[package]]
-name = "icu_provider"
-version = "2.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421"
-dependencies = [
- "displaydoc",
- "icu_locale_core",
- "writeable",
- "yoke",
- "zerofrom",
- "zerotrie",
- "zerovec",
-]
-
-[[package]]
-name = "id-arena"
-version = "2.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
-
-[[package]]
-name = "ident_case"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
-
-[[package]]
-name = "idna"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de"
-dependencies = [
- "idna_adapter",
- "smallvec",
- "utf8_iter",
-]
-
-[[package]]
-name = "idna_adapter"
-version = "1.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344"
-dependencies = [
- "icu_normalizer",
- "icu_properties",
-]
-
-[[package]]
-name = "indexmap"
-version = "1.9.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
-dependencies = [
- "autocfg",
- "hashbrown 0.12.3",
- "serde",
-]
-
-[[package]]
-name = "indexmap"
-version = "2.13.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "45a8a2b9cb3e0b0c1803dbb0758ffac5de2f425b23c28f518faabd9d805342ff"
-dependencies = [
- "equivalent",
- "hashbrown 0.16.1",
- "serde",
- "serde_core",
-]
-
-[[package]]
-name = "inout"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01"
-dependencies = [
- "generic-array",
-]
-
-[[package]]
-name = "ipnetwork"
-version = "0.20.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf466541e9d546596ee94f9f69590f89473455f88372423e0008fc1a7daf100e"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "itertools"
-version = "0.14.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
-dependencies = [
- "either",
-]
-
-[[package]]
-name = "itoa"
-version = "1.0.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
-
-[[package]]
-name = "jni"
-version = "0.21.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97"
-dependencies = [
- "cesu8",
- "cfg-if",
- "combine",
- "jni-sys 0.3.1",
- "log",
- "thiserror 1.0.69",
- "walkdir",
- "windows-sys 0.45.0",
-]
-
-[[package]]
-name = "jni-sys"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258"
-dependencies = [
- "jni-sys 0.4.1",
-]
-
-[[package]]
-name = "jni-sys"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2"
-dependencies = [
- "jni-sys-macros",
-]
-
-[[package]]
-name = "jni-sys-macros"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264"
-dependencies = [
- "quote",
- "syn 2.0.117",
-]
-
-[[package]]
-name = "js-sys"
-version = "0.3.94"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2e04e2ef80ce82e13552136fabeef8a5ed1f985a96805761cbb9a2c34e7664d9"
-dependencies = [
- "once_cell",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "json5"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1"
-dependencies = [
- "pest",
- "pest_derive",
- "serde",
-]
-
-[[package]]
-name = "keccak"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653"
-dependencies = [
- "cpufeatures",
-]
-
-[[package]]
-name = "keyed-set"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89d255a6b6ecd77bb93ce91de984d7039bff7503f500eb4851a1269732f22baf"
-dependencies = [
- "hashbrown 0.14.5",
-]
-
-[[package]]
-name = "lazy_static"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
-dependencies = [
- "spin 0.9.8",
-]
-
-[[package]]
-name = "leb128"
-version = "0.2.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67"
-
-[[package]]
-name = "leb128fmt"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
-
-[[package]]
-name = "libc"
-version = "0.2.184"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af"
-
-[[package]]
-name = "libloading"
-version = "0.8.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55"
-dependencies = [
- "cfg-if",
- "windows-link",
-]
-
-[[package]]
-name = "libm"
-version = "0.2.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
-
-[[package]]
-name = "libredox"
-version = "0.1.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ddbf48fd451246b1f8c2610bd3b4ac0cc6e149d89832867093ab69a17194f08"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "litemap"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0"
-
-[[package]]
-name = "lock_api"
-version = "0.4.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
-dependencies = [
- "scopeguard",
-]
-
-[[package]]
-name = "log"
-version = "0.4.29"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
-
-[[package]]
-name = "lru-slab"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154"
-
-[[package]]
-name = "lz4_flex"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b8c72594ac26bfd34f2d99dfced2edfaddfe8a476e3ff2ca0eb293d925c4f83"
-dependencies = [
- "twox-hash",
-]
-
-[[package]]
-name = "matchers"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9"
-dependencies = [
- "regex-automata",
-]
-
-[[package]]
-name = "memchr"
-version = "2.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
-
-[[package]]
-name = "minimal-lexical"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
-
-[[package]]
-name = "miniz_oxide"
-version = "0.8.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
-dependencies = [
- "adler2",
- "simd-adler32",
-]
-
-[[package]]
-name = "mio"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1"
-dependencies = [
- "libc",
- "wasi",
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "nanorand"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3"
-dependencies = [
- "getrandom 0.2.17",
-]
-
-[[package]]
-name = "nix"
-version = "0.29.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
-dependencies = [
- "bitflags 2.11.0",
- "cfg-if",
- "cfg_aliases",
- "libc",
-]
-
-[[package]]
-name = "no-std-net"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43794a0ace135be66a25d3ae77d41b91615fb68ae937f904090203e81f755b65"
-
-[[package]]
-name = "nom"
-version = "7.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
-dependencies = [
- "memchr",
- "minimal-lexical",
-]
-
-[[package]]
-name = "nonempty-collections"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e216d0e8cf9d54fa66e5780f6e1d5dc96d1c1b3c25aeba3b6758548bcbbd8b9d"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "nu-ansi-term"
-version = "0.50.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
-dependencies = [
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "num-bigint"
-version = "0.4.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
-dependencies = [
- "num-integer",
- "num-traits",
-]
-
-[[package]]
-name = "num-bigint-dig"
-version = "0.8.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7"
-dependencies = [
- "lazy_static",
- "libm",
- "num-integer",
- "num-iter",
- "num-traits",
- "rand 0.8.5",
- "smallvec",
- "zeroize",
-]
-
-[[package]]
-name = "num-conv"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967"
-
-[[package]]
-name = "num-integer"
-version = "0.1.46"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
-dependencies = [
- "num-traits",
-]
-
-[[package]]
-name = "num-iter"
-version = "0.1.45"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf"
-dependencies = [
- "autocfg",
- "num-integer",
- "num-traits",
-]
-
-[[package]]
-name = "num-traits"
-version = "0.2.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
-dependencies = [
- "autocfg",
- "libm",
-]
-
-[[package]]
-name = "num_cpus"
-version = "1.17.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b"
-dependencies = [
- "hermit-abi 0.5.2",
- "libc",
-]
-
-[[package]]
-name = "oid-registry"
-version = "0.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "12f40cff3dde1b6087cc5d5f5d4d65712f34016a03ed60e9c08dcc392736b5b7"
-dependencies = [
- "asn1-rs",
-]
-
-[[package]]
-name = "once_cell"
-version = "1.21.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
-
-[[package]]
-name = "openssl-probe"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe"
-
-[[package]]
-name = "option-ext"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
-
-[[package]]
-name = "os_str_bytes"
-version = "6.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1"
-
-[[package]]
-name = "parking"
-version = "2.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
-
-[[package]]
-name = "parking_lot"
-version = "0.12.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a"
-dependencies = [
- "lock_api",
- "parking_lot_core",
-]
-
-[[package]]
-name = "parking_lot_core"
-version = "0.9.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1"
-dependencies = [
- "cfg-if",
- "libc",
- "redox_syscall 0.5.18",
- "smallvec",
- "windows-link",
-]
-
-[[package]]
-name = "paste"
-version = "1.0.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
-
-[[package]]
-name = "pem"
-version = "3.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be"
-dependencies = [
- "base64",
- "serde_core",
-]
-
-[[package]]
-name = "pem-rfc7468"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412"
-dependencies = [
- "base64ct",
-]
-
-[[package]]
-name = "percent-encoding"
-version = "2.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
-
-[[package]]
-name = "pest"
-version = "2.8.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e0848c601009d37dfa3430c4666e147e49cdcf1b92ecd3e63657d8a5f19da662"
-dependencies = [
- "memchr",
- "ucd-trie",
-]
-
-[[package]]
-name = "pest_derive"
-version = "2.8.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "11f486f1ea21e6c10ed15d5a7c77165d0ee443402f0780849d1768e7d9d6fe77"
-dependencies = [
- "pest",
- "pest_generator",
-]
-
-[[package]]
-name = "pest_generator"
-version = "2.8.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8040c4647b13b210a963c1ed407c1ff4fdfa01c31d6d2a098218702e6664f94f"
-dependencies = [
- "pest",
- "pest_meta",
- "proc-macro2",
- "quote",
- "syn 2.0.117",
-]
-
-[[package]]
-name = "pest_meta"
-version = "2.8.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89815c69d36021a140146f26659a81d6c2afa33d216d736dd4be5381a7362220"
-dependencies = [
- "pest",
- "sha2",
-]
-
-[[package]]
-name = "petgraph"
-version = "0.8.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455"
-dependencies = [
- "fixedbitset",
- "hashbrown 0.15.5",
- "indexmap 2.13.1",
- "serde",
-]
-
-[[package]]
-name = "phf"
-version = "0.13.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf"
-dependencies = [
- "phf_macros",
- "phf_shared",
- "serde",
-]
-
-[[package]]
-name = "phf_generator"
-version = "0.13.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737"
-dependencies = [
- "fastrand",
- "phf_shared",
-]
-
-[[package]]
-name = "phf_macros"
-version = "0.13.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef"
-dependencies = [
- "phf_generator",
- "phf_shared",
- "proc-macro2",
- "quote",
- "syn 2.0.117",
-]
-
-[[package]]
-name = "phf_shared"
-version = "0.13.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266"
-dependencies = [
- "siphasher",
-]
-
-[[package]]
-name = "pin-project"
-version = "1.1.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517"
-dependencies = [
- "pin-project-internal",
-]
-
-[[package]]
-name = "pin-project-internal"
-version = "1.1.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.117",
-]
-
-[[package]]
-name = "pin-project-lite"
-version = "0.2.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
-
-[[package]]
-name = "pkcs1"
-version = "0.7.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f"
-dependencies = [
- "der",
- "pkcs8",
- "spki",
-]
-
-[[package]]
-name = "pkcs8"
-version = "0.10.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7"
-dependencies = [
- "der",
- "spki",
-]
-
-[[package]]
-name = "pnet_base"
-version = "0.35.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ffc190d4067df16af3aba49b3b74c469e611cad6314676eaf1157f31aa0fb2f7"
-dependencies = [
- "no-std-net",
-]
-
-[[package]]
-name = "pnet_datalink"
-version = "0.35.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e79e70ec0be163102a332e1d2d5586d362ad76b01cec86f830241f2b6452a7b7"
-dependencies = [
- "ipnetwork",
- "libc",
- "pnet_base",
- "pnet_sys",
- "winapi",
-]
-
-[[package]]
-name = "pnet_sys"
-version = "0.35.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d4643d3d4db6b08741050c2f3afa9a892c4244c085a72fcda93c9c2c9a00f4b"
-dependencies = [
- "libc",
- "winapi",
-]
-
-[[package]]
-name = "portable-atomic"
-version = "1.13.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
-
-[[package]]
-name = "potential_utf"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564"
-dependencies = [
- "zerovec",
-]
-
-[[package]]
-name = "powerfmt"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
-
-[[package]]
-name = "ppv-lite86"
-version = "0.2.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
-dependencies = [
- "zerocopy",
-]
-
-[[package]]
-name = "prettyplease"
-version = "0.2.37"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
-dependencies = [
- "proc-macro2",
- "syn 2.0.117",
-]
-
-[[package]]
-name = "proc-macro-crate"
-version = "3.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f"
-dependencies = [
- "toml_edit",
-]
-
-[[package]]
-name = "proc-macro2"
-version = "1.0.106"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
-dependencies = [
- "unicode-ident",
-]
-
-[[package]]
-name = "quinn"
-version = "0.11.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20"
-dependencies = [
- "bytes",
- "cfg_aliases",
- "pin-project-lite",
- "quinn-proto",
- "quinn-udp",
- "rustc-hash",
- "rustls",
- "socket2 0.6.3",
- "thiserror 2.0.18",
- "tokio",
- "tracing",
- "web-time",
-]
-
-[[package]]
-name = "quinn-proto"
-version = "0.11.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098"
-dependencies = [
- "bytes",
- "fastbloom",
- "getrandom 0.3.4",
- "lru-slab",
- "rand 0.9.2",
- "ring",
- "rustc-hash",
- "rustls",
- "rustls-pki-types",
- "rustls-platform-verifier",
- "slab",
- "thiserror 2.0.18",
- "tinyvec",
- "tracing",
- "web-time",
-]
-
-[[package]]
-name = "quinn-udp"
-version = "0.5.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd"
-dependencies = [
- "cfg_aliases",
- "libc",
- "once_cell",
- "socket2 0.6.3",
- "tracing",
- "windows-sys 0.60.2",
-]
-
-[[package]]
-name = "quote"
-version = "1.0.45"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
-dependencies = [
- "proc-macro2",
-]
-
-[[package]]
-name = "r-efi"
-version = "5.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
-
-[[package]]
-name = "r-efi"
-version = "6.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
-
-[[package]]
-name = "rand"
-version = "0.8.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
-dependencies = [
- "libc",
- "rand_chacha 0.3.1",
- "rand_core 0.6.4",
-]
-
-[[package]]
-name = "rand"
-version = "0.9.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
-dependencies = [
- "rand_chacha 0.9.0",
- "rand_core 0.9.5",
-]
-
-[[package]]
-name = "rand_chacha"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
-dependencies = [
- "ppv-lite86",
- "rand_core 0.6.4",
-]
-
-[[package]]
-name = "rand_chacha"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
-dependencies = [
- "ppv-lite86",
- "rand_core 0.9.5",
-]
-
-[[package]]
-name = "rand_core"
-version = "0.6.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
-dependencies = [
- "getrandom 0.2.17",
-]
-
-[[package]]
-name = "rand_core"
-version = "0.9.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c"
-dependencies = [
- "getrandom 0.3.4",
-]
-
-[[package]]
-name = "rcgen"
-version = "0.14.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10b99e0098aa4082912d4c649628623db6aba77335e4f4569ff5083a6448b32e"
-dependencies = [
- "pem",
- "ring",
- "rustls-pki-types",
- "time",
- "x509-parser",
- "yasna",
-]
-
-[[package]]
-name = "redox_syscall"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
-dependencies = [
- "bitflags 1.3.2",
-]
-
-[[package]]
-name = "redox_syscall"
-version = "0.5.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
-dependencies = [
- "bitflags 2.11.0",
-]
-
-[[package]]
-name = "redox_users"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac"
-dependencies = [
- "getrandom 0.2.17",
- "libredox",
- "thiserror 2.0.18",
-]
-
-[[package]]
-name = "ref-cast"
-version = "1.0.25"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d"
-dependencies = [
- "ref-cast-impl",
-]
-
-[[package]]
-name = "ref-cast-impl"
-version = "1.0.25"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.117",
-]
-
-[[package]]
-name = "regex"
-version = "1.12.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276"
-dependencies = [
- "aho-corasick",
- "memchr",
- "regex-automata",
- "regex-syntax",
-]
-
-[[package]]
-name = "regex-automata"
-version = "0.4.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
-dependencies = [
- "aho-corasick",
- "memchr",
- "regex-syntax",
-]
-
-[[package]]
-name = "regex-syntax"
-version = "0.8.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
-
-[[package]]
-name = "ring"
-version = "0.17.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
-dependencies = [
- "cc",
- "cfg-if",
- "getrandom 0.2.17",
- "libc",
- "untrusted",
- "windows-sys 0.52.0",
-]
-
-[[package]]
-name = "ringbuffer-spsc"
-version = "0.1.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d3e7aa0a681b232e7cd7f856a53b10603df88ca74b79a8d8088845185492e35"
-dependencies = [
- "array-init",
- "crossbeam",
-]
-
-[[package]]
-name = "ron"
-version = "0.12.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4147b952f3f819eca0e99527022f7d6a8d05f111aeb0a62960c74eb283bec8fc"
-dependencies = [
- "bitflags 2.11.0",
- "once_cell",
- "serde",
- "serde_derive",
- "typeid",
- "unicode-ident",
-]
-
-[[package]]
-name = "rsa"
-version = "0.9.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d"
-dependencies = [
- "const-oid",
- "digest",
- "num-bigint-dig",
- "num-integer",
- "num-traits",
- "pkcs1",
- "pkcs8",
- "rand_core 0.6.4",
- "signature",
- "spki",
- "subtle",
- "zeroize",
-]
-
-[[package]]
-name = "rustc-hash"
-version = "2.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe"
-
-[[package]]
-name = "rustc_version"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
-dependencies = [
- "semver",
-]
-
-[[package]]
-name = "rusticata-macros"
-version = "4.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632"
-dependencies = [
- "nom",
-]
-
-[[package]]
-name = "rustls"
-version = "0.23.37"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4"
-dependencies = [
- "log",
- "once_cell",
- "ring",
- "rustls-pki-types",
- "rustls-webpki",
- "subtle",
- "zeroize",
-]
-
-[[package]]
-name = "rustls-native-certs"
-version = "0.8.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63"
-dependencies = [
- "openssl-probe",
- "rustls-pki-types",
- "schannel",
- "security-framework",
-]
-
-[[package]]
-name = "rustls-pemfile"
-version = "2.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50"
-dependencies = [
- "rustls-pki-types",
-]
-
-[[package]]
-name = "rustls-pki-types"
-version = "1.14.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd"
-dependencies = [
- "web-time",
- "zeroize",
-]
-
-[[package]]
-name = "rustls-platform-verifier"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784"
-dependencies = [
- "core-foundation",
- "core-foundation-sys",
- "jni",
- "log",
- "once_cell",
- "rustls",
- "rustls-native-certs",
- "rustls-platform-verifier-android",
- "rustls-webpki",
- "security-framework",
- "security-framework-sys",
- "webpki-root-certs",
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "rustls-platform-verifier-android"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f"
-
-[[package]]
-name = "rustls-webpki"
-version = "0.103.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef"
-dependencies = [
- "ring",
- "rustls-pki-types",
- "untrusted",
-]
-
-[[package]]
-name = "rustversion"
-version = "1.0.22"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
-
-[[package]]
-name = "ryu"
-version = "1.0.23"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f"
-
-[[package]]
-name = "same-file"
-version = "1.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
-dependencies = [
- "winapi-util",
-]
-
-[[package]]
-name = "schannel"
-version = "0.1.29"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939"
-dependencies = [
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "schemars"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f"
-dependencies = [
- "dyn-clone",
- "ref-cast",
- "serde",
- "serde_json",
-]
-
-[[package]]
-name = "schemars"
-version = "1.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2b42f36aa1cd011945615b92222f6bf73c599a102a300334cd7f8dbeec726cc"
-dependencies = [
- "dyn-clone",
- "either",
- "ref-cast",
- "schemars_derive",
- "serde",
- "serde_json",
-]
-
-[[package]]
-name = "schemars_derive"
-version = "1.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d115b50f4aaeea07e79c1912f645c7513d81715d0420f8bc77a18c6260b307f"
-dependencies = [
- "proc-macro2",
- "quote",
- "serde_derive_internals",
- "syn 2.0.117",
-]
-
-[[package]]
-name = "scopeguard"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
-
-[[package]]
-name = "secrecy"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e"
-dependencies = [
- "serde",
- "zeroize",
-]
-
-[[package]]
-name = "security-framework"
-version = "3.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d"
-dependencies = [
- "bitflags 2.11.0",
- "core-foundation",
- "core-foundation-sys",
- "libc",
- "security-framework-sys",
-]
-
-[[package]]
-name = "security-framework-sys"
-version = "2.17.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3"
-dependencies = [
- "core-foundation-sys",
- "libc",
-]
-
-[[package]]
-name = "semver"
-version = "1.0.28"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
-
-[[package]]
-name = "serde"
-version = "1.0.228"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
-dependencies = [
- "serde_core",
- "serde_derive",
-]
-
-[[package]]
-name = "serde_core"
-version = "1.0.228"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
-dependencies = [
- "serde_derive",
-]
-
-[[package]]
-name = "serde_derive"
-version = "1.0.228"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.117",
-]
-
-[[package]]
-name = "serde_derive_internals"
-version = "0.29.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.117",
-]
-
-[[package]]
-name = "serde_json"
-version = "1.0.149"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
-dependencies = [
- "itoa",
- "memchr",
- "serde",
- "serde_core",
- "zmij",
-]
-
-[[package]]
-name = "serde_spanned"
-version = "1.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26"
-dependencies = [
- "serde_core",
-]
-
-[[package]]
-name = "serde_with"
-version = "3.18.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd5414fad8e6907dbdd5bc441a50ae8d6e26151a03b1de04d89a5576de61d01f"
-dependencies = [
- "base64",
- "chrono",
- "hex",
- "indexmap 1.9.3",
- "indexmap 2.13.1",
- "schemars 0.9.0",
- "schemars 1.2.1",
- "serde_core",
- "serde_json",
- "serde_with_macros",
- "time",
-]
-
-[[package]]
-name = "serde_with_macros"
-version = "3.18.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d3db8978e608f1fe7357e211969fd9abdcae80bac1ba7a3369bb7eb6b404eb65"
-dependencies = [
- "darling",
- "proc-macro2",
- "quote",
- "syn 2.0.117",
-]
-
-[[package]]
-name = "serde_yaml"
-version = "0.9.34+deprecated"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
-dependencies = [
- "indexmap 2.13.1",
- "itoa",
- "ryu",
- "serde",
- "unsafe-libyaml",
-]
-
-[[package]]
-name = "sha1"
-version = "0.10.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
-dependencies = [
- "cfg-if",
- "cpufeatures",
- "digest",
-]
-
-[[package]]
-name = "sha2"
-version = "0.10.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
-dependencies = [
- "cfg-if",
- "cpufeatures",
- "digest",
-]
-
-[[package]]
-name = "sha2-const-stable"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f179d4e11094a893b82fff208f74d448a7512f99f5a0acbd5c679b705f83ed9"
-
-[[package]]
-name = "sha3"
-version = "0.10.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60"
-dependencies = [
- "digest",
- "keccak",
-]
-
-[[package]]
-name = "sharded-slab"
-version = "0.1.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
-dependencies = [
- "lazy_static",
-]
-
-[[package]]
-name = "shellexpand"
-version = "3.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32824fab5e16e6c4d86dc1ba84489390419a39f97699852b66480bb87d297ed8"
-dependencies = [
- "dirs",
-]
-
-[[package]]
-name = "shlex"
-version = "1.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
-
-[[package]]
-name = "signature"
-version = "2.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
-dependencies = [
- "digest",
- "rand_core 0.6.4",
-]
-
-[[package]]
-name = "simd-adler32"
-version = "0.3.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214"
-
-[[package]]
-name = "siphasher"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e"
-
-[[package]]
-name = "slab"
-version = "0.4.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
-
-[[package]]
-name = "smallvec"
-version = "1.15.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
-
-[[package]]
-name = "socket2"
-version = "0.5.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678"
-dependencies = [
- "libc",
- "windows-sys 0.52.0",
-]
-
-[[package]]
-name = "socket2"
-version = "0.6.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e"
-dependencies = [
- "libc",
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "spin"
-version = "0.9.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
-dependencies = [
- "lock_api",
-]
-
-[[package]]
-name = "spin"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591"
-
-[[package]]
-name = "spki"
-version = "0.7.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d"
-dependencies = [
- "base64ct",
- "der",
-]
-
-[[package]]
-name = "stabby"
-version = "72.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "976399a0c48ea769ef7f5dc303bb88240ab8d84008647a6b2303eced3dab3945"
-dependencies = [
- "rustversion",
- "stabby-abi",
-]
-
-[[package]]
-name = "stabby-abi"
-version = "72.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7b54832a9a1f92a0e55e74a5c0332744426edc515bb3fbad82f10b874a87f0d"
-dependencies = [
- "rustc_version",
- "rustversion",
- "sha2-const-stable",
- "stabby-macros",
-]
-
-[[package]]
-name = "stabby-macros"
-version = "72.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a768b1e51e4dbfa4fa52ae5c01241c0a41e2938fdffbb84add0c8238092f9091"
-dependencies = [
- "proc-macro-crate",
- "proc-macro2",
- "quote",
- "rand 0.8.5",
- "syn 1.0.109",
-]
-
-[[package]]
-name = "stable_deref_trait"
-version = "1.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
-
-[[package]]
-name = "static_assertions"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
-
-[[package]]
-name = "strsim"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
-
-[[package]]
-name = "strsim"
-version = "0.11.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
-
-[[package]]
-name = "subtle"
-version = "2.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
-
-[[package]]
-name = "syn"
-version = "1.0.109"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
-dependencies = [
- "proc-macro2",
- "quote",
- "unicode-ident",
-]
-
-[[package]]
-name = "syn"
-version = "2.0.117"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
-dependencies = [
- "proc-macro2",
- "quote",
- "unicode-ident",
-]
-
-[[package]]
-name = "synstructure"
-version = "0.13.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.117",
-]
-
-[[package]]
-name = "termcolor"
-version = "1.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
-dependencies = [
- "winapi-util",
-]
-
-[[package]]
-name = "textwrap"
-version = "0.16.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057"
-
-[[package]]
-name = "thiserror"
-version = "1.0.69"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
-dependencies = [
- "thiserror-impl 1.0.69",
-]
-
-[[package]]
-name = "thiserror"
-version = "2.0.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
-dependencies = [
- "thiserror-impl 2.0.18",
-]
-
-[[package]]
-name = "thiserror-impl"
-version = "1.0.69"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.117",
-]
-
-[[package]]
-name = "thiserror-impl"
-version = "2.0.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.117",
-]
-
-[[package]]
-name = "thread_local"
-version = "1.1.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
-name = "time"
-version = "0.3.47"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c"
-dependencies = [
- "deranged",
- "itoa",
- "num-conv",
- "powerfmt",
- "serde_core",
- "time-core",
- "time-macros",
-]
-
-[[package]]
-name = "time-core"
-version = "0.1.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca"
-
-[[package]]
-name = "time-macros"
-version = "0.2.27"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215"
-dependencies = [
- "num-conv",
- "time-core",
-]
-
-[[package]]
-name = "tinystr"
-version = "0.8.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d"
-dependencies = [
- "displaydoc",
- "zerovec",
-]
-
-[[package]]
-name = "tinyvec"
-version = "1.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3"
-dependencies = [
- "tinyvec_macros",
-]
-
-[[package]]
-name = "tinyvec_macros"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
-
-[[package]]
-name = "tls-listener"
-version = "0.11.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1461056cc1ef47003f7ee16e4cef3741068d4c7f6b627bfce49b7c00c120a530"
-dependencies = [
- "futures-util",
- "pin-project-lite",
- "thiserror 2.0.18",
- "tokio",
- "tokio-rustls",
-]
-
-[[package]]
-name = "token-cell"
-version = "2.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fb48920ae769b58126c8c93269805011c793201f95fde28b479b81a9a531bbde"
-dependencies = [
- "paste",
- "portable-atomic",
- "rustversion",
-]
-
-[[package]]
-name = "tokio"
-version = "1.51.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2bd1c4c0fc4a7ab90fc15ef6daaa3ec3b893f004f915f2392557ed23237820cd"
-dependencies = [
- "bytes",
- "libc",
- "mio",
- "pin-project-lite",
- "socket2 0.6.3",
- "tokio-macros",
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "tokio-macros"
-version = "2.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.117",
-]
-
-[[package]]
-name = "tokio-rustls"
-version = "0.26.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61"
-dependencies = [
- "rustls",
- "tokio",
-]
-
-[[package]]
-name = "tokio-tungstenite"
-version = "0.24.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "edc5f74e248dc973e0dbb7b74c7e0d6fcc301c694ff50049504004ef4d0cdcd9"
-dependencies = [
- "futures-util",
- "log",
- "tokio",
- "tungstenite",
-]
-
-[[package]]
-name = "tokio-util"
-version = "0.7.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098"
-dependencies = [
- "bytes",
- "futures-core",
- "futures-sink",
- "futures-util",
- "pin-project-lite",
- "tokio",
-]
-
-[[package]]
-name = "toml"
-version = "0.9.12+spec-1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863"
-dependencies = [
- "indexmap 2.13.1",
- "serde_core",
- "serde_spanned",
- "toml_datetime 0.7.5+spec-1.1.0",
- "toml_parser",
- "toml_writer",
- "winnow 0.7.15",
-]
-
-[[package]]
-name = "toml_datetime"
-version = "0.7.5+spec-1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347"
-dependencies = [
- "serde_core",
-]
-
-[[package]]
-name = "toml_datetime"
-version = "1.1.1+spec-1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7"
-dependencies = [
- "serde_core",
-]
-
-[[package]]
-name = "toml_edit"
-version = "0.25.11+spec-1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b"
-dependencies = [
- "indexmap 2.13.1",
- "toml_datetime 1.1.1+spec-1.1.0",
- "toml_parser",
- "winnow 1.0.1",
-]
-
-[[package]]
-name = "toml_parser"
-version = "1.1.2+spec-1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526"
-dependencies = [
- "winnow 1.0.1",
-]
-
-[[package]]
-name = "toml_writer"
-version = "1.1.1+spec-1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db"
-
-[[package]]
-name = "tracing"
-version = "0.1.44"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
-dependencies = [
- "log",
- "pin-project-lite",
- "tracing-attributes",
- "tracing-core",
-]
-
-[[package]]
-name = "tracing-attributes"
-version = "0.1.31"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.117",
-]
-
-[[package]]
-name = "tracing-core"
-version = "0.1.36"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a"
-dependencies = [
- "once_cell",
- "valuable",
-]
-
-[[package]]
-name = "tracing-log"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
-dependencies = [
- "log",
- "once_cell",
- "tracing-core",
-]
-
-[[package]]
-name = "tracing-serde"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1"
-dependencies = [
- "serde",
- "tracing-core",
-]
-
-[[package]]
-name = "tracing-subscriber"
-version = "0.3.23"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319"
-dependencies = [
- "matchers",
- "nu-ansi-term",
- "once_cell",
- "regex-automata",
- "serde",
- "serde_json",
- "sharded-slab",
- "smallvec",
- "thread_local",
- "tracing",
- "tracing-core",
- "tracing-log",
- "tracing-serde",
-]
-
-[[package]]
-name = "tungstenite"
-version = "0.24.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a"
-dependencies = [
- "byteorder",
- "bytes",
- "data-encoding",
- "http",
- "httparse",
- "log",
- "rand 0.8.5",
- "sha1",
- "thiserror 1.0.69",
- "utf-8",
-]
-
-[[package]]
-name = "twox-hash"
-version = "1.6.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675"
-dependencies = [
- "cfg-if",
- "static_assertions",
-]
-
-[[package]]
-name = "typeid"
-version = "1.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c"
-
-[[package]]
-name = "typenum"
-version = "1.19.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
-
-[[package]]
-name = "ucd-trie"
-version = "0.1.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
-
-[[package]]
-name = "uhlc"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b62a645e3e4e6c85b7abe49b086aa3204119431f42b6123b0070419fb6e9d24e"
-dependencies = [
- "humantime",
- "lazy_static",
- "log",
- "rand 0.8.5",
- "serde",
- "spin 0.10.0",
-]
-
-[[package]]
-name = "unicode-ident"
-version = "1.0.24"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
-
-[[package]]
-name = "unicode-xid"
-version = "0.2.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
-
-[[package]]
-name = "unsafe-libyaml"
-version = "0.2.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
-
-[[package]]
-name = "untrusted"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
-
-[[package]]
-name = "unzip-n"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3b5bb2756c16fb66f80cfbf5fb0e0c09a7001e739f453c9ec241b9c8b1556fda"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.117",
-]
-
-[[package]]
-name = "url"
-version = "2.5.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed"
-dependencies = [
- "form_urlencoded",
- "idna",
- "percent-encoding",
- "serde",
-]
-
-[[package]]
-name = "utf-8"
-version = "0.7.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
-
-[[package]]
-name = "utf8_iter"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
-
-[[package]]
-name = "uuid"
-version = "1.23.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9"
-dependencies = [
- "getrandom 0.4.2",
- "js-sys",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "validated_struct"
-version = "2.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "869a93e8a7286e339e1128630051d82babbcd75d585975af07b9f3327220e60e"
-dependencies = [
- "json5",
- "serde",
- "serde_json",
- "validated_struct_macros",
-]
-
-[[package]]
-name = "validated_struct_macros"
-version = "2.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c44ce98e7227a04eeb4cf9c784109a5c9710e54849ceb4f09f8597247897f1e"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.117",
- "unzip-n",
-]
-
-[[package]]
-name = "valuable"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
-
-[[package]]
-name = "vec_map"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
-
-[[package]]
-name = "version_check"
-version = "0.9.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
-
-[[package]]
-name = "walkdir"
-version = "2.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
-dependencies = [
- "same-file",
- "winapi-util",
-]
-
-[[package]]
-name = "wasi"
-version = "0.11.1+wasi-snapshot-preview1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
-
-[[package]]
-name = "wasip2"
-version = "1.0.2+wasi-0.2.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5"
-dependencies = [
- "wit-bindgen",
-]
-
-[[package]]
-name = "wasip3"
-version = "0.4.0+wasi-0.3.0-rc-2026-01-06"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5"
-dependencies = [
- "wit-bindgen",
-]
-
-[[package]]
-name = "wasm-bindgen"
-version = "0.2.117"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0551fc1bb415591e3372d0bc4780db7e587d84e2a7e79da121051c5c4b89d0b0"
-dependencies = [
- "cfg-if",
- "once_cell",
- "rustversion",
- "wasm-bindgen-macro",
- "wasm-bindgen-shared",
-]
-
-[[package]]
-name = "wasm-bindgen-macro"
-version = "0.2.117"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fbdf9a35adf44786aecd5ff89b4563a90325f9da0923236f6104e603c7e86be"
-dependencies = [
- "quote",
- "wasm-bindgen-macro-support",
-]
-
-[[package]]
-name = "wasm-bindgen-macro-support"
-version = "0.2.117"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dca9693ef2bab6d4e6707234500350d8dad079eb508dca05530c85dc3a529ff2"
-dependencies = [
- "bumpalo",
- "proc-macro2",
- "quote",
- "syn 2.0.117",
- "wasm-bindgen-shared",
-]
-
-[[package]]
-name = "wasm-bindgen-shared"
-version = "0.2.117"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "39129a682a6d2d841b6c429d0c51e5cb0ed1a03829d8b3d1e69a011e62cb3d3b"
-dependencies = [
- "unicode-ident",
-]
-
-[[package]]
-name = "wasm-encoder"
-version = "0.244.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319"
-dependencies = [
- "leb128fmt",
- "wasmparser",
-]
-
-[[package]]
-name = "wasm-metadata"
-version = "0.244.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909"
-dependencies = [
- "anyhow",
- "indexmap 2.13.1",
- "wasm-encoder",
- "wasmparser",
-]
-
-[[package]]
-name = "wasmparser"
-version = "0.244.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe"
-dependencies = [
- "bitflags 2.11.0",
- "hashbrown 0.15.5",
- "indexmap 2.13.1",
- "semver",
-]
-
-[[package]]
-name = "web-time"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"
-dependencies = [
- "js-sys",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "webpki-root-certs"
-version = "1.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "804f18a4ac2676ffb4e8b5b5fa9ae38af06df08162314f96a68d2a363e21a8ca"
-dependencies = [
- "rustls-pki-types",
-]
-
-[[package]]
-name = "webpki-roots"
-version = "1.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed"
-dependencies = [
- "rustls-pki-types",
-]
-
-[[package]]
-name = "winapi"
-version = "0.3.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
-dependencies = [
- "winapi-i686-pc-windows-gnu",
- "winapi-x86_64-pc-windows-gnu",
-]
-
-[[package]]
-name = "winapi-i686-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
-
-[[package]]
-name = "winapi-util"
-version = "0.1.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
-dependencies = [
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "winapi-x86_64-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
-
-[[package]]
-name = "windows-core"
-version = "0.62.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
-dependencies = [
- "windows-implement",
- "windows-interface",
- "windows-link",
- "windows-result",
- "windows-strings",
-]
-
-[[package]]
-name = "windows-implement"
-version = "0.60.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.117",
-]
-
-[[package]]
-name = "windows-interface"
-version = "0.59.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.117",
-]
-
-[[package]]
-name = "windows-link"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
-
-[[package]]
-name = "windows-result"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
-dependencies = [
- "windows-link",
-]
-
-[[package]]
-name = "windows-strings"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
-dependencies = [
- "windows-link",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.45.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
-dependencies = [
- "windows-targets 0.42.2",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.52.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
-dependencies = [
- "windows-targets 0.52.6",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.60.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
-dependencies = [
- "windows-targets 0.53.5",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.61.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
-dependencies = [
- "windows-link",
-]
-
-[[package]]
-name = "windows-targets"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
-dependencies = [
- "windows_aarch64_gnullvm 0.42.2",
- "windows_aarch64_msvc 0.42.2",
- "windows_i686_gnu 0.42.2",
- "windows_i686_msvc 0.42.2",
- "windows_x86_64_gnu 0.42.2",
- "windows_x86_64_gnullvm 0.42.2",
- "windows_x86_64_msvc 0.42.2",
-]
-
-[[package]]
-name = "windows-targets"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
-dependencies = [
- "windows_aarch64_gnullvm 0.52.6",
- "windows_aarch64_msvc 0.52.6",
- "windows_i686_gnu 0.52.6",
- "windows_i686_gnullvm 0.52.6",
- "windows_i686_msvc 0.52.6",
- "windows_x86_64_gnu 0.52.6",
- "windows_x86_64_gnullvm 0.52.6",
- "windows_x86_64_msvc 0.52.6",
-]
-
-[[package]]
-name = "windows-targets"
-version = "0.53.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3"
-dependencies = [
- "windows-link",
- "windows_aarch64_gnullvm 0.53.1",
- "windows_aarch64_msvc 0.53.1",
- "windows_i686_gnu 0.53.1",
- "windows_i686_gnullvm 0.53.1",
- "windows_i686_msvc 0.53.1",
- "windows_x86_64_gnu 0.53.1",
- "windows_x86_64_gnullvm 0.53.1",
- "windows_x86_64_msvc 0.53.1",
-]
-
-[[package]]
-name = "windows_aarch64_gnullvm"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
-
-[[package]]
-name = "windows_aarch64_gnullvm"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
-
-[[package]]
-name = "windows_aarch64_gnullvm"
-version = "0.53.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53"
-
-[[package]]
-name = "windows_aarch64_msvc"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
-
-[[package]]
-name = "windows_aarch64_msvc"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
-
-[[package]]
-name = "windows_aarch64_msvc"
-version = "0.53.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"
-
-[[package]]
-name = "windows_i686_gnu"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
-
-[[package]]
-name = "windows_i686_gnu"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
-
-[[package]]
-name = "windows_i686_gnu"
-version = "0.53.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3"
-
-[[package]]
-name = "windows_i686_gnullvm"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
-
-[[package]]
-name = "windows_i686_gnullvm"
-version = "0.53.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"
-
-[[package]]
-name = "windows_i686_msvc"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
-
-[[package]]
-name = "windows_i686_msvc"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
-
-[[package]]
-name = "windows_i686_msvc"
-version = "0.53.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"
-
-[[package]]
-name = "windows_x86_64_gnu"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
-
-[[package]]
-name = "windows_x86_64_gnu"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
-
-[[package]]
-name = "windows_x86_64_gnu"
-version = "0.53.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"
-
-[[package]]
-name = "windows_x86_64_gnullvm"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
-
-[[package]]
-name = "windows_x86_64_gnullvm"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
-
-[[package]]
-name = "windows_x86_64_gnullvm"
-version = "0.53.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1"
-
-[[package]]
-name = "windows_x86_64_msvc"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
-
-[[package]]
-name = "windows_x86_64_msvc"
-version = "0.52.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
-
-[[package]]
-name = "windows_x86_64_msvc"
-version = "0.53.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
-
-[[package]]
-name = "winnow"
-version = "0.7.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945"
-
-[[package]]
-name = "winnow"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09dac053f1cd375980747450bfc7250c264eaae0583872e845c0c7cd578872b5"
-dependencies = [
- "memchr",
-]
-
-[[package]]
-name = "wit-bindgen"
-version = "0.51.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
-dependencies = [
- "wit-bindgen-rust-macro",
-]
-
-[[package]]
-name = "wit-bindgen-core"
-version = "0.51.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc"
-dependencies = [
- "anyhow",
- "heck",
- "wit-parser",
-]
-
-[[package]]
-name = "wit-bindgen-rust"
-version = "0.51.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21"
-dependencies = [
- "anyhow",
- "heck",
- "indexmap 2.13.1",
- "prettyplease",
- "syn 2.0.117",
- "wasm-metadata",
- "wit-bindgen-core",
- "wit-component",
-]
-
-[[package]]
-name = "wit-bindgen-rust-macro"
-version = "0.51.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a"
-dependencies = [
- "anyhow",
- "prettyplease",
- "proc-macro2",
- "quote",
- "syn 2.0.117",
- "wit-bindgen-core",
- "wit-bindgen-rust",
-]
-
-[[package]]
-name = "wit-component"
-version = "0.244.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2"
-dependencies = [
- "anyhow",
- "bitflags 2.11.0",
- "indexmap 2.13.1",
- "log",
- "serde",
- "serde_derive",
- "serde_json",
- "wasm-encoder",
- "wasm-metadata",
- "wasmparser",
- "wit-parser",
-]
-
-[[package]]
-name = "wit-parser"
-version = "0.244.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736"
-dependencies = [
- "anyhow",
- "id-arena",
- "indexmap 2.13.1",
- "log",
- "semver",
- "serde",
- "serde_derive",
- "serde_json",
- "unicode-xid",
- "wasmparser",
-]
-
-[[package]]
-name = "writeable"
-version = "0.6.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4"
-
-[[package]]
-name = "x509-parser"
-version = "0.18.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d43b0f71ce057da06bc0851b23ee24f3f86190b07203dd8f567d0b706a185202"
-dependencies = [
- "asn1-rs",
- "data-encoding",
- "der-parser",
- "lazy_static",
- "nom",
- "oid-registry",
- "ring",
- "rusticata-macros",
- "thiserror 2.0.18",
- "time",
-]
-
-[[package]]
-name = "yasna"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd"
-dependencies = [
- "time",
-]
-
-[[package]]
-name = "yoke"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca"
-dependencies = [
- "stable_deref_trait",
- "yoke-derive",
- "zerofrom",
-]
-
-[[package]]
-name = "yoke-derive"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.117",
- "synstructure",
-]
-
-[[package]]
-name = "zenoh"
-version = "1.9.0"
-source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#ec8b19786aced876d9dd64891359d6b2500d9a9b"
-dependencies = [
- "ahash",
- "arc-swap",
- "async-trait",
- "bytes",
- "const_format",
- "flate2",
- "flume 0.11.1",
- "futures",
- "git-version",
- "itertools",
- "json5",
- "lazy_static",
- "nonempty-collections",
- "once_cell",
- "petgraph",
- "phf",
- "rand 0.8.5",
- "rustc_version",
- "serde",
- "serde_json",
- "socket2 0.5.10",
- "tokio",
- "tokio-util",
- "tracing",
- "uhlc",
- "vec_map",
- "zenoh-buffers",
- "zenoh-codec",
- "zenoh-collections",
- "zenoh-config",
- "zenoh-core",
- "zenoh-keyexpr",
- "zenoh-link",
- "zenoh-link-commons",
- "zenoh-macros",
- "zenoh-plugin-trait",
- "zenoh-protocol",
- "zenoh-result",
- "zenoh-runtime",
- "zenoh-sync",
- "zenoh-task",
- "zenoh-transport",
- "zenoh-util",
-]
-
-[[package]]
-name = "zenoh-buffers"
-version = "1.9.0"
-source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#ec8b19786aced876d9dd64891359d6b2500d9a9b"
-dependencies = [
- "zenoh-collections",
-]
-
-[[package]]
-name = "zenoh-codec"
-version = "1.9.0"
-source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#ec8b19786aced876d9dd64891359d6b2500d9a9b"
-dependencies = [
- "tracing",
- "uhlc",
- "zenoh-buffers",
- "zenoh-protocol",
-]
-
-[[package]]
-name = "zenoh-collections"
-version = "1.9.0"
-source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#ec8b19786aced876d9dd64891359d6b2500d9a9b"
-dependencies = [
- "ahash",
-]
-
-[[package]]
-name = "zenoh-config"
-version = "1.9.0"
-source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#ec8b19786aced876d9dd64891359d6b2500d9a9b"
-dependencies = [
- "json5",
- "nonempty-collections",
- "num_cpus",
- "secrecy",
- "serde",
- "serde_json",
- "serde_with",
- "serde_yaml",
- "toml",
- "tracing",
- "uhlc",
- "validated_struct",
- "zenoh-core",
- "zenoh-keyexpr",
- "zenoh-macros",
- "zenoh-protocol",
- "zenoh-result",
- "zenoh-util",
-]
-
-[[package]]
-name = "zenoh-core"
-version = "1.9.0"
-source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#ec8b19786aced876d9dd64891359d6b2500d9a9b"
-dependencies = [
- "lazy_static",
- "tokio",
- "zenoh-result",
- "zenoh-runtime",
-]
-
-[[package]]
-name = "zenoh-crypto"
-version = "1.9.0"
-source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#ec8b19786aced876d9dd64891359d6b2500d9a9b"
-dependencies = [
- "aes",
- "hmac",
- "rand 0.8.5",
- "rand_chacha 0.3.1",
- "sha3",
- "zenoh-result",
-]
-
-[[package]]
-name = "zenoh-ext"
-version = "1.9.0"
-source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#ec8b19786aced876d9dd64891359d6b2500d9a9b"
-dependencies = [
- "async-trait",
- "bincode",
- "flume 0.11.1",
- "futures",
- "leb128",
- "serde",
- "tokio",
- "tracing",
- "uhlc",
- "zenoh",
- "zenoh-macros",
- "zenoh-util",
-]
-
-[[package]]
-name = "zenoh-keyexpr"
-version = "1.9.0"
-source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#ec8b19786aced876d9dd64891359d6b2500d9a9b"
-dependencies = [
- "getrandom 0.2.17",
- "hashbrown 0.16.1",
- "keyed-set",
- "rand 0.8.5",
- "schemars 1.2.1",
- "serde",
- "token-cell",
- "zenoh-result",
-]
-
-[[package]]
-name = "zenoh-link"
-version = "1.9.0"
-source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#ec8b19786aced876d9dd64891359d6b2500d9a9b"
-dependencies = [
- "zenoh-config",
- "zenoh-link-commons",
- "zenoh-link-quic",
- "zenoh-link-quic_datagram",
- "zenoh-link-tcp",
- "zenoh-link-tls",
- "zenoh-link-udp",
- "zenoh-link-unixsock_stream",
- "zenoh-link-ws",
- "zenoh-protocol",
- "zenoh-result",
-]
-
-[[package]]
-name = "zenoh-link-commons"
-version = "1.9.0"
-source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#ec8b19786aced876d9dd64891359d6b2500d9a9b"
-dependencies = [
- "async-trait",
- "base64",
- "bytes",
- "flume 0.11.1",
- "futures",
- "quinn",
- "quinn-proto",
- "rcgen",
- "rustls",
- "rustls-pemfile",
- "rustls-pki-types",
- "rustls-webpki",
- "secrecy",
- "serde",
- "socket2 0.5.10",
- "time",
- "tokio",
- "tokio-util",
- "tracing",
- "webpki-roots",
- "x509-parser",
- "zenoh-buffers",
- "zenoh-codec",
- "zenoh-config",
- "zenoh-core",
- "zenoh-protocol",
- "zenoh-result",
- "zenoh-runtime",
- "zenoh-util",
-]
-
-[[package]]
-name = "zenoh-link-quic"
-version = "1.9.0"
-source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#ec8b19786aced876d9dd64891359d6b2500d9a9b"
-dependencies = [
- "async-trait",
- "rustls-webpki",
- "time",
- "tracing",
- "zenoh-core",
- "zenoh-link-commons",
- "zenoh-link-quic_datagram",
- "zenoh-protocol",
- "zenoh-result",
-]
-
-[[package]]
-name = "zenoh-link-quic_datagram"
-version = "1.9.0"
-source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#ec8b19786aced876d9dd64891359d6b2500d9a9b"
-dependencies = [
- "async-trait",
- "rustls-webpki",
- "time",
- "tokio-util",
- "tracing",
- "zenoh-core",
- "zenoh-link-commons",
- "zenoh-protocol",
- "zenoh-result",
-]
-
-[[package]]
-name = "zenoh-link-tcp"
-version = "1.9.0"
-source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#ec8b19786aced876d9dd64891359d6b2500d9a9b"
-dependencies = [
- "async-trait",
- "socket2 0.5.10",
- "tokio",
- "tokio-util",
- "tracing",
- "zenoh-config",
- "zenoh-core",
- "zenoh-link-commons",
- "zenoh-protocol",
- "zenoh-result",
-]
-
-[[package]]
-name = "zenoh-link-tls"
-version = "1.9.0"
-source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#ec8b19786aced876d9dd64891359d6b2500d9a9b"
-dependencies = [
- "async-trait",
- "base64",
- "rustls",
- "rustls-pemfile",
- "rustls-pki-types",
- "rustls-webpki",
- "secrecy",
- "socket2 0.5.10",
- "time",
- "tls-listener",
- "tokio",
- "tokio-rustls",
- "tokio-util",
- "tracing",
- "webpki-roots",
- "x509-parser",
- "zenoh-config",
- "zenoh-core",
- "zenoh-link-commons",
- "zenoh-protocol",
- "zenoh-result",
- "zenoh-runtime",
-]
-
-[[package]]
-name = "zenoh-link-udp"
-version = "1.9.0"
-source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#ec8b19786aced876d9dd64891359d6b2500d9a9b"
-dependencies = [
- "async-trait",
- "libc",
- "socket2 0.5.10",
- "tokio",
- "tokio-util",
- "tracing",
- "windows-sys 0.61.2",
- "zenoh-buffers",
- "zenoh-core",
- "zenoh-link-commons",
- "zenoh-link-quic_datagram",
- "zenoh-protocol",
- "zenoh-result",
- "zenoh-sync",
- "zenoh-util",
-]
-
-[[package]]
-name = "zenoh-link-unixsock_stream"
-version = "1.9.0"
-source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#ec8b19786aced876d9dd64891359d6b2500d9a9b"
-dependencies = [
- "async-trait",
- "nix",
- "tokio",
- "tokio-util",
- "tracing",
- "uuid",
- "zenoh-core",
- "zenoh-link-commons",
- "zenoh-protocol",
- "zenoh-result",
- "zenoh-runtime",
-]
-
-[[package]]
-name = "zenoh-link-ws"
-version = "1.9.0"
-source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#ec8b19786aced876d9dd64891359d6b2500d9a9b"
-dependencies = [
- "async-trait",
- "futures-util",
- "tokio",
- "tokio-tungstenite",
- "tokio-util",
- "tracing",
- "url",
- "zenoh-core",
- "zenoh-link-commons",
- "zenoh-protocol",
- "zenoh-result",
- "zenoh-runtime",
- "zenoh-util",
-]
-
-[[package]]
-name = "zenoh-macros"
-version = "1.9.0"
-source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#ec8b19786aced876d9dd64891359d6b2500d9a9b"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.117",
- "zenoh-keyexpr",
-]
-
-[[package]]
-name = "zenoh-plugin-trait"
-version = "1.9.0"
-source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#ec8b19786aced876d9dd64891359d6b2500d9a9b"
-dependencies = [
- "git-version",
- "libloading",
- "serde",
- "stabby",
- "tracing",
- "zenoh-config",
- "zenoh-keyexpr",
- "zenoh-macros",
- "zenoh-result",
- "zenoh-util",
-]
-
-[[package]]
-name = "zenoh-protocol"
-version = "1.9.0"
-source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#ec8b19786aced876d9dd64891359d6b2500d9a9b"
-dependencies = [
- "const_format",
- "rand 0.8.5",
- "serde",
- "uhlc",
- "zenoh-buffers",
- "zenoh-keyexpr",
- "zenoh-macros",
- "zenoh-result",
-]
-
-[[package]]
-name = "zenoh-result"
-version = "1.9.0"
-source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#ec8b19786aced876d9dd64891359d6b2500d9a9b"
-dependencies = [
- "anyhow",
-]
-
-[[package]]
-name = "zenoh-runtime"
-version = "1.9.0"
-source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#ec8b19786aced876d9dd64891359d6b2500d9a9b"
-dependencies = [
- "lazy_static",
- "ron",
- "serde",
- "tokio",
- "tracing",
- "zenoh-macros",
- "zenoh-result",
-]
-
-[[package]]
-name = "zenoh-sync"
-version = "1.9.0"
-source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#ec8b19786aced876d9dd64891359d6b2500d9a9b"
-dependencies = [
- "arc-swap",
- "event-listener",
- "futures",
- "tokio",
- "zenoh-buffers",
- "zenoh-collections",
- "zenoh-core",
-]
-
-[[package]]
-name = "zenoh-task"
-version = "1.9.0"
-source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#ec8b19786aced876d9dd64891359d6b2500d9a9b"
-dependencies = [
- "futures",
- "tokio",
- "tokio-util",
- "tracing",
- "zenoh-core",
- "zenoh-runtime",
-]
-
-[[package]]
-name = "zenoh-transport"
-version = "1.9.0"
-source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#ec8b19786aced876d9dd64891359d6b2500d9a9b"
-dependencies = [
- "async-trait",
- "crossbeam-utils",
- "flume 0.11.1",
- "futures",
- "lazy_static",
- "lz4_flex",
- "rand 0.8.5",
- "ringbuffer-spsc",
- "rsa",
- "serde",
- "sha3",
- "tokio",
- "tokio-util",
- "tracing",
- "zenoh-buffers",
- "zenoh-codec",
- "zenoh-config",
- "zenoh-core",
- "zenoh-crypto",
- "zenoh-link",
- "zenoh-link-commons",
- "zenoh-protocol",
- "zenoh-result",
- "zenoh-runtime",
- "zenoh-sync",
- "zenoh-task",
- "zenoh-util",
-]
-
-[[package]]
-name = "zenoh-util"
-version = "1.9.0"
-source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#ec8b19786aced876d9dd64891359d6b2500d9a9b"
-dependencies = [
- "async-trait",
- "const_format",
- "flume 0.11.1",
- "home",
- "humantime",
- "lazy_static",
- "libc",
- "libloading",
- "pnet_datalink",
- "schemars 1.2.1",
- "serde",
- "serde_json",
- "shellexpand",
- "tokio",
- "tracing",
- "tracing-subscriber",
- "winapi",
- "zenoh-core",
- "zenoh-result",
-]
-
-[[package]]
-name = "zenoh_jni"
-version = "1.9.0"
-dependencies = [
- "android-logd-logger",
- "async-std",
- "clap",
- "flume 0.10.14",
- "jni",
- "json5",
- "rustc_version",
- "serde_yaml",
- "tracing",
- "uhlc",
- "zenoh",
- "zenoh-ext",
-]
-
-[[package]]
-name = "zerocopy"
-version = "0.8.48"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9"
-dependencies = [
- "zerocopy-derive",
-]
-
-[[package]]
-name = "zerocopy-derive"
-version = "0.8.48"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.117",
-]
-
-[[package]]
-name = "zerofrom"
-version = "0.1.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df"
-dependencies = [
- "zerofrom-derive",
-]
-
-[[package]]
-name = "zerofrom-derive"
-version = "0.1.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.117",
- "synstructure",
-]
-
-[[package]]
-name = "zeroize"
-version = "1.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"
-
-[[package]]
-name = "zerotrie"
-version = "0.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf"
-dependencies = [
- "displaydoc",
- "yoke",
- "zerofrom",
-]
-
-[[package]]
-name = "zerovec"
-version = "0.11.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239"
-dependencies = [
- "yoke",
- "zerofrom",
- "zerovec-derive",
-]
-
-[[package]]
-name = "zerovec-derive"
-version = "0.11.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.117",
-]
-
-[[package]]
-name = "zmij"
-version = "1.0.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
diff --git a/zenoh-jni/Cargo.toml b/zenoh-jni/Cargo.toml
deleted file mode 100644
index 9e0b70dd..00000000
--- a/zenoh-jni/Cargo.toml
+++ /dev/null
@@ -1,55 +0,0 @@
-#
-# Copyright (c) 2023 ZettaScale Technology
-#
-# This program and the accompanying materials are made available under the
-# terms of the Eclipse Public License 2.0 which is available at
-# http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-# which is available at https://www.apache.org/licenses/LICENSE-2.0.
-#
-# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-#
-# Contributors:
-# ZettaScale Zenoh Team,
-#
-
-[package]
-rust-version = "1.75.0"
-version = "1.9.0"
-repository = "https://github.com/eclipse-zenoh/zenoh"
-homepage = "http://zenoh.io"
-edition = "2021"
-license = "EPL-2.0 OR Apache-2.0"
-categories = ["network-programming"]
-description = "Zenoh: Zero Overhead Pub/sub, Store/Query and Compute."
-name = "zenoh_jni"
-
-[features]
-default = ["zenoh/default", "zenoh-ext"]
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-[dependencies]
-android-logd-logger = "0.4.0"
-async-std = { version = "=1.12.0", default-features = false }
-clap = "3.2.23"
-jni = "0.21.1"
-flume = "0.10.14"
-uhlc = "0.8.0"
-json5 = "0.4.1"
-serde_yaml = "0.9.19"
-zenoh = { version = "1.9.0", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["unstable", "internal"], default-features = false }
-zenoh-ext = { version = "1.9.0", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["unstable", "internal"], default-features = false, optional = true }
-tracing = { version = "0.1" , features = ["log"] }
-
-[lib]
-name = "zenoh_jni"
-crate-type = ["staticlib", "dylib"]
-
-[build-dependencies]
-rustc_version = "0.4.0"
-
-[profile.release]
-debug = false # If you want debug symbol in release mode, set the env variable: RUSTFLAGS=-g
-lto = "fat"
-codegen-units = 1
-opt-level = 3
-panic = "abort"
diff --git a/zenoh-jni/src/config.rs b/zenoh-jni/src/config.rs
deleted file mode 100644
index 0ada1340..00000000
--- a/zenoh-jni/src/config.rs
+++ /dev/null
@@ -1,185 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-use std::{ptr::null, sync::Arc};
-
-use jni::{
- objects::{JClass, JString},
- sys::jstring,
- JNIEnv,
-};
-use zenoh::Config;
-
-use crate::{errors::ZResult, zerror};
-use crate::{throw_exception, utils::decode_string};
-
-/// Loads the default configuration, returning a raw pointer to it.
-///
-/// The pointer to the config is expected to be freed later on upon the destruction of the
-/// Kotlin Config instance.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub extern "C" fn Java_io_zenoh_jni_JNIConfig_00024Companion_loadDefaultConfigViaJNI(
- _env: JNIEnv,
- _class: JClass,
-) -> *const Config {
- let config = Config::default();
- Arc::into_raw(Arc::new(config))
-}
-
-/// Loads the config from a file, returning a pointer to the loaded config in case of success.
-/// In case of failure, an exception is thrown via JNI.
-///
-/// The pointer to the config is expected to be freed later on upon the destruction of the
-/// Kotlin Config instance.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub extern "C" fn Java_io_zenoh_jni_JNIConfig_00024Companion_loadConfigFileViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- config_path: JString,
-) -> *const Config {
- || -> ZResult<*const Config> {
- let config_file_path = decode_string(&mut env, &config_path)?;
- let config = Config::from_file(config_file_path).map_err(|err| zerror!(err))?;
- Ok(Arc::into_raw(Arc::new(config)))
- }()
- .unwrap_or_else(|err| {
- throw_exception!(env, err);
- null()
- })
-}
-
-/// Loads the config from a json/json5 formatted string, returning a pointer to the loaded config
-/// in case of success. In case of failure, an exception is thrown via JNI.
-///
-/// The pointer to the config is expected to be freed later on upon the destruction of the
-/// Kotlin Config instance.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub extern "C" fn Java_io_zenoh_jni_JNIConfig_00024Companion_loadJsonConfigViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- json_config: JString,
-) -> *const Config {
- || -> ZResult<*const Config> {
- let json_config = decode_string(&mut env, &json_config)?;
- let mut deserializer =
- json5::Deserializer::from_str(&json_config).map_err(|err| zerror!(err))?;
- let config = Config::from_deserializer(&mut deserializer).map_err(|err| match err {
- Ok(c) => zerror!("Invalid configuration: {}", c),
- Err(e) => zerror!("JSON error: {}", e),
- })?;
- Ok(Arc::into_raw(Arc::new(config)))
- }()
- .unwrap_or_else(|err| {
- throw_exception!(env, err);
- null()
- })
-}
-
-/// Loads the config from a yaml-formatted string, returning a pointer to the loaded config
-/// in case of success. In case of failure, an exception is thrown via JNI.
-///
-/// The pointer to the config is expected to be freed later on upon the destruction of the
-/// Kotlin Config instance.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub extern "C" fn Java_io_zenoh_jni_JNIConfig_00024Companion_loadYamlConfigViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- yaml_config: JString,
-) -> *const Config {
- || -> ZResult<*const Config> {
- let yaml_config = decode_string(&mut env, &yaml_config)?;
- let deserializer = serde_yaml::Deserializer::from_str(&yaml_config);
- let config = Config::from_deserializer(deserializer).map_err(|err| match err {
- Ok(c) => zerror!("Invalid configuration: {}", c),
- Err(e) => zerror!("YAML error: {}", e),
- })?;
- Ok(Arc::into_raw(Arc::new(config)))
- }()
- .unwrap_or_else(|err| {
- throw_exception!(env, err);
- null()
- })
-}
-
-/// Returns the json value associated to the provided [key]. May throw an exception in case of failure, which must be handled
-/// on the kotlin layer.
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNIConfig_00024Companion_getJsonViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- cfg_ptr: *const Config,
- key: JString,
-) -> jstring {
- let arc_cfg: Arc = Arc::from_raw(cfg_ptr);
- let result = || -> ZResult {
- let key = decode_string(&mut env, &key)?;
- let json = arc_cfg.get_json(&key).map_err(|err| zerror!(err))?;
- let java_json = env.new_string(json).map_err(|err| zerror!(err))?;
- Ok(java_json.as_raw())
- }()
- .unwrap_or_else(|err| {
- throw_exception!(env, err);
- JString::default().as_raw()
- });
- std::mem::forget(arc_cfg);
- result
-}
-
-/// Inserts a json5 value associated to the provided [key]. May throw an exception in case of failure, which must be handled
-/// on the kotlin layer.
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNIConfig_00024Companion_insertJson5ViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- cfg_ptr: *const Config,
- key: JString,
- value: JString,
-) {
- || -> ZResult<()> {
- let key = decode_string(&mut env, &key)?;
- let value = decode_string(&mut env, &value)?;
- let mut config = core::ptr::read(cfg_ptr);
- let insert_result = config
- .insert_json5(&key, &value)
- .map_err(|err| zerror!(err));
- core::ptr::write(cfg_ptr as *mut _, config);
- insert_result
- }()
- .unwrap_or_else(|err| {
- throw_exception!(env, err);
- })
-}
-
-/// Frees the pointer to the config. The pointer should be valid and should have been obtained through
-/// one of the preceding `load` functions. This function should be called upon destruction of the kotlin
-/// Config instance.
-#[no_mangle]
-#[allow(non_snake_case)]
-pub(crate) unsafe extern "C" fn Java_io_zenoh_jni_JNIConfig_00024Companion_freePtrViaJNI(
- _env: JNIEnv,
- _: JClass,
- config_ptr: *const Config,
-) {
- Arc::from_raw(config_ptr);
-}
diff --git a/zenoh-jni/src/errors.rs b/zenoh-jni/src/errors.rs
deleted file mode 100644
index 23687d4c..00000000
--- a/zenoh-jni/src/errors.rs
+++ /dev/null
@@ -1,59 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-use std::fmt;
-
-use jni::JNIEnv;
-
-#[macro_export]
-macro_rules! throw_exception {
- ($env:expr, $err:expr) => {{
- let _ = $err.throw_on_jvm(&mut $env).map_err(|err| {
- tracing::error!("Unable to throw exception: {}", err);
- });
- }};
-}
-
-#[macro_export]
-macro_rules! zerror {
- ($arg:expr) => {
- $crate::errors::ZError($arg.to_string())
- };
- ($fmt:expr, $($arg:tt)*) => {
- $crate::errors::ZError(format!($fmt, $($arg)*))
- };
-}
-
-pub(crate) type ZResult = core::result::Result;
-
-#[derive(Debug)]
-pub(crate) struct ZError(pub String);
-
-impl fmt::Display for ZError {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "{}", self.0)
- }
-}
-
-impl ZError {
- const KOTLIN_EXCEPTION_NAME: &'static str = "io/zenoh/exceptions/ZError";
-
- pub fn throw_on_jvm(&self, env: &mut JNIEnv) -> ZResult<()> {
- let exception_class = env
- .find_class(Self::KOTLIN_EXCEPTION_NAME)
- .map_err(|err| zerror!("Failed to retrieve exception class: {}", err))?;
- env.throw_new(exception_class, self.to_string())
- .map_err(|err| zerror!("Failed to throw exception: {}", err))
- }
-}
diff --git a/zenoh-jni/src/ext/advanced_publisher.rs b/zenoh-jni/src/ext/advanced_publisher.rs
deleted file mode 100644
index d0a51e36..00000000
--- a/zenoh-jni/src/ext/advanced_publisher.rs
+++ /dev/null
@@ -1,339 +0,0 @@
-//
-// Copyright (c) 2025 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-use std::sync::Arc;
-
-use jni::objects::JValue;
-use jni::{
- objects::{JByteArray, JClass, JString},
- sys::jint,
- JNIEnv,
-};
-use zenoh::handlers::{Callback, DefaultHandler};
-use zenoh::Wait;
-use zenoh_ext::AdvancedPublisher;
-
-use crate::owned_object::OwnedObject;
-use crate::utils::{get_callback_global_ref, get_java_vm, load_on_close};
-
-use crate::throw_exception;
-use crate::{
- errors::ZResult,
- utils::{decode_byte_array, decode_encoding},
- zerror,
-};
-use jni::sys::jboolean;
-use std::ptr::null;
-
-use jni::objects::JObject;
-use zenoh::matching::{MatchingListener, MatchingListenerBuilder, MatchingStatus};
-
-trait SetJniMatchingStatusCallback {
- type WithCallback;
-
- unsafe fn set_jni_matching_status_callback(
- self,
- env: &mut JNIEnv,
- callback: JObject,
- on_close: JObject,
- ) -> ZResult;
-}
-
-impl<'a> SetJniMatchingStatusCallback for MatchingListenerBuilder<'a, DefaultHandler> {
- type WithCallback = MatchingListenerBuilder<'a, Callback>;
-
- unsafe fn set_jni_matching_status_callback(
- self,
- env: &mut JNIEnv,
- callback: JObject,
- on_close: JObject,
- ) -> ZResult {
- let java_vm = Arc::new(get_java_vm(env)?);
- let callback_global_ref = get_callback_global_ref(env, callback)?;
- let on_close_global_ref = get_callback_global_ref(env, on_close)?;
- let on_close = load_on_close(&java_vm, on_close_global_ref);
-
- let builder = self.callback(move |matching_status| {
- on_close.noop(); // Moves `on_close` inside the closure so it gets destroyed with the closure
- let _ = || -> ZResult<()> {
- let mut env = java_vm.attach_current_thread_as_daemon().map_err(|err| {
- zerror!("Unable to attach thread for matching listener: {}", err)
- })?;
-
- env.call_method(
- &callback_global_ref,
- "run",
- "(Z)V",
- &[JValue::from(matching_status.matching())],
- )
- .map_err(|err| zerror!(err))?;
- Ok(())
- }()
- .map_err(|err| tracing::error!("On matching listener callback error: {err}"));
- });
- Ok(builder)
- }
-}
-
-/// Declare a MatchingListener for [AdvancedPublisher] via JNI.
-///
-/// Parameters:
-/// - `env`: The JNI environment.
-/// - `_class`: The JNI class.
-/// - `advanced_publisher_ptr`: The raw pointer to an [AdvancedPublisher].
-/// - `callback`: The callback function as an instance of the `JNIMatchingListenerCallback` interface in Java/Kotlin.
-/// - `on_close`: A Java/Kotlin `JNIOnCloseCallback` function interface to be called upon undeclaring the [MatchingListener].
-///
-/// Returns:
-/// - A raw pointer to the declared [MatchingListener]. In case of failure, an exception is thrown and null is returned.
-///
-/// Safety:
-/// - The function is marked as unsafe due to raw pointer manipulation and JNI interaction.
-/// - It assumes that the provided [AdvancedPublisher] pointer is valid and has not been modified or freed.
-/// - The [AdvancedPublisher] pointer remains valid and the ownership of the [AdvancedPublisher] is not transferred,
-/// allowing safe usage of the [AdvancedPublisher] after this function call.
-/// - The callback function passed as `callback` must be a valid instance of the `JNIMatchingListenerCallback` interface
-/// in Java/Kotlin, matching the specified signature.
-/// - The function may throw a JNI exception in case of failure, which should be handled by the caller.
-///
-#[cfg(feature = "zenoh-ext")]
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNIAdvancedPublisher_declareMatchingListenerViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- advanced_publisher_ptr: *const AdvancedPublisher,
-
- callback: JObject,
- on_close: JObject,
-) -> *const MatchingListener<()> {
- let advanced_publisher = OwnedObject::from_raw(advanced_publisher_ptr);
-
- || -> ZResult<*const MatchingListener<()>> {
- tracing::debug!(
- "Declaring matching listener on '{}'...",
- advanced_publisher.key_expr()
- );
-
- let matching_listener = advanced_publisher
- .matching_listener()
- .set_jni_matching_status_callback(&mut env, callback, on_close)?
- .wait()
- .map_err(|err| zerror!("Unable to declare matching listener: {}", err))?;
-
- tracing::debug!(
- "Matching listener declared on '{}'...",
- advanced_publisher.key_expr()
- );
- Ok(Arc::into_raw(Arc::new(matching_listener)))
- }()
- .unwrap_or_else(|err| {
- throw_exception!(env, err);
- null()
- })
-}
-
-/// Declare a background matching listener for [AdvancedPublisher] via JNI.
-/// Register the listener callback to be run in background until the [AdvancedPublisher] is undeclared.
-///
-/// Parameters:
-/// - `env`: The JNI environment.
-/// - `_class`: The JNI class.
-/// - `advanced_publisher_ptr`: The raw pointer to an [AdvancedPublisher].
-/// - `callback`: The callback function as an instance of the `JNIMatchingListenerCallback` interface in Java/Kotlin.
-/// - `on_close`: A Java/Kotlin `JNIOnCloseCallback` function interface to be called upon undeclaring the [AdvancedPublisher].
-///
-/// Safety:
-/// - The function is marked as unsafe due to raw pointer manipulation and JNI interaction.
-/// - It assumes that the provided [AdvancedPublisher] pointer is valid and has not been modified or freed.
-/// - The [AdvancedPublisher] pointer remains valid and the ownership of the [AdvancedPublisher] is not transferred,
-/// allowing safe usage of the [AdvancedPublisher] after this function call.
-/// - The callback function passed as `callback` must be a valid instance of the `JNIMatchingListenerCallback` interface
-/// in Java/Kotlin, matching the specified signature.
-/// - The function may throw a JNI exception in case of failure, which should be handled by the caller.
-///
-#[cfg(feature = "zenoh-ext")]
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNIAdvancedPublisher_declareBackgroundMatchingListenerViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- advanced_publisher_ptr: *const AdvancedPublisher,
-
- callback: JObject,
- on_close: JObject,
-) {
- let advanced_publisher = OwnedObject::from_raw(advanced_publisher_ptr);
-
- || -> ZResult<()> {
- tracing::debug!(
- "Declaring background matching listener on '{}'...",
- advanced_publisher.key_expr()
- );
-
- advanced_publisher
- .matching_listener()
- .set_jni_matching_status_callback(&mut env, callback, on_close)?
- .background()
- .wait()
- .map_err(|err| zerror!("Unable to declare background matching listener: {}", err))?;
-
- tracing::debug!(
- "Background matching listener declared on '{}'...",
- advanced_publisher.key_expr()
- );
- Ok(())
- }()
- .unwrap_or_else(|err| {
- throw_exception!(env, err);
- });
-}
-
-/// Return the matching status of the [AdvancedPublisher].
-///
-/// Parameters:
-/// - `env`: The JNI environment.
-/// - `_class`: The JNI class.
-/// - `advanced_publisher_ptr`: The raw pointer to an [AdvancedPublisher].
-///
-/// Returns:
-/// - will return true if there exist Subscribers matching the Publisher's key expression and false otherwise.
-///
-/// Safety:
-/// - The function is marked as unsafe due to raw pointer manipulation and JNI interaction.
-/// - It assumes that the provided [AdvancedPublisher] pointer is valid and has not been modified or freed.
-/// - The [AdvancedPublisher] pointer remains valid and the ownership of the [AdvancedPublisher] is not transferred,
-/// allowing safe usage of the [AdvancedPublisher] after this function call.
-/// - The function may throw a JNI exception in case of failure, which should be handled by the caller.
-///
-#[cfg(feature = "zenoh-ext")]
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNIAdvancedPublisher_getMatchingStatusViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- advanced_publisher_ptr: *const AdvancedPublisher,
-) -> jboolean {
- use crate::errors::ZError;
-
- let advanced_publisher = OwnedObject::from_raw(advanced_publisher_ptr);
- advanced_publisher
- .matching_status()
- .wait()
- .map(|val| val.matching() as jboolean)
- .map_err(|e| zerror!(e.to_string()))
- .unwrap_or_else(|err: ZError| {
- throw_exception!(env, err);
- false as jboolean
- })
-}
-
-/// Performs a PUT operation on an [AdvancedPublisher] via JNI.
-///
-/// # Parameters
-/// - `env`: The JNI environment pointer.
-/// - `_class`: The Java class reference (unused).
-/// - `payload`: The byte array to be published.
-/// - `encoding_id`: The encoding ID of the payload.
-/// - `encoding_schema`: Nullable encoding schema string of the payload.
-/// - `attachment`: Nullble byte array for the attachment.
-/// - `publisher_ptr`: The raw pointer to the [AdvancedPublisher].
-///
-/// # Safety
-/// - This function is marked as unsafe due to raw pointer manipulation and JNI interaction.
-/// - Assumes that the provided [AdvancedPublisher] pointer is valid and has not been modified or freed.
-/// - The [AdvancedPublisher] pointer remains valid after this function call.
-/// - May throw an exception in case of failure, which must be handled by the caller.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNIAdvancedPublisher_putViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- payload: JByteArray,
- encoding_id: jint,
- encoding_schema: /*nullable*/ JString,
- attachment: /*nullable*/ JByteArray,
- publisher_ptr: *const AdvancedPublisher<'static>,
-) {
- let publisher = OwnedObject::from_raw(publisher_ptr);
- let _ = || -> ZResult<()> {
- let payload = decode_byte_array(&env, payload)?;
- let mut publication = publisher.put(payload);
- let encoding = decode_encoding(&mut env, encoding_id, &encoding_schema)?;
- publication = publication.encoding(encoding);
- if !attachment.is_null() {
- let attachment = decode_byte_array(&env, attachment)?;
- publication = publication.attachment::>(attachment)
- };
- publication.wait().map_err(|err| zerror!(err))
- }()
- .map_err(|err| throw_exception!(env, err));
-}
-
-/// Performs a DELETE operation on an [AdvancedPublisher] via JNI.
-///
-/// # Parameters
-/// - `env`: The JNI environment pointer.
-/// - `_class`: The Java class reference (unused).
-/// - `attachment`: Nullble byte array for the attachment.
-/// - `publisher_ptr`: The raw pointer to the [AdvancedPublisher].
-///
-/// # Safety
-/// - This function is marked as unsafe due to raw pointer manipulation and JNI interaction.
-/// - Assumes that the provided [AdvancedPublisher] pointer is valid and has not been modified or freed.
-/// - The [AdvancedPublisher] pointer remains valid after this function call.
-/// - May throw an exception in case of failure, which must be handled by the caller.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNIAdvancedPublisher_deleteViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- attachment: /*nullable*/ JByteArray,
- publisher_ptr: *const AdvancedPublisher<'static>,
-) {
- let publisher = OwnedObject::from_raw(publisher_ptr);
- let _ = || -> ZResult<()> {
- let mut delete = publisher.delete();
- if !attachment.is_null() {
- let attachment = decode_byte_array(&env, attachment)?;
- delete = delete.attachment::>(attachment)
- };
- delete.wait().map_err(|err| zerror!(err))
- }()
- .map_err(|err| throw_exception!(env, err));
-}
-
-/// Frees the [AdvancedPublisher].
-///
-/// # Parameters:
-/// - `_env`: The JNI environment.
-/// - `_class`: The JNI class.
-/// - `publisher_ptr`: The raw pointer to the [AdvancedPublisher].
-///
-/// # Safety:
-/// - The function is marked as unsafe due to raw pointer manipulation.
-/// - It assumes that the provided [AdvancedPublisher] pointer is valid and has not been modified or freed.
-/// - After calling this function, the [AdvancedPublisher] pointer becomes invalid and should not be used anymore.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub(crate) unsafe extern "C" fn Java_io_zenoh_jni_JNIAdvancedPublisher_freePtrViaJNI(
- _env: JNIEnv,
- _: JClass,
- publisher_ptr: *const AdvancedPublisher,
-) {
- Arc::from_raw(publisher_ptr);
-}
diff --git a/zenoh-jni/src/ext/advanced_subscriber.rs b/zenoh-jni/src/ext/advanced_subscriber.rs
deleted file mode 100644
index 532c84e8..00000000
--- a/zenoh-jni/src/ext/advanced_subscriber.rs
+++ /dev/null
@@ -1,359 +0,0 @@
-//
-// Copyright (c) 2025 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-use std::sync::Arc;
-
-use jni::sys::jboolean;
-use jni::{objects::JClass, JNIEnv};
-use zenoh::handlers::{Callback, DefaultHandler};
-use zenoh::pubsub::Subscriber;
-use zenoh_ext::SampleMissListener;
-use zenoh_ext::{AdvancedSubscriber, Miss, SampleMissListenerBuilder};
-
-use crate::sample_callback::SetJniSampleCallback;
-use jni::objects::JObject;
-
-use crate::errors::ZResult;
-use jni::objects::JValue;
-use zenoh::Wait;
-
-use crate::owned_object::OwnedObject;
-
-use crate::utils::{get_callback_global_ref, get_java_vm, load_on_close};
-use crate::zerror;
-use std::ptr::null;
-
-use crate::throw_exception;
-
-trait SetJniSampleMissListenerCallback {
- type WithCallback;
-
- unsafe fn set_jni_sample_miss_callback(
- self,
- env: &mut JNIEnv,
- callback: JObject,
- on_close: JObject,
- ) -> ZResult;
-}
-
-impl<'a> SetJniSampleMissListenerCallback for SampleMissListenerBuilder<'a, DefaultHandler> {
- type WithCallback = SampleMissListenerBuilder<'a, Callback>;
-
- unsafe fn set_jni_sample_miss_callback(
- self,
- env: &mut JNIEnv,
- callback: JObject,
- on_close: JObject,
- ) -> ZResult {
- let java_vm = Arc::new(get_java_vm(env)?);
- let callback_global_ref = get_callback_global_ref(env, callback)?;
- let on_close_global_ref = get_callback_global_ref(env, on_close)?;
- let on_close = load_on_close(&java_vm, on_close_global_ref);
-
- let builder = self.callback(move |miss| {
- on_close.noop(); // Moves `on_close` inside the closure so it gets destroyed with the closure
- let _ = || -> ZResult<()> {
- let mut env = java_vm.attach_current_thread_as_daemon().map_err(|err| {
- zerror!("Unable to attach thread for sample miss listener: {}", err)
- })?;
-
- let (zid_lower, zid_upper, eid) = {
- let id = miss.source();
-
- let zid = id.zid().to_le_bytes();
- let zid_lower = i64::from_le_bytes(zid[0..8].try_into().unwrap());
- let zid_upper = i64::from_le_bytes(zid[8..16].try_into().unwrap());
-
- (zid_lower, zid_upper, id.eid())
- };
- let missed_count = miss.nb();
-
- env.call_method(
- &callback_global_ref,
- "run",
- "(JJJJ)V",
- &[
- JValue::from(zid_lower),
- JValue::from(zid_upper),
- JValue::from(eid as i64),
- JValue::from(missed_count as i64),
- ],
- )
- .map_err(|err| zerror!(err))?;
- Ok(())
- }()
- .map_err(|err| tracing::error!("On sample miss listener callback error: {err}"));
- });
- Ok(builder)
- }
-}
-
-/// Declares a subscriber to detect matching publishers for an [AdvancedSubscriber] via JNI.
-///
-/// Parameters:
-/// - `env`: The JNI environment.
-/// - `_class`: The JNI class.
-/// - `advanced_subscriber_ptr`: The raw pointer to the [AdvancedSubscriber].
-/// - `callback`: The callback function as an instance of the `JNISubscriberCallback` interface in Java/Kotlin.
-/// - `on_close`: A Java/Kotlin `JNIOnCloseCallback` function interface to be called upon closing the subscriber.
-///
-/// Returns:
-/// - A raw pointer to the declared [Subscriber]. In case of failure, an exception is thrown and null is returned.
-///
-/// Safety:
-/// - The function is marked as unsafe due to raw pointer manipulation and JNI interaction.
-/// - It assumes that the provided [AdvancedSubscriber] pointer is valid and has not been modified or freed.
-/// - The [AdvancedSubscriber] pointer remains valid and the ownership of the [AdvancedSubscriber] is not transferred,
-/// allowing safe usage of the [AdvancedSubscriber] after this function call.
-/// - The callback function passed as `callback` must be a valid instance of the `JNISubscriberCallback` interface
-/// in Java/Kotlin, matching the specified signature.
-/// - The function may throw a JNI exception in case of failure, which should be handled by the caller.
-///
-#[cfg(feature = "zenoh-ext")]
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNIAdvancedSubscriber_declareDetectPublishersSubscriberViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- advanced_subscriber_ptr: *const AdvancedSubscriber<()>,
- history: jboolean,
- callback: JObject,
- on_close: JObject,
-) -> *const Subscriber<()> {
- let advanced_subscriber = OwnedObject::from_raw(advanced_subscriber_ptr);
-
- || -> ZResult<*const Subscriber<()>> {
- tracing::debug!(
- "Declaring detect publishers subscriber on '{}'...",
- advanced_subscriber.key_expr()
- );
-
- let detect_publishers_subscriber = advanced_subscriber
- .detect_publishers()
- .history(history != 0)
- .set_jni_sample_callback(&mut env, callback, on_close)?
- .wait()
- .map_err(|err| zerror!("Unable to declare detect publishers subscriber: {}", err))?;
-
- tracing::debug!(
- "Detect publishers subscriber declared on '{}'...",
- advanced_subscriber.key_expr()
- );
- Ok(Arc::into_raw(Arc::new(detect_publishers_subscriber)))
- }()
- .unwrap_or_else(|err| {
- throw_exception!(env, err);
- null()
- })
-}
-
-/// Declares a background subscriber to detect matching publishers for an [AdvancedSubscriber] via JNI.
-///
-/// Parameters:
-/// - `env`: The JNI environment.
-/// - `_class`: The JNI class.
-/// - `advanced_subscriber_ptr`: The raw pointer to the [AdvancedSubscriber].
-/// - `callback`: The callback function as an instance of the `JNISubscriberCallback` interface in Java/Kotlin.
-/// - `on_close`: A Java/Kotlin `JNIOnCloseCallback` function interface to be called upon closing the subscriber.
-///
-/// Safety:
-/// - The function is marked as unsafe due to raw pointer manipulation and JNI interaction.
-/// - It assumes that the provided [AdvancedSubscriber] pointer is valid and has not been modified or freed.
-/// - The [AdvancedSubscriber] pointer remains valid and the ownership of the [AdvancedSubscriber] is not transferred,
-/// allowing safe usage of the [AdvancedSubscriber] after this function call.
-/// - The callback function passed as `callback` must be a valid instance of the `JNISubscriberCallback` interface
-/// in Java/Kotlin, matching the specified signature.
-/// - The function may throw a JNI exception in case of failure, which should be handled by the caller.
-///
-#[cfg(feature = "zenoh-ext")]
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNIAdvancedSubscriber_declareBackgroundDetectPublishersSubscriberViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- advanced_subscriber_ptr: *const AdvancedSubscriber<()>,
- history: jboolean,
- callback: JObject,
- on_close: JObject,
-) {
- let advanced_subscriber = OwnedObject::from_raw(advanced_subscriber_ptr);
-
- || -> ZResult<()> {
- tracing::debug!(
- "Declaring background detect publishers subscriber on '{}'...",
- advanced_subscriber.key_expr()
- );
-
- advanced_subscriber
- .detect_publishers()
- .history(history != 0)
- .set_jni_sample_callback(&mut env, callback, on_close)?
- .background()
- .wait()
- .map_err(|err| {
- zerror!(
- "Unable to declare background detect publishers subscriber: {}",
- err
- )
- })?;
-
- tracing::debug!(
- "Background detect publishers subscriber declared on '{}'...",
- advanced_subscriber.key_expr()
- );
- Ok(())
- }()
- .unwrap_or_else(|err| {
- throw_exception!(env, err);
- });
-}
-
-/// Declares a [SampleMissListener] to detect missed samples for an [AdvancedSubscriber] via JNI.
-///
-/// Parameters:
-/// - `env`: The JNI environment.
-/// - `_class`: The JNI class.
-/// - `advanced_subscriber_ptr`: The raw pointer to the [AdvancedSubscriber].
-/// - `callback`: The callback function as an instance of the `JNISampleMissListenerCallback` interface in Java/Kotlin.
-/// - `on_close`: A Java/Kotlin `JNIOnCloseCallback` function interface to be called upon closing the subscriber.
-///
-/// Returns:
-/// - A raw pointer to the declared [SampleMissListener]. In case of failure, an exception is thrown and null is returned.
-///
-/// Safety:
-/// - The function is marked as unsafe due to raw pointer manipulation and JNI interaction.
-/// - It assumes that the provided [AdvancedSubscriber] pointer is valid and has not been modified or freed.
-/// - The [AdvancedSubscriber] pointer remains valid and the ownership of the [AdvancedSubscriber] is not transferred,
-/// allowing safe usage of the [AdvancedSubscriber] after this function call.
-/// - The callback function passed as `callback` must be a valid instance of the `JNISampleMissListenerCallback` interface
-/// in Java/Kotlin, matching the specified signature.
-/// - The function may throw a JNI exception in case of failure, which should be handled by the caller.
-///
-#[cfg(feature = "zenoh-ext")]
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNIAdvancedSubscriber_declareSampleMissListenerViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- advanced_subscriber_ptr: *const AdvancedSubscriber<()>,
-
- callback: JObject,
- on_close: JObject,
-) -> *const SampleMissListener<()> {
- let advanced_subscriber = OwnedObject::from_raw(advanced_subscriber_ptr);
-
- || -> ZResult<*const SampleMissListener<()>> {
- tracing::debug!(
- "Declaring sample miss listener on '{}'...",
- advanced_subscriber.key_expr()
- );
-
- let result = advanced_subscriber
- .sample_miss_listener()
- .set_jni_sample_miss_callback(&mut env, callback, on_close)?
- .wait();
-
- let sample_miss_listener =
- result.map_err(|err| zerror!("Unable to declare sample miss listener: {}", err))?;
-
- tracing::debug!(
- "Matching listener declared on '{}'...",
- advanced_subscriber.key_expr()
- );
- Ok(Arc::into_raw(Arc::new(sample_miss_listener)))
- }()
- .unwrap_or_else(|err| {
- throw_exception!(env, err);
- null()
- })
-}
-
-/// Declare a background sample miss listener for [AdvancedSubscriber] via JNI.
-/// Register the listener callback to be run in background until the [AdvancedSubscriber] is undeclared.
-///
-/// Parameters:
-/// - `env`: The JNI environment.
-/// - `_class`: The JNI class.
-/// - `advanced_subscriber_ptr`: The raw pointer to an [AdvancedSubscriber].
-/// - `callback`: The callback function as an instance of the `JNISampleMissListenerCallback` interface in Java/Kotlin.
-/// - `on_close`: A Java/Kotlin `JNIOnCloseCallback` function interface to be called upon undeclaring the [AdvancedSubscriber].
-///
-/// Safety:
-/// - The function is marked as unsafe due to raw pointer manipulation and JNI interaction.
-/// - It assumes that the provided [AdvancedSubscriber] pointer is valid and has not been modified or freed.
-/// - The [AdvancedSubscriber] pointer remains valid and the ownership of the [AdvancedSubscriber] is not transferred,
-/// allowing safe usage of the [AdvancedSubscriber] after this function call.
-/// - The callback function passed as `callback` must be a valid instance of the `JNISampleMissListenerCallback` interface
-/// in Java/Kotlin, matching the specified signature.
-/// - The function may throw a JNI exception in case of failure, which should be handled by the caller.
-///
-#[cfg(feature = "zenoh-ext")]
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNIAdvancedSubscriber_declareBackgroundSampleMissListenerViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- advanced_subscriber_ptr: *const AdvancedSubscriber<()>,
-
- callback: JObject,
- on_close: JObject,
-) {
- let advanced_subscriber = OwnedObject::from_raw(advanced_subscriber_ptr);
-
- || -> ZResult<()> {
- tracing::debug!(
- "Declaring background sample miss listener on '{}'...",
- advanced_subscriber.key_expr()
- );
-
- advanced_subscriber
- .sample_miss_listener()
- .set_jni_sample_miss_callback(&mut env, callback, on_close)?
- .background()
- .wait()
- .map_err(|err| zerror!("Unable to declare background sample miss listener: {}", err))?;
-
- tracing::debug!(
- "Background sample miss listener declared on '{}'...",
- advanced_subscriber.key_expr()
- );
- Ok(())
- }()
- .unwrap_or_else(|err| {
- throw_exception!(env, err);
- })
-}
-
-/// Frees the [AdvancedSubscriber].
-///
-/// # Parameters:
-/// - `_env`: The JNI environment.
-/// - `_class`: The JNI class.
-/// - `subscriber_ptr`: The raw pointer to the [AdvancedSubscriber].
-///
-/// # Safety:
-/// - The function is marked as unsafe due to raw pointer manipulation.
-/// - It assumes that the provided [AdvancedSubscriber] pointer is valid and has not been modified or freed.
-/// - The function takes ownership of the raw pointer and releases the associated memory.
-/// - After calling this function, the [AdvancedSubscriber] pointer becomes invalid and should not be used anymore.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub(crate) unsafe extern "C" fn Java_io_zenoh_jni_JNIAdvancedSubscriber_freePtrViaJNI(
- _env: JNIEnv,
- _: JClass,
- subscriber_ptr: *const AdvancedSubscriber<()>,
-) {
- Arc::from_raw(subscriber_ptr);
-}
diff --git a/zenoh-jni/src/ext/matching_listener.rs b/zenoh-jni/src/ext/matching_listener.rs
deleted file mode 100644
index fd8856e1..00000000
--- a/zenoh-jni/src/ext/matching_listener.rs
+++ /dev/null
@@ -1,41 +0,0 @@
-//
-// Copyright (c) 2025 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-use std::sync::Arc;
-
-use jni::{objects::JClass, JNIEnv};
-use zenoh::matching::MatchingListener;
-
-/// Frees the [MatchingListener].
-///
-/// # Parameters:
-/// - `_env`: The JNI environment.
-/// - `_class`: The JNI class.
-/// - `matching_listener_ptr`: The raw pointer to the [MatchingListener].
-///
-/// # Safety:
-/// - The function is marked as unsafe due to raw pointer manipulation.
-/// - It assumes that the provided [MatchingListener] pointer is valid and has not been modified or freed.
-/// - The function takes ownership of the raw pointer and releases the associated memory.
-/// - After calling this function, the [MatchingListener] pointer becomes invalid and should not be used anymore.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub(crate) unsafe extern "C" fn Java_io_zenoh_jni_JNIMatchingListener_freePtrViaJNI(
- _env: JNIEnv,
- _: JClass,
- matching_listener_ptr: *const MatchingListener<()>,
-) {
- Arc::from_raw(matching_listener_ptr);
-}
diff --git a/zenoh-jni/src/ext/mod.rs b/zenoh-jni/src/ext/mod.rs
deleted file mode 100644
index 193fd21c..00000000
--- a/zenoh-jni/src/ext/mod.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-//
-// Copyright (c) 2025 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-mod advanced_publisher;
-mod advanced_subscriber;
-mod matching_listener;
-mod sample_miss_listener;
diff --git a/zenoh-jni/src/ext/sample_miss_listener.rs b/zenoh-jni/src/ext/sample_miss_listener.rs
deleted file mode 100644
index ede727b6..00000000
--- a/zenoh-jni/src/ext/sample_miss_listener.rs
+++ /dev/null
@@ -1,41 +0,0 @@
-//
-// Copyright (c) 2025 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-use std::sync::Arc;
-
-use jni::{objects::JClass, JNIEnv};
-use zenoh_ext::SampleMissListener;
-
-/// Frees the [SampleMissListener].
-///
-/// # Parameters:
-/// - `_env`: The JNI environment.
-/// - `_class`: The JNI class.
-/// - `sample_miss_listener_ptr`: The raw pointer to the [SampleMissListener].
-///
-/// # Safety:
-/// - The function is marked as unsafe due to raw pointer manipulation.
-/// - It assumes that the provided [SampleMissListener] pointer is valid and has not been modified or freed.
-/// - The function takes ownership of the raw pointer and releases the associated memory.
-/// - After calling this function, the [SampleMissListener] pointer becomes invalid and should not be used anymore.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub(crate) unsafe extern "C" fn Java_io_zenoh_jni_JNISampleMissListener_freePtrViaJNI(
- _env: JNIEnv,
- _: JClass,
- sample_miss_listener_ptr: *const SampleMissListener<()>,
-) {
- Arc::from_raw(sample_miss_listener_ptr);
-}
diff --git a/zenoh-jni/src/key_expr.rs b/zenoh-jni/src/key_expr.rs
deleted file mode 100644
index 11d39d47..00000000
--- a/zenoh-jni/src/key_expr.rs
+++ /dev/null
@@ -1,333 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-use std::ops::Deref;
-use std::sync::Arc;
-
-use jni::objects::JClass;
-use jni::sys::{jboolean, jint, jstring};
-use jni::{objects::JString, JNIEnv};
-use zenoh::key_expr::KeyExpr;
-
-use crate::errors::ZResult;
-use crate::utils::decode_string;
-use crate::{throw_exception, zerror};
-
-/// Validates the provided `key_expr` to be a valid key expression, returning it back
-/// in case of success or throwing an exception in case of failure.
-///
-/// # Parameters:
-/// `env`: The JNI environment.
-/// `_class`: the Java class (unused).
-/// `key_expr`: Java string representation of the intended key expression.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub extern "C" fn Java_io_zenoh_jni_JNIKeyExpr_00024Companion_tryFromViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- key_expr: JString,
-) -> jstring {
- validate_key_expr(&mut env, &key_expr)
- .map(|_| **key_expr)
- .unwrap_or_else(|err| {
- throw_exception!(env, err);
- JString::default().as_raw()
- })
-}
-
-/// Returns a java string representation of the autocanonized version of the provided `key_expr`.
-/// In case of failure and exception will be thrown.
-///
-/// # Parameters:
-/// `env`: The JNI environment.
-/// `_class`: the Java class (unused).
-/// `key_expr`: Java string representation of the intended key expression.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub extern "C" fn Java_io_zenoh_jni_JNIKeyExpr_00024Companion_autocanonizeViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- key_expr: JString,
-) -> jstring {
- autocanonize_key_expr(&mut env, &key_expr)
- .and_then(|key_expr| {
- env.new_string(key_expr.to_string())
- .map(|kexp| kexp.as_raw())
- .map_err(|err| zerror!(err))
- })
- .unwrap_or_else(|err| {
- throw_exception!(env, err);
- JString::default().as_raw()
- })
-}
-
-/// Returns true in case key_expr_1 intersects key_expr_2.
-///
-/// # Params:
-/// - `key_expr_ptr_1`: Pointer to the key expression 1, differs from null only if it's a declared key expr.
-/// - `key_expr_str_1`: String representation of the key expression 1.
-/// - `key_expr_ptr_2`: Pointer to the key expression 2, differs from null only if it's a declared key expr.
-/// - `key_expr_str_2`: String representation of the key expression 2.
-///
-/// # Safety
-/// - This function is marked as unsafe due to raw pointer manipulation, which happens only when providing
-/// key expressions that were declared from a session (in that case the key expression has a pointer associated).
-///
-/// In that case, this function assumes the pointers are valid pointers to key expressions and those pointers
-/// remain valid after the call to this function.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNIKeyExpr_00024Companion_intersectsViaJNI(
- mut env: JNIEnv,
- _: JClass,
- key_expr_ptr_1: /*nullable*/ *const KeyExpr<'static>,
- key_expr_str_1: JString,
- key_expr_ptr_2: /*nullable*/ *const KeyExpr<'static>,
- key_expr_str_2: JString,
-) -> jboolean {
- || -> ZResult {
- let key_expr_1 = process_kotlin_key_expr(&mut env, &key_expr_str_1, key_expr_ptr_1)?;
- let key_expr_2 = process_kotlin_key_expr(&mut env, &key_expr_str_2, key_expr_ptr_2)?;
- Ok(key_expr_1.intersects(&key_expr_2) as jboolean)
- }()
- .unwrap_or_else(|err| {
- throw_exception!(env, err);
- false as jboolean
- })
-}
-
-/// Returns true in case key_expr_1 includes key_expr_2.
-///
-/// # Params:
-/// - `key_expr_ptr_1`: Pointer to the key expression 1, differs from null only if it's a declared key expr.
-/// - `key_expr_str_1`: String representation of the key expression 1.
-/// - `key_expr_ptr_2`: Pointer to the key expression 2, differs from null only if it's a declared key expr.
-/// - `key_expr_str_2`: String representation of the key expression 2.
-///
-/// # Safety
-/// - This function is marked as unsafe due to raw pointer manipulation, which happens only when providing
-/// key expressions that were declared from a session (in that case the key expression has a pointer associated).
-///
-/// In that case, this function assumes the pointers are valid pointers to key expressions and those pointers
-/// remain valid after the call to this function.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNIKeyExpr_00024Companion_includesViaJNI(
- mut env: JNIEnv,
- _: JClass,
- key_expr_ptr_1: /*nullable*/ *const KeyExpr<'static>,
- key_expr_str_1: JString,
- key_expr_ptr_2: /*nullable*/ *const KeyExpr<'static>,
- key_expr_str_2: JString,
-) -> jboolean {
- || -> ZResult {
- let key_expr_1 = process_kotlin_key_expr(&mut env, &key_expr_str_1, key_expr_ptr_1)?;
- let key_expr_2 = process_kotlin_key_expr(&mut env, &key_expr_str_2, key_expr_ptr_2)?;
- Ok(key_expr_1.includes(&key_expr_2) as jboolean)
- }()
- .unwrap_or_else(|err| {
- throw_exception!(env, err);
- false as jboolean
- })
-}
-
-/// Returns the integer representation of the intersection level of the key expression 1 and key expression 2,
-/// from the perspective of key expression 1.
-///
-/// # Params:
-/// - `key_expr_ptr_1`: Pointer to the key expression 1, differs from null only if it's a declared key expr.
-/// - `key_expr_str_1`: String representation of the key expression 1.
-/// - `key_expr_ptr_2`: Pointer to the key expression 2, differs from null only if it's a declared key expr.
-/// - `key_expr_str_2`: String representation of the key expression 2.
-///
-/// # Safety
-/// - This function is marked as unsafe due to raw pointer manipulation, which happens only when providing
-/// key expressions that were declared from a session (in that case the key expression has a pointer associated).
-///
-/// In that case, this function assumes the pointers are valid pointers to key expressions and those pointers
-/// remain valid after the call to this function.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNIKeyExpr_00024Companion_relationToViaJNI(
- mut env: JNIEnv,
- _: JClass,
- key_expr_ptr_1: /*nullable*/ *const KeyExpr<'static>,
- key_expr_str_1: JString,
- key_expr_ptr_2: /*nullable*/ *const KeyExpr<'static>,
- key_expr_str_2: JString,
-) -> jint {
- || -> ZResult {
- let key_expr_1 = process_kotlin_key_expr(&mut env, &key_expr_str_1, key_expr_ptr_1)?;
- let key_expr_2 = process_kotlin_key_expr(&mut env, &key_expr_str_2, key_expr_ptr_2)?;
- Ok(key_expr_1.relation_to(&key_expr_2) as jint)
- }()
- .unwrap_or_else(|err| {
- throw_exception!(env, err);
- -1 as jint
- })
-}
-
-/// Joins key expression 1 with key expression 2, where key_expr_2 is a string. Returns the string representation
-/// of the result, or throws an exception in case of failure.
-///
-/// # Params:
-/// - `key_expr_ptr_1`: Pointer to the key expression 1, differs from null only if it's a declared key expr.
-/// - `key_expr_ptr_1`: String representation of the key expression 1.
-/// - `key_expr_2`: String representation of the key expression 2.
-///
-/// # Safety
-/// - This function is marked as unsafe due to raw pointer manipulation, which happens only when providing
-/// key expressions that were declared from a session (in that case the key expression has a pointer associated).
-///
-/// In that case, this function assumes the pointers are valid pointers to key expressions and those pointers
-/// remain valid after the call to this function.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNIKeyExpr_00024Companion_joinViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- key_expr_ptr_1: /*nullable*/ *const KeyExpr<'static>,
- key_expr_str_1: JString,
- key_expr_2: JString,
-) -> jstring {
- || -> ZResult {
- let key_expr_1 = process_kotlin_key_expr(&mut env, &key_expr_str_1, key_expr_ptr_1)?;
- let key_expr_2_str = decode_string(&mut env, &key_expr_2)?;
- let result = key_expr_1
- .join(key_expr_2_str.as_str())
- .map_err(|err| zerror!(err))?;
- env.new_string(result.to_string())
- .map(|kexp| kexp.as_raw())
- .map_err(|err| zerror!(err))
- }()
- .unwrap_or_else(|err| {
- throw_exception!(env, err);
- JString::default().as_raw()
- })
-}
-
-/// Concats key_expr_1 with key_expr_2, where key_expr_2 is a string. Returns the string representation
-/// of the result, or throws an exception in case of failure.
-///
-/// # Params:
-/// - `key_expr_ptr_1`: Pointer to the key expression 1, differs from null only if it's a declared key expr.
-/// - `key_expr_ptr_1`: String representation of the key expression 1.
-/// - `key_expr_2`: String representation of the key expression 2.
-///
-/// # Safety
-/// - This function is marked as unsafe due to raw pointer manipulation, which happens only when providing
-/// key expressions that were declared from a session (in that case the key expression has a pointer associated).
-///
-/// In that case, this function assumes the pointers are valid pointers to key expressions and those pointers
-/// remain valid after the call to this function.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNIKeyExpr_00024Companion_concatViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- key_expr_ptr_1: /*nullable*/ *const KeyExpr<'static>,
- key_expr_str_1: JString,
- key_expr_2: JString,
-) -> jstring {
- || -> ZResult {
- let key_expr_1 = process_kotlin_key_expr(&mut env, &key_expr_str_1, key_expr_ptr_1)?;
- let key_expr_2_str = decode_string(&mut env, &key_expr_2)?;
- let result = key_expr_1
- .concat(key_expr_2_str.as_str())
- .map_err(|err| zerror!(err))?;
- env.new_string(result.to_string())
- .map(|kexp| kexp.as_raw())
- .map_err(|err| zerror!(err))
- }()
- .unwrap_or_else(|err| {
- throw_exception!(env, err);
- JString::default().as_raw()
- })
-}
-
-/// Frees a declared key expression.
-///
-/// # Parameters
-/// - `_env`: Unused. The JNI environment.
-/// - `_class`: Unused. The java class from which the function was called.
-/// - `key_expr_ptr`: the pointer to the key expression.
-///
-/// # Safety
-/// - This function assumes the provided pointer is valid and points to a native key expression.
-/// - The memory associated to the pointer is freed after returning from this call, turning the
-/// pointer invalid after that.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNIKeyExpr_freePtrViaJNI(
- _env: JNIEnv,
- _: JClass,
- key_expr_ptr: *const KeyExpr<'static>,
-) {
- Arc::from_raw(key_expr_ptr);
-}
-
-fn validate_key_expr(env: &mut JNIEnv, key_expr: &JString) -> ZResult> {
- let key_expr_str = decode_string(env, key_expr)
- .map_err(|err| zerror!("Unable to get key expression string value: '{}'.", err))?;
-
- KeyExpr::try_from(key_expr_str)
- .map_err(|err| zerror!("Unable to create key expression: '{}'.", err))
-}
-
-fn autocanonize_key_expr(env: &mut JNIEnv, key_expr: &JString) -> ZResult> {
- decode_string(env, key_expr)
- .map_err(|err| zerror!("Unable to get key expression string value: '{}'.", err))
- .and_then(|key_expr_str| {
- KeyExpr::autocanonize(key_expr_str)
- .map_err(|err| zerror!("Unable to create key expression: '{}'", err))
- })
-}
-
-/// Processes a kotlin key expression.
-///
-/// Receives the Java/Kotlin string representation of the key expression as well as a pointer.
-/// The pointer is only valid in cases where the key expression is associated to a native pointer
-/// (when the key expression was declared from a session).
-/// If the pointer is valid, the key expression returned is the key expression the pointer pointed to.
-/// Otherwise, a key expression created from the string representation of the key expression is returned.
-///
-/// # Safety:
-///
-/// The key_expr_str argument provided should already have been validated upon creation of the
-/// KeyExpr instance on Kotlin.
-///
-pub(crate) unsafe fn process_kotlin_key_expr(
- env: &mut JNIEnv,
- key_expr_str: &JString,
- key_expr_ptr: *const KeyExpr<'static>,
-) -> ZResult> {
- if key_expr_ptr.is_null() {
- let key_expr = decode_string(env, key_expr_str)
- .map_err(|err| zerror!("Unable to get key expression string value: '{}'.", err))?;
- Ok(KeyExpr::from_string_unchecked(key_expr))
- } else {
- let key_expr = Arc::from_raw(key_expr_ptr);
- let key_expr_clone = key_expr.deref().clone();
- std::mem::forget(key_expr);
- Ok(key_expr_clone)
- }
-}
diff --git a/zenoh-jni/src/lib.rs b/zenoh-jni/src/lib.rs
deleted file mode 100644
index 93765edb..00000000
--- a/zenoh-jni/src/lib.rs
+++ /dev/null
@@ -1,41 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-mod config;
-mod errors;
-#[cfg(feature = "zenoh-ext")]
-mod ext;
-mod key_expr;
-mod liveliness;
-mod logger;
-pub(crate) mod owned_object;
-mod publisher;
-mod querier;
-mod query;
-mod queryable;
-pub(crate) mod sample_callback;
-mod scouting;
-mod session;
-mod subscriber;
-mod utils;
-#[cfg(feature = "zenoh-ext")]
-mod zbytes;
-mod zenoh_id;
-
-// Test should be runned with `cargo test --no-default-features`
-#[test]
-#[cfg(not(feature = "default"))]
-fn test_no_default_features() {
- assert_eq!(zenoh::FEATURES, concat!(" zenoh/unstable"));
-}
diff --git a/zenoh-jni/src/liveliness.rs b/zenoh-jni/src/liveliness.rs
deleted file mode 100644
index d822eb94..00000000
--- a/zenoh-jni/src/liveliness.rs
+++ /dev/null
@@ -1,174 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-use std::{ptr::null, sync::Arc, time::Duration};
-
-use jni::{
- objects::{JClass, JObject, JString},
- sys::{jboolean, jlong},
- JNIEnv,
-};
-
-use zenoh::{
- internal::runtime::ZRuntime, key_expr::KeyExpr, liveliness::LivelinessToken,
- pubsub::Subscriber, Session, Wait,
-};
-
-use crate::{
- errors::ZResult,
- key_expr::process_kotlin_key_expr,
- owned_object::OwnedObject,
- sample_callback::SetJniSampleCallback,
- session::{on_reply_error, on_reply_success},
- throw_exception,
- utils::{get_callback_global_ref, get_java_vm, load_on_close},
- zerror,
-};
-
-#[no_mangle]
-#[allow(non_snake_case)]
-pub extern "C" fn Java_io_zenoh_jni_JNILiveliness_getViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- session_ptr: *const Session,
- key_expr_ptr: /*nullable*/ *const KeyExpr<'static>,
- key_expr_str: JString,
- callback: JObject,
- timeout_ms: jlong,
- on_close: JObject,
-) {
- let session = unsafe { OwnedObject::from_raw(session_ptr) };
- let _ = || -> ZResult<()> {
- let key_expr = unsafe { process_kotlin_key_expr(&mut env, &key_expr_str, key_expr_ptr) }?;
- let java_vm = Arc::new(get_java_vm(&mut env)?);
- let callback_global_ref = get_callback_global_ref(&mut env, callback)?;
- let on_close_global_ref = get_callback_global_ref(&mut env, on_close)?;
- let on_close = load_on_close(&java_vm, on_close_global_ref);
- let timeout = Duration::from_millis(timeout_ms as u64);
- let replies = session
- .liveliness()
- .get(key_expr.to_owned())
- .timeout(timeout)
- .wait()
- .map_err(|err| zerror!(err))?;
-
- ZRuntime::Application.spawn(async move {
- on_close.noop(); // Does nothing, but moves `on_close` inside the closure so it gets destroyed with the closure
- while let Ok(reply) = replies.recv_async().await {
- || -> ZResult<()> {
- tracing::debug!("Receiving liveliness reply through JNI: {:?}", reply);
- let mut env = java_vm.attach_current_thread_as_daemon().map_err(|err| {
- zerror!(
- "Unable to attach thread for GET liveliness query callback: {}.",
- err
- )
- })?;
- match reply.result() {
- Ok(sample) => on_reply_success(
- &mut env,
- reply.replier_id(),
- sample,
- &callback_global_ref,
- ),
- Err(error) => on_reply_error(
- &mut env,
- reply.replier_id(),
- error,
- &callback_global_ref,
- ),
- }
- }()
- .unwrap_or_else(|err| tracing::error!("Error on get liveliness callback: {err}."));
- }
- });
- Ok(())
- }()
- .map_err(|err| {
- throw_exception!(env, err);
- });
-}
-
-#[no_mangle]
-#[allow(non_snake_case)]
-pub extern "C" fn Java_io_zenoh_jni_JNILiveliness_declareTokenViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- session_ptr: *const Session,
- key_expr_ptr: /*nullable*/ *const KeyExpr<'static>,
- key_expr_str: JString,
-) -> *const LivelinessToken {
- let session = unsafe { OwnedObject::from_raw(session_ptr) };
- || -> ZResult<*const LivelinessToken> {
- let key_expr = unsafe { process_kotlin_key_expr(&mut env, &key_expr_str, key_expr_ptr) }?;
- tracing::trace!("Declaring liveliness token on '{key_expr}'.");
- let token = session
- .liveliness()
- .declare_token(key_expr)
- .wait()
- .map_err(|err| zerror!(err))?;
- Ok(Arc::into_raw(Arc::new(token)))
- }()
- .unwrap_or_else(|err| {
- throw_exception!(env, err);
- null()
- })
-}
-
-#[no_mangle]
-#[allow(non_snake_case)]
-pub extern "C" fn Java_io_zenoh_jni_JNILivelinessToken_00024Companion_undeclareViaJNI(
- _env: JNIEnv,
- _: JClass,
- token_ptr: *const LivelinessToken,
-) {
- unsafe { Arc::from_raw(token_ptr) };
-}
-
-#[no_mangle]
-#[allow(non_snake_case)]
-pub extern "C" fn Java_io_zenoh_jni_JNILiveliness_declareSubscriberViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- session_ptr: *const Session,
- key_expr_ptr: /*nullable*/ *const KeyExpr<'static>,
- key_expr_str: JString,
- callback: JObject,
- history: jboolean,
- on_close: JObject,
-) -> *const Subscriber<()> {
- let session = unsafe { OwnedObject::from_raw(session_ptr) };
- || -> ZResult<*const Subscriber<()>> {
- let key_expr = unsafe { process_kotlin_key_expr(&mut env, &key_expr_str, key_expr_ptr)? };
- tracing::debug!("Declaring liveliness subscriber on '{}'...", key_expr);
-
- let result = unsafe {
- session
- .liveliness()
- .declare_subscriber(key_expr.to_owned())
- .history(history != 0)
- .set_jni_sample_callback(&mut env, callback, on_close)?
- .wait()
- };
-
- let subscriber =
- result.map_err(|err| zerror!("Unable to declare liveliness subscriber: {}", err))?;
-
- tracing::debug!("Liveliness subscriber declared on '{}'.", key_expr);
- Ok(Arc::into_raw(Arc::new(subscriber)))
- }()
- .unwrap_or_else(|err| {
- throw_exception!(env, err);
- null()
- })
-}
diff --git a/zenoh-jni/src/logger.rs b/zenoh-jni/src/logger.rs
deleted file mode 100644
index 12047a3e..00000000
--- a/zenoh-jni/src/logger.rs
+++ /dev/null
@@ -1,79 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-use jni::{
- objects::{JClass, JString},
- JNIEnv,
-};
-
-use crate::{errors::ZResult, throw_exception, zerror};
-
-/// Redirects the Rust logs either to logcat for Android systems or to the standard output (for non-Android systems).
-///
-/// This function is meant to be called from Java/Kotlin code through JNI. It takes a `filter`
-/// indicating the desired log level.
-/// If the logger was already initialized in a previous call, then it does nothing.
-///
-/// See https://docs.rs/env_logger/latest/env_logger/index.html for accepted filter format.
-///
-/// # Parameters:
-/// - `env`: The JNI environment.
-/// - `_class`: The JNI class.
-/// - `filter`: The logs filter.
-///
-/// # Errors:
-/// - If there is an error parsing the log level string, a `JNIException` is thrown on the JVM.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub extern "C" fn Java_io_zenoh_Logger_00024Companion_startLogsViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- filter: JString,
-) {
- || -> ZResult<()> {
- let log_level = parse_filter(&mut env, filter)?;
- #[cfg(target_os = "android")]
- {
- android_logd_logger::builder()
- .parse_filters(log_level.as_str())
- .tag_target_strip()
- .prepend_module(true)
- .pstore(false)
- .try_init()
- .ok();
- }
-
- #[cfg(not(target_os = "android"))]
- {
- android_logd_logger::builder()
- .parse_filters(log_level.as_str())
- .tag_target_strip()
- .prepend_module(true)
- .try_init()
- .ok();
- }
-
- Ok(())
- }()
- .unwrap_or_else(|err| throw_exception!(env, err))
-}
-
-fn parse_filter(env: &mut JNIEnv, log_level: JString) -> ZResult {
- let log_level = env.get_string(&log_level).map_err(|err| zerror!(err))?;
- log_level
- .to_str()
- .map(|level| Ok(level.to_string()))
- .map_err(|err| zerror!(err))?
-}
diff --git a/zenoh-jni/src/owned_object.rs b/zenoh-jni/src/owned_object.rs
deleted file mode 100644
index 25f1c521..00000000
--- a/zenoh-jni/src/owned_object.rs
+++ /dev/null
@@ -1,46 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-use std::{ops::Deref, sync::Arc};
-
-/// Safe accessor to refocounted ([Arc]) owned objects.
-/// Helps to avoid early drop by offloading [std::mem::forget] from user
-pub(crate) struct OwnedObject {
- inner: Option>,
-}
-
-impl Deref for OwnedObject {
- type Target = T;
-
- fn deref(&self) -> &Self::Target {
- // SAFETY: inner is always initialized
- unsafe { self.inner.as_ref().unwrap_unchecked() }
- }
-}
-
-impl Drop for OwnedObject {
- fn drop(&mut self) {
- // SAFETY: inner is always initialized
- let inner = unsafe { self.inner.take().unwrap_unchecked() };
- std::mem::forget(inner);
- }
-}
-
-impl OwnedObject {
- pub(crate) unsafe fn from_raw(ptr: *const T) -> Self {
- Self {
- inner: Some(Arc::from_raw(ptr)),
- }
- }
-}
diff --git a/zenoh-jni/src/publisher.rs b/zenoh-jni/src/publisher.rs
deleted file mode 100644
index ead60c3f..00000000
--- a/zenoh-jni/src/publisher.rs
+++ /dev/null
@@ -1,130 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-use std::sync::Arc;
-
-use jni::{
- objects::{JByteArray, JClass, JString},
- sys::jint,
- JNIEnv,
-};
-use zenoh::{pubsub::Publisher, Wait};
-
-use crate::throw_exception;
-use crate::{
- errors::ZResult,
- utils::{decode_byte_array, decode_encoding},
- zerror,
-};
-
-/// Performs a PUT operation on a Zenoh publisher via JNI.
-///
-/// # Parameters
-/// - `env`: The JNI environment pointer.
-/// - `_class`: The Java class reference (unused).
-/// - `payload`: The byte array to be published.
-/// - `encoding_id`: The encoding ID of the payload.
-/// - `encoding_schema`: Nullable encoding schema string of the payload.
-/// - `attachment`: Nullble byte array for the attachment.
-/// - `publisher_ptr`: The raw pointer to the Zenoh publisher ([Publisher]).
-///
-/// # Safety
-/// - This function is marked as unsafe due to raw pointer manipulation and JNI interaction.
-/// - Assumes that the provided publisher pointer is valid and has not been modified or freed.
-/// - The publisher pointer remains valid after this function call.
-/// - May throw an exception in case of failure, which must be handled by the caller.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNIPublisher_putViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- payload: JByteArray,
- encoding_id: jint,
- encoding_schema: /*nullable*/ JString,
- attachment: /*nullable*/ JByteArray,
- publisher_ptr: *const Publisher<'static>,
-) {
- let publisher = Arc::from_raw(publisher_ptr);
- let _ = || -> ZResult<()> {
- let payload = decode_byte_array(&env, payload)?;
- let mut publication = publisher.put(payload);
- let encoding = decode_encoding(&mut env, encoding_id, &encoding_schema)?;
- publication = publication.encoding(encoding);
- if !attachment.is_null() {
- let attachment = decode_byte_array(&env, attachment)?;
- publication = publication.attachment::>(attachment)
- };
- publication.wait().map_err(|err| zerror!(err))
- }()
- .map_err(|err| throw_exception!(env, err));
- std::mem::forget(publisher);
-}
-
-/// Performs a DELETE operation on a Zenoh publisher via JNI.
-///
-/// # Parameters
-/// - `env`: The JNI environment pointer.
-/// - `_class`: The Java class reference (unused).
-/// - `attachment`: Nullble byte array for the attachment.
-/// - `publisher_ptr`: The raw pointer to the Zenoh publisher ([Publisher]).
-///
-/// # Safety
-/// - This function is marked as unsafe due to raw pointer manipulation and JNI interaction.
-/// - Assumes that the provided publisher pointer is valid and has not been modified or freed.
-/// - The publisher pointer remains valid after this function call.
-/// - May throw an exception in case of failure, which must be handled by the caller.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNIPublisher_deleteViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- attachment: /*nullable*/ JByteArray,
- publisher_ptr: *const Publisher<'static>,
-) {
- let publisher = Arc::from_raw(publisher_ptr);
- let _ = || -> ZResult<()> {
- let mut delete = publisher.delete();
- if !attachment.is_null() {
- let attachment = decode_byte_array(&env, attachment)?;
- delete = delete.attachment::>(attachment)
- };
- delete.wait().map_err(|err| zerror!(err))
- }()
- .map_err(|err| throw_exception!(env, err));
- std::mem::forget(publisher)
-}
-
-/// Frees the publisher.
-///
-/// # Parameters:
-/// - `_env`: The JNI environment.
-/// - `_class`: The JNI class.
-/// - `publisher_ptr`: The raw pointer to the Zenoh publisher ([Publisher]).
-///
-/// # Safety:
-/// - The function is marked as unsafe due to raw pointer manipulation.
-/// - It assumes that the provided publisher pointer is valid and has not been modified or freed.
-/// - After calling this function, the publisher pointer becomes invalid and should not be used anymore.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub(crate) unsafe extern "C" fn Java_io_zenoh_jni_JNIPublisher_freePtrViaJNI(
- _env: JNIEnv,
- _: JClass,
- publisher_ptr: *const Publisher,
-) {
- Arc::from_raw(publisher_ptr);
-}
diff --git a/zenoh-jni/src/querier.rs b/zenoh-jni/src/querier.rs
deleted file mode 100644
index 8c239498..00000000
--- a/zenoh-jni/src/querier.rs
+++ /dev/null
@@ -1,137 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-use std::sync::Arc;
-
-use jni::{
- objects::{JByteArray, JClass, JObject, JString},
- sys::jint,
- JNIEnv,
-};
-use zenoh::{key_expr::KeyExpr, query::Querier, Wait};
-
-use crate::{
- errors::ZResult,
- key_expr::process_kotlin_key_expr,
- session::{on_reply_error, on_reply_success},
- throw_exception,
- utils::{
- decode_byte_array, decode_encoding, decode_string, get_callback_global_ref, get_java_vm,
- load_on_close,
- },
- zerror,
-};
-
-/// Perform a Zenoh GET through a querier.
-///
-/// This function is meant to be called from Java/Kotlin code through JNI.
-///
-/// Parameters:
-/// - `env`: The JNI environment.
-/// - `_class`: The JNI class.
-/// - `querier_ptr`: The raw pointer to the querier.
-/// - `key_expr_ptr`: A raw pointer to the [KeyExpr] provided to the kotlin querier. May be null in case of using an
-/// undeclared key expression.
-/// - `key_expr_str`: String representation of the key expression used during the querier declaration.
-/// It won't be considered in case a key_expr_ptr to a declared key expression is provided.
-/// - `selector_params`: Optional selector parameters for the query.
-/// - `callback`: Reference to the Kotlin callback to be run upon receiving a reply.
-/// - `on_close`: Reference to a kotlin callback to be run upon finishing the get operation, mostly used for closing a provided channel.
-/// - `attachment`: Optional attachment.
-/// - `payload`: Optional payload for the query.
-/// - `encoding_id`: Encoding id of the payload provided.
-/// - `encoding_schema`: Encoding schema of the payload provided.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNIQuerier_getViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- querier_ptr: *const Querier,
- key_expr_ptr: /*nullable*/ *const KeyExpr<'static>,
- key_expr_str: JString,
- selector_params: /*nullable*/ JString,
- callback: JObject,
- on_close: JObject,
- attachment: /*nullable*/ JByteArray,
- payload: /*nullable*/ JByteArray,
- encoding_id: jint,
- encoding_schema: /*nullable*/ JString,
-) {
- let querier = Arc::from_raw(querier_ptr);
- let _ = || -> ZResult<()> {
- let key_expr = process_kotlin_key_expr(&mut env, &key_expr_str, key_expr_ptr)?;
- let java_vm = Arc::new(get_java_vm(&mut env)?);
- let callback_global_ref = get_callback_global_ref(&mut env, callback)?;
- let on_close_global_ref = get_callback_global_ref(&mut env, on_close)?;
- let on_close = load_on_close(&java_vm, on_close_global_ref);
- let mut get_builder = querier.get().callback(move |reply| {
- || -> ZResult<()> {
- on_close.noop(); // Does nothing, but moves `on_close` inside the closure so it gets destroyed with the closure
- tracing::debug!("Receiving reply through JNI: {:?}", reply);
- let mut env = java_vm.attach_current_thread_as_daemon().map_err(|err| {
- zerror!("Unable to attach thread for GET query callback: {}.", err)
- })?;
-
- match reply.result() {
- Ok(sample) => {
- on_reply_success(&mut env, reply.replier_id(), sample, &callback_global_ref)
- }
- Err(error) => {
- on_reply_error(&mut env, reply.replier_id(), error, &callback_global_ref)
- }
- }
- }()
- .unwrap_or_else(|err| tracing::error!("Error on get callback: {err}"));
- });
-
- if !selector_params.is_null() {
- let params = decode_string(&mut env, &selector_params)?;
- get_builder = get_builder.parameters(params)
- };
-
- if !payload.is_null() {
- let encoding = decode_encoding(&mut env, encoding_id, &encoding_schema)?;
- get_builder = get_builder.encoding(encoding);
- get_builder = get_builder.payload(decode_byte_array(&env, payload)?);
- }
-
- if !attachment.is_null() {
- let attachment = decode_byte_array(&env, attachment)?;
- get_builder = get_builder.attachment::>(attachment);
- }
-
- get_builder
- .wait()
- .map(|_| tracing::trace!("Performing get on '{key_expr}'.",))
- .map_err(|err| zerror!(err))
- }()
- .map_err(|err| throw_exception!(env, err));
- std::mem::forget(querier);
-}
-
-///
-/// Frees the pointer of the querier.
-///
-/// After a call to this function, no further jni operations should be performed using the querier associated to the raw pointer provided.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub(crate) unsafe extern "C" fn Java_io_zenoh_jni_JNIQuerier_freePtrViaJNI(
- _env: JNIEnv,
- _: JClass,
- querier_ptr: *const Querier<'static>,
-) {
- Arc::from_raw(querier_ptr);
-}
diff --git a/zenoh-jni/src/query.rs b/zenoh-jni/src/query.rs
deleted file mode 100644
index 95affb7e..00000000
--- a/zenoh-jni/src/query.rs
+++ /dev/null
@@ -1,206 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-use std::sync::Arc;
-
-use crate::utils::{decode_byte_array, decode_encoding};
-use crate::zerror;
-use crate::{errors::ZResult, key_expr::process_kotlin_key_expr, throw_exception};
-use jni::{
- objects::{JByteArray, JClass, JString},
- sys::{jboolean, jint, jlong},
- JNIEnv,
-};
-use uhlc::ID;
-use zenoh::{
- key_expr::KeyExpr,
- query::Query,
- time::{Timestamp, NTP64},
- Wait,
-};
-
-/// Replies with `success` to a Zenoh [Query] via JNI, freeing the query in the process.
-///
-/// # Parameters:
-/// - `env`: The JNI environment.
-/// - `_class`: The JNI class.
-/// - `query_ptr`: The raw pointer to the Zenoh query.
-/// - `key_expr_ptr`: Nullable key expression pointer associated with the query result. This parameter
-/// is meant to be used with declared key expressions, which have a pointer associated to them.
-/// In case of it being null, then the `key_expr_string` will be used to perform the reply.
-/// - `key_expr_str`: The string representation of the key expression associated with the query result.
-/// - `payload`: The payload for the reply.
-/// - `encoding_id`: The encoding id of the payload.
-/// - `encoding_schema`: Nullable encoding schema.
-/// - `timestamp_enabled`: A boolean indicating whether the timestamp is enabled.
-/// - `timestamp_ntp_64`: The NTP64 timestamp value.
-/// - `attachment`: Nullable user attachment encoded as a byte array.
-/// - `qos_express`: Whether the reply should be sent with the express flag.
-///
-/// # Safety:
-/// - This function is marked as unsafe due to raw pointer manipulation and JNI interaction.
-/// - It assumes that the provided raw pointer to the Zenoh query is valid and has not been modified or freed.
-/// - The query pointer is freed after calling this function (queries shouldn't be replied more than once),
-/// therefore the query isn't valid anymore after that.
-/// - May throw a JNI exception in case of failure, which should be handled by the caller.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub(crate) unsafe extern "C" fn Java_io_zenoh_jni_JNIQuery_replySuccessViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- query_ptr: *const Query,
- key_expr_ptr: /*nullable*/ *const KeyExpr<'static>,
- key_expr_str: JString,
- payload: JByteArray,
- encoding_id: jint,
- encoding_schema: /*nullable*/ JString,
- timestamp_enabled: jboolean,
- timestamp_ntp_64: jlong,
- attachment: /*nullable*/ JByteArray,
- qos_express: jboolean,
-) {
- let _ = || -> ZResult<()> {
- let query = Arc::from_raw(query_ptr);
- let key_expr = process_kotlin_key_expr(&mut env, &key_expr_str, key_expr_ptr)?;
- let payload = decode_byte_array(&env, payload)?;
- let mut reply_builder = query.reply(key_expr, payload);
- let encoding = decode_encoding(&mut env, encoding_id, &encoding_schema)?;
- reply_builder = reply_builder.encoding(encoding);
- if timestamp_enabled != 0 {
- let ts = Timestamp::new(NTP64(timestamp_ntp_64 as u64), ID::rand());
- reply_builder = reply_builder.timestamp(ts)
- }
- if !attachment.is_null() {
- reply_builder = reply_builder.attachment(decode_byte_array(&env, attachment)?);
- }
- reply_builder = reply_builder.express(qos_express != 0);
- reply_builder.wait().map_err(|err| zerror!(err))
- }()
- .map_err(|err| throw_exception!(env, err));
-}
-
-/// Replies with `error` to a Zenoh [Query] via JNI, freeing the query in the process.
-///
-/// # Parameters:
-/// - `env`: The JNI environment.
-/// - `_class`: The JNI class.
-/// - `query_ptr`: The raw pointer to the Zenoh query.
-/// - `payload`: The payload for the reply.
-/// - `encoding_id`: The encoding id of the payload.
-/// - `encoding_schema`: Nullable encoding schema.
-///
-/// # Safety:
-/// - This function is marked as unsafe due to raw pointer manipulation and JNI interaction.
-/// - It assumes that the provided raw pointer to the Zenoh query is valid and has not been modified or freed.
-/// - May throw a JNI exception in case of failure, which should be handled by the caller.
-/// - The query pointer is freed after calling this function (queries shouldn't be replied more than once),
-/// therefore the query isn't valid anymore after that.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub(crate) unsafe extern "C" fn Java_io_zenoh_jni_JNIQuery_replyErrorViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- query_ptr: *const Query,
- payload: JByteArray,
- encoding_id: jint,
- encoding_schema: /*nullable*/ JString,
-) {
- let _ = || -> ZResult<()> {
- let query = Arc::from_raw(query_ptr);
- let encoding = decode_encoding(&mut env, encoding_id, &encoding_schema)?;
- query
- .reply_err(decode_byte_array(&env, payload)?)
- .encoding(encoding)
- .wait()
- .map_err(|err| zerror!(err))
- }()
- .map_err(|err| throw_exception!(env, err));
-}
-
-/// Replies with `delete` to a Zenoh [Query] via JNI, freeing the query in the process.
-///
-/// # Parameters:
-/// - `env`: The JNI environment.
-/// - `_class`: The JNI class.
-/// - `query_ptr`: The raw pointer to the Zenoh query.
-/// - `key_expr_ptr`: Nullable key expression pointer associated with the query result. This parameter
-/// is meant to be used with declared key expressions, which have a pointer associated to them.
-/// In case of it being null, then the `key_expr_string` will be used to perform the reply.
-/// - `key_expr_str`: The string representation of the key expression associated with the query result.
-/// - `timestamp_enabled`: A boolean indicating whether the timestamp is enabled.
-/// - `timestamp_ntp_64`: The NTP64 timestamp value.
-/// - `attachment`: Nullable user attachment encoded as a byte array.
-/// - `qos_express`: Whether the reply should be sent with the express flag.
-///
-/// # Safety:
-/// - This function is marked as unsafe due to raw pointer manipulation and JNI interaction.
-/// - It assumes that the provided raw pointer to the Zenoh query is valid and has not been modified or freed.
-/// - May throw a JNI exception in case of failure, which should be handled by the caller.
-/// - The query pointer is freed after calling this function (queries shouldn't be replied more than once),
-/// therefore the query isn't valid anymore after that.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub(crate) unsafe extern "C" fn Java_io_zenoh_jni_JNIQuery_replyDeleteViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- query_ptr: *const Query,
- key_expr_ptr: /*nullable*/ *const KeyExpr<'static>,
- key_expr_str: JString,
- timestamp_enabled: jboolean,
- timestamp_ntp_64: jlong,
- attachment: /*nullable*/ JByteArray,
- qos_express: jboolean,
-) {
- let _ = || -> ZResult<()> {
- let query = Arc::from_raw(query_ptr);
- let key_expr = process_kotlin_key_expr(&mut env, &key_expr_str, key_expr_ptr)?;
- let mut reply_builder = query.reply_del(key_expr);
- if timestamp_enabled != 0 {
- let ts = Timestamp::new(NTP64(timestamp_ntp_64 as u64), ID::rand());
- reply_builder = reply_builder.timestamp(ts)
- }
- if !attachment.is_null() {
- reply_builder = reply_builder.attachment(decode_byte_array(&env, attachment)?);
- }
- reply_builder = reply_builder.express(qos_express != 0);
- reply_builder.wait().map_err(|err| zerror!(err))
- }()
- .map_err(|err| throw_exception!(env, err));
-}
-
-/// Frees the Query via JNI.
-///
-/// Parameters:
-/// - `_env`: The JNI environment.
-/// - `_class`: The JNI class.
-/// - `ptr`: The raw pointer to the Zenoh query ([Query]).
-///
-/// Safety:
-/// - The function is marked as unsafe due to raw pointer manipulation.
-/// - It assumes that the provided query pointer is valid and has not been modified or freed.
-/// - The function takes ownership of the raw pointer and releases the associated memory.
-/// - After calling this function, the query pointer becomes invalid and should not be used anymore.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub(crate) unsafe extern "C" fn Java_io_zenoh_jni_JNIQuery_freePtrViaJNI(
- _env: JNIEnv,
- _: JClass,
- query_ptr: *const Query,
-) {
- Arc::from_raw(query_ptr);
-}
diff --git a/zenoh-jni/src/queryable.rs b/zenoh-jni/src/queryable.rs
deleted file mode 100644
index 5d2ddb1d..00000000
--- a/zenoh-jni/src/queryable.rs
+++ /dev/null
@@ -1,41 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-use std::sync::Arc;
-
-use jni::{objects::JClass, JNIEnv};
-use zenoh::query::Queryable;
-
-/// Frees the [Queryable].
-///
-/// # Parameters:
-/// - `_env`: The JNI environment.
-/// - `_class`: The JNI class.
-/// - `queryable_ptr`: The raw pointer to the Zenoh queryable ([Queryable]).
-///
-/// # Safety:
-/// - The function is marked as unsafe due to raw pointer manipulation.
-/// - It assumes that the provided queryable pointer is valid and has not been modified or freed.
-/// - The function takes ownership of the raw pointer and releases the associated memory.
-/// - After calling this function, the queryable pointer becomes invalid and should not be used anymore.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub(crate) unsafe extern "C" fn Java_io_zenoh_jni_JNIQueryable_freePtrViaJNI(
- _env: JNIEnv,
- _: JClass,
- queryable_ptr: *const Queryable<()>,
-) {
- Arc::from_raw(queryable_ptr);
-}
diff --git a/zenoh-jni/src/sample_callback.rs b/zenoh-jni/src/sample_callback.rs
deleted file mode 100644
index 09181490..00000000
--- a/zenoh-jni/src/sample_callback.rs
+++ /dev/null
@@ -1,138 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-use std::sync::Arc;
-
-use jni::{
- objects::{JByteArray, JObject, JString, JValue},
- sys::jint,
- JNIEnv,
-};
-use zenoh::{
- handlers::{Callback, DefaultHandler},
- liveliness::LivelinessSubscriberBuilder,
- pubsub::SubscriberBuilder,
- sample::Sample,
-};
-
-use crate::{errors::ZResult, utils::*, zerror};
-
-pub(crate) trait SetJniSampleCallback: Sized + HasSampleCallbackSetter {
- unsafe fn set_jni_sample_callback(
- self,
- env: &mut JNIEnv,
- callback: JObject,
- on_close: JObject,
- ) -> ZResult {
- let java_vm = Arc::new(get_java_vm(env)?);
- let callback_global_ref = get_callback_global_ref(env, callback)?;
- let on_close_global_ref = get_callback_global_ref(env, on_close)?;
- let on_close = load_on_close(&java_vm, on_close_global_ref);
-
- let builder = self.set_callback(move |sample: Sample| {
- on_close.noop(); // Moves `on_close` inside the closure so it gets destroyed with the closure
- let _ = || -> ZResult<()> {
- let mut env = java_vm.attach_current_thread_as_daemon().map_err(|err| {
- zerror!("Unable to attach thread for sample callback: {}", err)
- })?;
- let byte_array = bytes_to_java_array(&env, sample.payload())
- .map(|array| env.auto_local(array))?;
-
- let encoding_id: jint = sample.encoding().id() as jint;
- let encoding_schema = match sample.encoding().schema() {
- Some(schema) => slice_to_java_string(&env, schema)?,
- None => JString::default(),
- };
- let kind = sample.kind() as jint;
- let (timestamp, is_valid) = sample
- .timestamp()
- .map(|timestamp| (timestamp.get_time().as_u64(), true))
- .unwrap_or((0, false));
-
- let attachment_bytes = sample
- .attachment()
- .map_or_else(
- || Ok(JByteArray::default()),
- |attachment| bytes_to_java_array(&env, attachment),
- )
- .map(|array| env.auto_local(array))
- .map_err(|err| zerror!("Error processing attachment: {}", err))?;
-
- let key_expr_str = env.auto_local(
- env.new_string(sample.key_expr().to_string())
- .map_err(|err| zerror!("Error processing sample key expr: {}", err))?,
- );
-
- let express = sample.express();
- let priority = sample.priority() as jint;
- let cc = sample.congestion_control() as jint;
-
- env.call_method(
- &callback_global_ref,
- "run",
- "(Ljava/lang/String;[BILjava/lang/String;IJZ[BZII)V",
- &[
- JValue::from(&key_expr_str),
- JValue::from(&byte_array),
- JValue::from(encoding_id),
- JValue::from(&encoding_schema),
- JValue::from(kind),
- JValue::from(timestamp as i64),
- JValue::from(is_valid),
- JValue::from(&attachment_bytes),
- JValue::from(express),
- JValue::from(priority),
- JValue::from(cc),
- ],
- )
- .map_err(|err| zerror!(err))?;
- Ok(())
- }()
- .map_err(|err| tracing::error!("On sample callback error: {err}"));
- });
- Ok(builder)
- }
-}
-
-impl SetJniSampleCallback for T {}
-
-pub(crate) trait HasSampleCallbackSetter {
- type BuilderWithCallback;
-
- fn set_callback(self, callback: F) -> Self::BuilderWithCallback
- where
- F: Fn(Sample) + Send + Sync + 'static;
-}
-
-impl<'a, 'b> HasSampleCallbackSetter for SubscriberBuilder<'a, 'b, DefaultHandler> {
- type BuilderWithCallback = SubscriberBuilder<'a, 'b, Callback>;
-
- fn set_callback(self, callback: F) -> Self::BuilderWithCallback
- where
- F: Fn(Sample) + Send + Sync + 'static,
- {
- self.callback(callback)
- }
-}
-
-impl<'a, 'b> HasSampleCallbackSetter for LivelinessSubscriberBuilder<'a, 'b, DefaultHandler> {
- type BuilderWithCallback = LivelinessSubscriberBuilder<'a, 'b, Callback>;
-
- fn set_callback(self, callback: F) -> Self::BuilderWithCallback
- where
- F: Fn(Sample) + Send + Sync + 'static,
- {
- self.callback(callback)
- }
-}
diff --git a/zenoh-jni/src/scouting.rs b/zenoh-jni/src/scouting.rs
deleted file mode 100644
index b0a665c1..00000000
--- a/zenoh-jni/src/scouting.rs
+++ /dev/null
@@ -1,113 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-use std::{ptr::null, sync::Arc};
-
-use jni::{
- objects::{GlobalRef, JClass, JList, JObject, JValue},
- sys::jint,
- JNIEnv,
-};
-use zenoh::{config::WhatAmIMatcher, Wait};
-use zenoh::{scouting::Scout, Config};
-
-use crate::utils::{get_callback_global_ref, get_java_vm, load_on_close};
-use crate::{errors::ZResult, throw_exception, zerror};
-
-/// Start a scout.
-///
-/// # Params
-/// - `whatAmI`: Ordinal value of the WhatAmI enum.
-/// - `callback`: Callback to be executed whenever a hello message is received.
-/// - `config_ptr`: Optional config pointer.
-///
-/// Returns a pointer to the scout, which must be freed afterwards.
-/// If starting the scout fails, an exception is thrown on the JVM, and a null pointer is returned.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNIScout_00024Companion_scoutViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- whatAmI: jint,
- callback: JObject,
- on_close: JObject,
- config_ptr: /*nullable=*/ *const Config,
-) -> *const Scout<()> {
- || -> ZResult<*const Scout<()>> {
- let callback_global_ref = get_callback_global_ref(&mut env, callback)?;
- let java_vm = Arc::new(get_java_vm(&mut env)?);
- let on_close_global_ref: GlobalRef = get_callback_global_ref(&mut env, on_close)?;
- let on_close = load_on_close(&java_vm, on_close_global_ref);
- let whatAmIMatcher: WhatAmIMatcher = (whatAmI as u8).try_into().unwrap(); // The validity of the operation is guaranteed on the kotlin layer.
- let config = if config_ptr.is_null() {
- Config::default()
- } else {
- let arc_cfg = Arc::from_raw(config_ptr);
- let config_clone = arc_cfg.as_ref().clone();
- std::mem::forget(arc_cfg);
- config_clone
- };
- zenoh::scout(whatAmIMatcher, config)
- .callback(move |hello| {
- on_close.noop(); // Moves `on_close` inside the closure so it gets destroyed with the closure
- tracing::debug!("Received hello: {hello}");
- let _ = || -> jni::errors::Result<()> {
- let mut env = java_vm.attach_current_thread_as_daemon()?;
- let whatami = hello.whatami() as jint;
- let zenoh_id = env
- .byte_array_from_slice(&hello.zid().to_le_bytes())
- .map(|it| env.auto_local(it))?;
- let locators = env
- .new_object("java/util/ArrayList", "()V", &[])
- .map(|it| env.auto_local(it))?;
- let jlist = JList::from_env(&mut env, &locators)?;
- for value in hello.locators() {
- let locator = env.new_string(value.as_str())?;
- jlist.add(&mut env, &locator)?;
- }
- env.call_method(
- &callback_global_ref,
- "run",
- "(I[BLjava/util/List;)V",
- &[
- JValue::from(whatami),
- JValue::from(&zenoh_id),
- JValue::from(&locators),
- ],
- )?;
- Ok(())
- }()
- .map_err(|err| tracing::error!("Error while scouting: ${err}"));
- })
- .wait()
- .map(|scout| Arc::into_raw(Arc::new(scout)))
- .map_err(|err| zerror!(err))
- }()
- .unwrap_or_else(|err| {
- throw_exception!(env, err);
- null()
- })
-}
-
-/// Frees the scout.
-#[no_mangle]
-#[allow(non_snake_case)]
-pub(crate) unsafe extern "C" fn Java_io_zenoh_jni_JNIScout_00024Companion_freePtrViaJNI(
- _env: JNIEnv,
- _: JClass,
- scout_ptr: *const Scout<()>,
-) {
- Arc::from_raw(scout_ptr);
-}
diff --git a/zenoh-jni/src/session.rs b/zenoh-jni/src/session.rs
deleted file mode 100644
index 4c9702f9..00000000
--- a/zenoh-jni/src/session.rs
+++ /dev/null
@@ -1,1447 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-use std::{mem, ops::Deref, ptr::null, sync::Arc, time::Duration};
-
-use jni::{
- objects::{GlobalRef, JByteArray, JClass, JList, JObject, JString, JValue},
- sys::{jboolean, jbyteArray, jint, jlong, jobject},
- JNIEnv,
-};
-use zenoh::{
- config::Config,
- handlers::Callback,
- key_expr::KeyExpr,
- pubsub::{Publisher, PublisherBuilder, Subscriber, SubscriberBuilder},
- query::{Querier, Query, Queryable, ReplyError, Selector},
- sample::Sample,
- session::{EntityGlobalId, Session, ZenohId},
- Wait,
-};
-
-use crate::owned_object::OwnedObject;
-#[cfg(feature = "zenoh-ext")]
-use jni::sys::jdouble;
-#[cfg(feature = "zenoh-ext")]
-use zenoh_ext::{
- AdvancedPublisher, AdvancedPublisherBuilderExt, AdvancedSubscriber,
- AdvancedSubscriberBuilderExt, CacheConfig, HistoryConfig, MissDetectionConfig, RecoveryConfig,
- RepliesConfig,
-};
-
-use crate::{
- errors::ZResult, key_expr::process_kotlin_key_expr, sample_callback::SetJniSampleCallback,
- throw_exception, utils::*, zerror,
-};
-
-/// Open a Zenoh session via JNI.
-///
-/// It returns an [Arc] raw pointer to the Zenoh Session, which should be stored as a private read-only attribute
-/// of the session object in the Java/Kotlin code. Subsequent calls to other session functions will require
-/// this raw pointer to retrieve the [Session] using `Arc::from_raw`.
-///
-/// If opening the session fails, an exception is thrown on the JVM, and a null pointer is returned.
-///
-/// # Parameters:
-/// - `env`: The JNI environment.
-/// - `_class`: The JNI class (parameter required by the JNI interface but unused).
-/// - `config_path`: Nullable path to the Zenoh config file. If null, the default configuration will be loaded.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNISession_openSessionViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- config_ptr: *const Config,
-) -> *const Session {
- let session = open_session(config_ptr);
- match session {
- Ok(session) => Arc::into_raw(Arc::new(session)),
- Err(err) => {
- tracing::error!("Unable to open session: {}", err);
- throw_exception!(env, zerror!(err));
- null()
- }
- }
-}
-
-/// Open a Zenoh session with the configuration pointed out by `config_path`.
-///
-/// If the config path provided is null then the default configuration is loaded.
-///
-unsafe fn open_session(config_ptr: *const Config) -> ZResult {
- let config = Arc::from_raw(config_ptr);
- let result = zenoh::open(config.as_ref().clone())
- .wait()
- .map_err(|err| zerror!(err));
- mem::forget(config);
- result
-}
-
-/// Open a Zenoh session with a JSON configuration.
-///
-/// It returns an [Arc] raw pointer to the Zenoh Session, which should be stored as a private read-only attribute
-/// of the session object in the Java/Kotlin code. Subsequent calls to other session functions will require
-/// this raw pointer to retrieve the [Session] using `Arc::from_raw`.
-///
-/// If opening the session fails, an exception is thrown on the JVM, and a null pointer is returned.
-///
-/// # Parameters:
-/// - `env`: The JNI environment.
-/// - `_class`: The JNI class (parameter required by the JNI interface but unused).
-/// - `json_config`: Configuration as a JSON string.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub extern "C" fn Java_io_zenoh_jni_JNISession_openSessionWithJsonConfigViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- json_config: JString,
-) -> *const Session {
- let session = open_session_with_json_config(&mut env, json_config);
- match session {
- Ok(session) => Arc::into_raw(Arc::new(session)),
- Err(err) => {
- tracing::error!("Unable to open session: {}", err);
- throw_exception!(env, zerror!(err));
- null()
- }
- }
-}
-
-/// Open a Zenoh session with the provided json configuration.
-///
-fn open_session_with_json_config(env: &mut JNIEnv, json_config: JString) -> ZResult {
- let json_config = decode_string(env, &json_config)?;
- let mut deserializer =
- json5::Deserializer::from_str(&json_config).map_err(|err| zerror!(err))?;
- let config = Config::from_deserializer(&mut deserializer).map_err(|err| match err {
- Ok(c) => zerror!("Invalid configuration: {}", c),
- Err(e) => zerror!("JSON error: {}", e),
- })?;
- zenoh::open(config).wait().map_err(|err| zerror!(err))
-}
-
-/// Open a Zenoh session with a YAML configuration.
-///
-/// It returns an [Arc] raw pointer to the Zenoh Session, which should be stored as a private read-only attribute
-/// of the session object in the Java/Kotlin code. Subsequent calls to other session functions will require
-/// this raw pointer to retrieve the [Session] using `Arc::from_raw`.
-///
-/// If opening the session fails, an exception is thrown on the JVM, and a null pointer is returned.
-///
-/// # Parameters:
-/// - `env`: The JNI environment.
-/// - `_class`: The JNI class (parameter required by the JNI interface but unused).
-/// - `yaml_config`: Configuration as a YAML string.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub extern "C" fn Java_io_zenoh_jni_JNISession_openSessionWithYamlConfigViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- yaml_config: JString,
-) -> *const Session {
- let session = open_session_with_yaml_config(&mut env, yaml_config);
- match session {
- Ok(session) => Arc::into_raw(Arc::new(session)),
- Err(err) => {
- tracing::error!("Unable to open session: {}", err);
- throw_exception!(env, zerror!(err));
- null()
- }
- }
-}
-
-/// Open a Zenoh session with the provided yaml configuration.
-///
-fn open_session_with_yaml_config(env: &mut JNIEnv, yaml_config: JString) -> ZResult {
- let yaml_config = decode_string(env, &yaml_config)?;
- let deserializer = serde_yaml::Deserializer::from_str(&yaml_config);
- let config = Config::from_deserializer(deserializer).map_err(|err| match err {
- Ok(c) => zerror!("Invalid configuration: {}", c),
- Err(e) => zerror!("YAML error: {}", e),
- })?;
- zenoh::open(config).wait().map_err(|err| zerror!(err))
-}
-
-/// Closes a Zenoh session via JNI.
-///
-/// # Parameters:
-/// - `env`: The JNI environment.
-/// - `_class`: The JNI class.
-/// - `session_ptr`: The raw pointer to the Zenoh session.
-///
-/// # Safety:
-/// - The function is marked as unsafe due to raw pointer manipulation and JNI interaction.
-/// - It assumes that the provided session pointer is valid and has not been modified or freed.
-/// - The function may throw a JNI exception in case of failure, which should be handled by the caller.
-/// - After the session is closed, the provided pointer is no more valid.
-///
-#[no_mangle]
-#[allow(non_snake_case, unused)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNISession_closeSessionViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- session_ptr: *const Session,
-) {
- Arc::from_raw(session_ptr);
-}
-
-/// Declare an advanced Zenoh subscriber via JNI.
-///
-/// Parameters:
-/// - `env`: The JNI environment.
-/// - `_class`: The JNI class.
-/// - `key_expr_ptr`: The key expression pointer for the subscriber. May be null in case of using an
-/// undeclared key expression.
-/// - `key_expr_str`: String representation of the key expression to be used to declare the subscriber.
-/// It won't be considered in case a key_expr_ptr to a declared key expression is provided.
-/// - `history_detect_late_publishers` : Enable detection of late joiner publishers and query for their historical data.
-/// Late joiner detection can only be achieved for [`AdvancedPublisher`] that enable publisher detection.
-/// History can only be retransmitted by [`AdvancedPublisher`] that enable cache.
-/// - `history_max_samples` : Specify how many samples to query for each resource. 0 means no limit.
-/// - `history_max_age_seconds` : Specify the maximum age of samples to query. <= 0.0 means no limit.
-/// - `recovery_config_enabled` : Enable missed samples recovery.
-/// - recovery_config_is_heartbeat: If true, use heartbeat mode and subscribe to heartbeats of [`AdvancedPublisher`],
-/// if false - enable periodic queries for not yet received Samples.
-/// - `recovery_query_period_ms` : Specify period for Periodic queries mode.
-/// - `subscriber_detection` : Allow this subscriber to be detected through liveliness.
-/// - `session_ptr`: The raw pointer to the Zenoh session.
-/// - `callback`: The callback function as an instance of the `JNISubscriberCallback` interface in Java/Kotlin.
-/// - `on_close`: A Java/Kotlin `JNIOnCloseCallback` function interface to be called upon closing the subscriber.
-///
-/// Returns:
-/// - A raw pointer to the declared [AdvancedSubscriber]. In case of failure, an exception is thrown and null is returned.
-///
-/// Safety:
-/// - The function is marked as unsafe due to raw pointer manipulation and JNI interaction.
-/// - It assumes that the provided [Session] pointer is valid and has not been modified or freed.
-/// - The [Session] pointer remains valid and the ownership of the [Session] is not transferred,
-/// allowing safe usage of the [Session] after this function call.
-/// - The callback function passed as `callback` must be a valid instance of the `JNISubscriberCallback` interface
-/// in Java/Kotlin, matching the specified signature.
-/// - The function may throw a JNI exception in case of failure, which should be handled by the caller.
-///
-#[cfg(feature = "zenoh-ext")]
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNISession_declareAdvancedSubscriberViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- key_expr_ptr: /*nullable*/ *const KeyExpr<'static>,
- key_expr_str: JString,
- session_ptr: *const Session,
- // HistoryConfig
- history_config_enabled: jboolean,
- history_detect_late_publishers: jboolean,
- history_max_samples: jlong,
- history_max_age_seconds: jdouble,
- // RecoveryConfig
- recovery_config_enabled: jboolean,
- recovery_config_is_heartbeat: jboolean,
- recovery_query_period_ms: jlong,
-
- subscriber_detection: jboolean,
-
- callback: JObject,
- on_close: JObject,
-) -> *const AdvancedSubscriber<()> {
- let session = Arc::from_raw(session_ptr);
- let subscriber_ptr = || -> ZResult<*const AdvancedSubscriber<()>> {
- let mut builder = prepare_subscriber_builder(
- &mut env,
- key_expr_ptr,
- &key_expr_str,
- &session,
- callback,
- on_close,
- "advanced subscriber",
- )?
- .advanced();
-
- if history_config_enabled != 0 {
- let mut history = match history_detect_late_publishers != 0 {
- true => HistoryConfig::default().detect_late_publishers(),
- false => HistoryConfig::default(),
- };
-
- if history_max_samples > 0 {
- history = history.max_samples(
- history_max_samples
- .try_into()
- .map_err(|e: std::num::TryFromIntError| zerror!(e.to_string()))?,
- );
- }
-
- if history_max_age_seconds > 0.0 {
- history = history.max_age(history_max_age_seconds);
- }
-
- builder = builder.history(history);
- }
-
- if recovery_config_enabled != 0 {
- let recovery = if recovery_config_is_heartbeat != 0 {
- RecoveryConfig::default().heartbeat()
- } else {
- let dur = Duration::from_millis(
- recovery_query_period_ms
- .try_into()
- .map_err(|e: std::num::TryFromIntError| zerror!(e.to_string()))?,
- );
- RecoveryConfig::default().periodic_queries(dur)
- };
- builder = builder.recovery(recovery);
- }
-
- if subscriber_detection != 0 {
- builder = builder.subscriber_detection();
- }
-
- builder
- .wait()
- .map(|s| Arc::into_raw(Arc::new(s)))
- .map_err(|err| zerror!("Unable to declare advanced subscriber: {}", err))
- }()
- .unwrap_or_else(|err| {
- throw_exception!(env, err);
- null()
- });
- std::mem::forget(session);
- subscriber_ptr
-}
-
-/// Declare an advanced Zenoh publisher via JNI.
-///
-/// # Parameters:
-/// - `env`: The JNI environment.
-/// - `_class`: The JNI class.
-/// - `key_expr_ptr`: Raw pointer to the [KeyExpr] to be used for the publisher, may be null.
-/// - `key_expr_str`: String representation of the [KeyExpr] to be used for the publisher.
-/// It is only considered when the key_expr_ptr parameter is null, meaning the function is
-/// receiving a key expression that was not declared.
-/// - `session_ptr`: Raw pointer to the Zenoh [Session] to be used for the publisher.
-/// - `congestion_control`: The [zenoh::publisher::CongestionControl] configuration as an ordinal.
-/// - `priority`: The [zenoh::core::Priority] configuration as an ordinal.
-/// - `is_express`: The express config of the publisher (see [zenoh::prelude::QoSBuilderTrait]).
-/// - `reliability`: The reliability value as an ordinal.
-///
-/// - `cache_max_samples` : If > 0 - Attach a cache to this [`AdvancedPublisher`] and specify how many samples to keep for each resource.
-/// - `cache_replies_priority` : The [zenoh::core::Priority] configuration as an ordinal used for cache replies.
-/// - `cache_replies_congestion_control` : The [zenoh::publisher::CongestionControl] configuration as an ordinal used for cache replies.
-/// - `cache_replies_is_express: jboolean` : The express config of the publisher (see [zenoh::prelude::QoSBuilderTrait]) used for cache replies.
-///
-/// - `sample_miss_detection_enabled` : Enables sample miss detection functionality: allow matching
-/// [`AdvancedSubscriber`] to detect lost samples and optionally ask for retransimission. Retransmission can only be achieved if cache is enabled.
-/// - `sample_miss_detection_is_not_heartbeat` : Use sample miss detection without heartbeat
-/// - `sample_miss_detection_heartbeat_ms` : Specify heartbeat period for heartbeat mode.
-/// - `sample_miss_detection_heartbeat_is_sporadic` : determine if heartbeat argument is treated as sporadic
-///
-/// # Returns:
-/// - A raw pointer to the declared [AdvancedPublisher] or null in case of failure.
-///
-/// # Safety:
-/// - The function is marked as unsafe due to raw pointer manipulation and JNI interaction.
-/// - It assumes that the provided [Session] pointer is valid and has not been modified or freed.
-/// - The ownership of the [Session] is not transferred, and the [Session] pointer remains valid
-/// after this function call so it is safe to use it after this call.
-/// - The function may throw an exception in case of failure, which should be handled by the caller.
-///
-#[cfg(feature = "zenoh-ext")]
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNISession_declareAdvancedPublisherViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- key_expr_ptr: /*nullable*/ *const KeyExpr<'static>,
- key_expr_str: JString,
- session_ptr: *const Session,
- congestion_control: jint,
- priority: jint,
- is_express: jboolean,
- reliability: jint,
- // CacheConfig
- cache_enabled: jboolean,
- cache_max_samples: jlong,
- cache_replies_priority: jint,
- cache_replies_congestion_control: jint,
- cache_replies_is_express: jboolean,
- // MissDetectionConfig
- sample_miss_detection_enabled: jboolean,
- sample_miss_detection_enable_heartbeat: jboolean,
- sample_miss_detection_heartbeat_ms: jlong,
- sample_miss_detection_heartbeat_is_sporadic: jboolean,
-
- publisher_detection: jboolean,
-) -> *const AdvancedPublisher<'static> {
- let session = OwnedObject::from_raw(session_ptr);
- let publisher_ptr = || -> ZResult<*const AdvancedPublisher<'static>> {
- let mut builder = prepare_publisher_builder(
- &mut env,
- key_expr_ptr,
- &key_expr_str,
- &session,
- congestion_control,
- priority,
- is_express,
- reliability,
- )?
- .advanced();
-
- // fill CacheConfig
- if cache_enabled != 0 {
- let cache_congestion_control =
- decode_congestion_control(cache_replies_congestion_control)?;
-
- let cache_priority = decode_priority(cache_replies_priority)?;
-
- let replies_config = RepliesConfig::default()
- .priority(cache_priority)
- .congestion_control(cache_congestion_control)
- .express(cache_replies_is_express != 0);
-
- let cache_config = CacheConfig::default()
- .max_samples(
- cache_max_samples
- .try_into()
- .map_err(|e: std::num::TryFromIntError| zerror!(e.to_string()))?,
- )
- .replies_config(replies_config);
-
- builder = builder.cache(cache_config);
- }
-
- // fill MissDetectionConfig
- if sample_miss_detection_enabled != 0 {
- let miss_detection_config = {
- let mut result = MissDetectionConfig::default();
- if sample_miss_detection_enable_heartbeat != 0 {
- let duration = Duration::from_millis(
- sample_miss_detection_heartbeat_ms
- .try_into()
- .map_err(|e: std::num::TryFromIntError| zerror!(e.to_string()))?,
- );
-
- result = match sample_miss_detection_heartbeat_is_sporadic != 0 {
- true => result.sporadic_heartbeat(duration),
- false => result.heartbeat(duration),
- };
- }
- result
- };
- builder = builder.sample_miss_detection(miss_detection_config);
- }
-
- if publisher_detection != 0 {
- builder = builder.publisher_detection();
- }
-
- let result = builder.wait();
- match result {
- Ok(publisher) => Ok(Arc::into_raw(Arc::new(publisher))),
- Err(err) => Err(zerror!(err)),
- }
- }()
- .unwrap_or_else(|err| {
- throw_exception!(env, err);
- null()
- });
- publisher_ptr
-}
-
-/// Declare a Zenoh publisher via JNI.
-///
-/// # Parameters:
-/// - `env`: The JNI environment.
-/// - `_class`: The JNI class.
-/// - `key_expr_ptr`: Raw pointer to the [KeyExpr] to be used for the publisher, may be null.
-/// - `key_expr_str`: String representation of the [KeyExpr] to be used for the publisher.
-/// It is only considered when the key_expr_ptr parameter is null, meaning the function is
-/// receiving a key expression that was not declared.
-/// - `session_ptr`: Raw pointer to the Zenoh [Session] to be used for the publisher.
-/// - `congestion_control`: The [zenoh::publisher::CongestionControl] configuration as an ordinal.
-/// - `priority`: The [zenoh::core::Priority] configuration as an ordinal.
-/// - `is_express`: The express config of the publisher (see [zenoh::prelude::QoSBuilderTrait]).
-/// - `reliability`: The reliability value as an ordinal.
-///
-/// # Returns:
-/// - A raw pointer to the declared Zenoh publisher or null in case of failure.
-///
-/// # Safety:
-/// - The function is marked as unsafe due to raw pointer manipulation and JNI interaction.
-/// - It assumes that the provided session pointer is valid and has not been modified or freed.
-/// - The ownership of the session is not transferred, and the session pointer remains valid
-/// after this function call so it is safe to use it after this call.
-/// - The function may throw an exception in case of failure, which should be handled by the caller.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNISession_declarePublisherViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- key_expr_ptr: /*nullable*/ *const KeyExpr<'static>,
- key_expr_str: JString,
- session_ptr: *const Session,
- congestion_control: jint,
- priority: jint,
- is_express: jboolean,
- reliability: jint,
-) -> *const Publisher<'static> {
- let session = Arc::from_raw(session_ptr);
- let publisher_ptr = || -> ZResult<*const Publisher<'static>> {
- prepare_publisher_builder(
- &mut env,
- key_expr_ptr,
- &key_expr_str,
- &session,
- congestion_control,
- priority,
- is_express,
- reliability,
- )?
- .wait()
- .map(|publisher| Arc::into_raw(Arc::new(publisher)))
- .map_err(|e| zerror!(e))
- }()
- .unwrap_or_else(|err| {
- throw_exception!(env, err);
- null()
- });
- std::mem::forget(session);
- publisher_ptr
-}
-
-#[allow(clippy::too_many_arguments)]
-unsafe fn prepare_publisher_builder<'a, 'b>(
- env: &mut JNIEnv,
- key_expr_ptr: /*nullable*/ *const KeyExpr<'static>,
- key_expr_str: &JString,
- session: &'a Session,
- congestion_control: jint,
- priority: jint,
- is_express: jboolean,
- reliability: jint,
-) -> ZResult> {
- let key_expr = process_kotlin_key_expr(env, key_expr_str, key_expr_ptr)?;
- let congestion_control = decode_congestion_control(congestion_control)?;
- let priority = decode_priority(priority)?;
- let reliability = decode_reliability(reliability)?;
- let builder = session
- .declare_publisher(key_expr)
- .congestion_control(congestion_control)
- .priority(priority)
- .express(is_express != 0)
- .reliability(reliability);
- Ok(builder)
-}
-
-/// Performs a `put` operation in the Zenoh session via JNI.
-///
-/// Parameters:
-/// - `env`: The JNI environment.
-/// - `_class`: The JNI class.
-/// - `key_expr_ptr`: Raw pointer to the [KeyExpr] to be used for the operation, may be null.
-/// - `key_expr_str`: String representation of the [KeyExpr] to be used for the operation.
-/// It is only considered when the key_expr_ptr parameter is null, meaning the function is
-/// receiving a key expression that was not declared.
-/// - `session_ptr`: Raw pointer to the [Session] to be used for the operation.
-/// - `payload`: The payload to send through the network.
-/// - `encoding_id`: The encoding id of the payload.
-/// - `encoding_schema`: Optional encoding schema, may be null.
-/// - `congestion_control`: The [CongestionControl] mechanism specified.
-/// - `priority`: The [Priority] mechanism specified.
-/// - `is_express`: The express flag.
-/// - `attachment`: Optional attachment encoded into a byte array. May be null.
-/// - `reliability`: The reliability value as an ordinal.
-///
-/// Safety:
-/// - The function is marked as unsafe due to raw pointer manipulation and JNI interaction.
-/// - It assumes that the provided session pointer is valid and has not been modified or freed.
-/// - The session pointer remains valid and the ownership of the session is not transferred,
-/// allowing safe usage of the session after this function call.
-/// - The function may throw an exception in case of failure, which should be handled by the Java/Kotlin caller.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNISession_putViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- key_expr_ptr: /*nullable*/ *const KeyExpr<'static>,
- key_expr_str: JString,
- session_ptr: *const Session,
- payload: JByteArray,
- encoding_id: jint,
- encoding_schema: JString,
- congestion_control: jint,
- priority: jint,
- is_express: jboolean,
- attachment: JByteArray,
- reliability: jint,
-) {
- let session = Arc::from_raw(session_ptr);
- let _ = || -> ZResult<()> {
- let key_expr = process_kotlin_key_expr(&mut env, &key_expr_str, key_expr_ptr)?;
- let payload = decode_byte_array(&env, payload)?;
- let encoding = decode_encoding(&mut env, encoding_id, &encoding_schema)?;
- let congestion_control = decode_congestion_control(congestion_control)?;
- let priority = decode_priority(priority)?;
- let reliability = decode_reliability(reliability)?;
-
- let mut put_builder = session
- .put(&key_expr, payload)
- .congestion_control(congestion_control)
- .encoding(encoding)
- .express(is_express != 0)
- .priority(priority)
- .reliability(reliability);
-
- if !attachment.is_null() {
- let attachment = decode_byte_array(&env, attachment)?;
- put_builder = put_builder.attachment(attachment)
- }
-
- put_builder
- .wait()
- .map(|_| tracing::trace!("Put on '{key_expr}'"))
- .map_err(|err| zerror!(err))
- }()
- .map_err(|err| throw_exception!(env, err));
- std::mem::forget(session);
-}
-
-/// Performs a `delete` operation in the Zenoh session via JNI.
-///
-/// Parameters:
-/// - `env`: The JNI environment.
-/// - `_class`: The JNI class.
-/// - `key_expr_ptr`: Raw pointer to the [KeyExpr] to be used for the operation, may be null.
-/// - `key_expr_str`: String representation of the [KeyExpr] to be used for the operation.
-/// It is only considered when the key_expr_ptr parameter is null, meaning the function is
-/// receiving a key expression that was not declared.
-/// - `session_ptr`: Raw pointer to the [Session] to be used for the operation.
-/// - `congestion_control`: The [CongestionControl] mechanism specified.
-/// - `priority`: The [Priority] mechanism specified.
-/// - `is_express`: The express flag.
-/// - `attachment`: Optional attachment encoded into a byte array. May be null.
-/// - `reliability`: The reliability value as an ordinal.
-///
-/// Safety:
-/// - The function is marked as unsafe due to raw pointer manipulation and JNI interaction.
-/// - It assumes that the provided session pointer is valid and has not been modified or freed.
-/// - The session pointer remains valid and the ownership of the session is not transferred,
-/// allowing safe usage of the session after this function call.
-/// - The function may throw a JNI exception or a Session exception in case of failure, which
-/// should be handled by the Java/Kotlin caller.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNISession_deleteViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- key_expr_ptr: /*nullable*/ *const KeyExpr<'static>,
- key_expr_str: JString,
- session_ptr: *const Session,
- congestion_control: jint,
- priority: jint,
- is_express: jboolean,
- attachment: JByteArray,
- reliability: jint,
-) {
- let session = Arc::from_raw(session_ptr);
- let _ = || -> ZResult<()> {
- let key_expr = process_kotlin_key_expr(&mut env, &key_expr_str, key_expr_ptr)?;
- let congestion_control = decode_congestion_control(congestion_control)?;
- let priority = decode_priority(priority)?;
- let reliability = decode_reliability(reliability)?;
-
- let mut delete_builder = session
- .delete(&key_expr)
- .congestion_control(congestion_control)
- .express(is_express != 0)
- .priority(priority)
- .reliability(reliability);
-
- if !attachment.is_null() {
- let attachment = decode_byte_array(&env, attachment)?;
- delete_builder = delete_builder.attachment(attachment)
- }
-
- delete_builder
- .wait()
- .map(|_| tracing::trace!("Delete on '{key_expr}'"))
- .map_err(|err| zerror!(err))
- }()
- .map_err(|err| throw_exception!(env, err));
- std::mem::forget(session);
-}
-
-/// Declare a Zenoh subscriber via JNI.
-///
-/// Parameters:
-/// - `env`: The JNI environment.
-/// - `_class`: The JNI class.
-/// - `key_expr_ptr`: The key expression pointer for the subscriber. May be null in case of using an
-/// undeclared key expression.
-/// - `key_expr_str`: String representation of the key expression to be used to declare the subscriber.
-/// It won't be considered in case a key_expr_ptr to a declared key expression is provided.
-/// - `session_ptr`: The raw pointer to the Zenoh session.
-/// - `callback`: The callback function as an instance of the `JNISubscriberCallback` interface in Java/Kotlin.
-/// - `on_close`: A Java/Kotlin `JNIOnCloseCallback` function interface to be called upon closing the subscriber.
-///
-/// Returns:
-/// - A raw pointer to the declared Zenoh subscriber. In case of failure, an exception is thrown and null is returned.
-///
-/// Safety:
-/// - The function is marked as unsafe due to raw pointer manipulation and JNI interaction.
-/// - It assumes that the provided session pointer is valid and has not been modified or freed.
-/// - The session pointer remains valid and the ownership of the session is not transferred,
-/// allowing safe usage of the session after this function call.
-/// - The callback function passed as `callback` must be a valid instance of the `JNISubscriberCallback` interface
-/// in Java/Kotlin, matching the specified signature.
-/// - The function may throw a JNI exception in case of failure, which should be handled by the caller.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNISession_declareSubscriberViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- key_expr_ptr: /*nullable*/ *const KeyExpr<'static>,
- key_expr_str: JString,
- session_ptr: *const Session,
- callback: JObject,
- on_close: JObject,
-) -> *const Subscriber<()> {
- let session = Arc::from_raw(session_ptr);
- let subscriber_ptr = || -> ZResult<*const Subscriber<()>> {
- prepare_subscriber_builder(
- &mut env,
- key_expr_ptr,
- &key_expr_str,
- &session,
- callback,
- on_close,
- "subscriber",
- )?
- .wait()
- .map(|s| Arc::into_raw(Arc::new(s)))
- .map_err(|err| zerror!("Unable to declare subscriber: {}", err))
- }()
- .unwrap_or_else(|err| {
- throw_exception!(env, err);
- null()
- });
- std::mem::forget(session);
- subscriber_ptr
-}
-
-unsafe fn prepare_subscriber_builder<'a, 'b>(
- env: &mut JNIEnv,
- key_expr_ptr: /*nullable*/ *const KeyExpr<'static>,
- key_expr_str: &JString,
- session: &'a Session,
- callback: JObject,
- on_close: JObject,
- entity_name: &str,
-) -> ZResult>> {
- let key_expr = process_kotlin_key_expr(env, key_expr_str, key_expr_ptr)?;
- tracing::debug!("Declaring {entity_name} on '{}'...", key_expr);
-
- let builder = session
- .declare_subscriber(key_expr.to_owned())
- .set_jni_sample_callback(env, callback, on_close)?;
-
- tracing::debug!("{entity_name} declared on '{}'.", key_expr);
- Ok(builder)
-}
-
-/// Declare a Zenoh querier via JNI.
-///
-/// This function is meant to be called from Java/Kotlin code through JNI.
-///
-/// Parameters:
-/// - `env`: The JNI environment.
-/// - `_class`: The JNI class.
-/// - `key_expr_ptr`: A raw pointer to the [KeyExpr] to be used for the querier. May be null in case of using an
-/// undeclared key expression.
-/// - `key_expr_str`: String representation of the key expression to be used to declare the querier.
-/// It won't be considered in case a key_expr_ptr to a declared key expression is provided.
-/// - `target`: The ordinal value of the query target enum value.
-/// - `consolidation`: The ordinal value of the consolidation enum value.
-/// - `congestion_control`: The ordinal value of the congestion control enum value.
-/// - `priority`: The ordinal value of the priority enum value.
-/// - `is_express`: The boolean express value of the QoS provided.
-/// - `timeout_ms`: The timeout in milliseconds.
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNISession_declareQuerierViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- key_expr_ptr: /*nullable*/ *const KeyExpr<'static>,
- key_expr_str: JString,
- session_ptr: *const Session,
- target: jint,
- consolidation: jint,
- congestion_control: jint,
- priority: jint,
- is_express: jboolean,
- timeout_ms: jlong,
- accept_replies: jint,
-) -> *const Querier<'static> {
- let session = Arc::from_raw(session_ptr);
- || -> ZResult<*const Querier<'static>> {
- let key_expr = process_kotlin_key_expr(&mut env, &key_expr_str, key_expr_ptr)?;
- let query_target = decode_query_target(target)?;
- let consolidation = decode_consolidation(consolidation)?;
- let congestion_control = decode_congestion_control(congestion_control)?;
- let timeout = Duration::from_millis(timeout_ms as u64);
- let priority = decode_priority(priority)?;
- let reply_key_expr = decode_reply_key_expr(accept_replies)?;
- tracing::debug!("Declaring querier on '{}'...", key_expr);
-
- let querier = session
- .declare_querier(key_expr.to_owned())
- .congestion_control(congestion_control)
- .consolidation(consolidation)
- .express(is_express != 0)
- .target(query_target)
- .priority(priority)
- .timeout(timeout)
- .accept_replies(reply_key_expr)
- .wait()
- .map_err(|err| zerror!(err))?;
-
- tracing::debug!("Querier declared on '{}'.", key_expr);
- std::mem::forget(session);
- Ok(Arc::into_raw(Arc::new(querier)))
- }()
- .unwrap_or_else(|err| {
- throw_exception!(env, err);
- null()
- })
-}
-
-/// Declare a Zenoh queryable via JNI.
-///
-/// This function is meant to be called from Java/Kotlin code through JNI.
-///
-/// Parameters:
-/// - `env`: The JNI environment.
-/// - `_class`: The JNI class.
-/// - `key_expr_ptr`: A raw pointer to the [KeyExpr] to be used for the queryable. May be null in case of using an
-/// undeclared key expression.
-/// - `key_expr_str`: String representation of the key expression to be used to declare the queryable.
-/// It won't be considered in case a key_expr_ptr to a declared key expression is provided.
-/// - `session_ptr`: A raw pointer to the Zenoh [Session] to be used to declare the queryable.
-/// - `callback`: The callback function as an instance of the `JNIQueryableCallback` interface in Java/Kotlin.
-/// - `on_close`: A Java/Kotlin `JNIOnCloseCallback` function interface to be called upon closing the queryable.
-/// - `complete`: The completeness of the queryable.
-///
-/// Returns:
-/// - A raw pointer to the declared Zenoh queryable. In case of failure, an exception is thrown and null is returned.
-///
-/// Safety:
-/// - The function is marked as unsafe due to raw pointer manipulation and JNI interaction.
-/// - It assumes that the provided session pointer is valid and has not been modified or freed.
-/// - The session pointer remains valid and the ownership of the session is not transferred,
-/// allowing safe usage of the session after this function call.
-/// - The callback function passed as `callback` must be a valid instance of the `JNIQueryableCallback` interface
-/// in Java/Kotlin, matching the specified signature.
-/// - The function may throw a JNI exception in case of failure, which should be handled by the caller.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNISession_declareQueryableViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- key_expr_ptr: /*nullable*/ *const KeyExpr<'static>,
- key_expr_str: JString,
- session_ptr: *const Session,
- callback: JObject,
- on_close: JObject,
- complete: jboolean,
-) -> *const Queryable<()> {
- let session = Arc::from_raw(session_ptr);
- let query_ptr = || -> ZResult<*const Queryable<()>> {
- let java_vm = Arc::new(get_java_vm(&mut env)?);
- let callback_global_ref = get_callback_global_ref(&mut env, callback)?;
- let on_close_global_ref = get_callback_global_ref(&mut env, on_close)?;
- let key_expr = process_kotlin_key_expr(&mut env, &key_expr_str, key_expr_ptr)?;
- let complete = complete != 0;
- let on_close = load_on_close(&java_vm, on_close_global_ref);
- tracing::debug!("Declaring queryable through JNI on {}", key_expr);
- let builder = session
- .declare_queryable(key_expr)
- .callback(move |query: Query| {
- on_close.noop(); // Does nothing, but moves `on_close` inside the closure so it gets destroyed with the closure
- let env = match java_vm.attach_current_thread_as_daemon() {
- Ok(env) => env,
- Err(err) => {
- tracing::error!("Unable to attach thread for queryable callback: {}", err);
- return;
- }
- };
-
- tracing::debug!("Receiving query through JNI: {}", query.to_string());
- match on_query(env, query, &callback_global_ref) {
- Ok(_) => tracing::debug!("Queryable callback called successfully."),
- Err(err) => tracing::error!("Error calling queryable callback: {}", err),
- }
- })
- .complete(complete);
-
- let queryable = builder
- .wait()
- .map_err(|err| zerror!("Error declaring queryable: {}", err))?;
- Ok(Arc::into_raw(Arc::new(queryable)))
- }()
- .unwrap_or_else(|err| {
- throw_exception!(env, err);
- null()
- });
- std::mem::forget(session);
- query_ptr
-}
-
-fn on_query(mut env: JNIEnv, query: Query, callback_global_ref: &GlobalRef) -> ZResult<()> {
- let selector_params_jstr = env
- .new_string(query.parameters().to_string())
- .map(|value| env.auto_local(value))
- .map_err(|err| {
- zerror!(
- "Could not create a JString through JNI for the Query key expression. {}",
- err
- )
- })?;
-
- let (payload, encoding_id, encoding_schema) = if let Some(payload) = query.payload() {
- let encoding = query.encoding().unwrap(); //If there is payload, there is encoding.
- let encoding_id = encoding.id() as jint;
- let encoding_schema = encoding
- .schema()
- .map_or_else(
- || Ok(JString::default()),
- |schema| slice_to_java_string(&env, schema),
- )
- .map(|value| env.auto_local(value))?;
- let byte_array = bytes_to_java_array(&env, payload).map(|value| env.auto_local(value))?;
- (byte_array, encoding_id, encoding_schema)
- } else {
- (
- env.auto_local(JByteArray::default()),
- 0,
- env.auto_local(JString::default()),
- )
- };
-
- let attachment_bytes = query
- .attachment()
- .map_or_else(
- || Ok(JByteArray::default()),
- |attachment| bytes_to_java_array(&env, attachment),
- )
- .map(|value| env.auto_local(value))
- .map_err(|err| zerror!("Error processing attachment of reply: {}.", err))?;
-
- let key_expr_str = env
- .new_string(query.key_expr().to_string())
- .map(|key_expr| env.auto_local(key_expr))
- .map_err(|err| {
- zerror!(
- "Could not create a JString through JNI for the Query key expression: {}.",
- err
- )
- })?;
-
- let query_ptr = Arc::into_raw(Arc::new(query));
-
- let result = env
- .call_method(
- callback_global_ref,
- "run",
- "(Ljava/lang/String;Ljava/lang/String;[BILjava/lang/String;[BJ)V",
- &[
- JValue::from(&key_expr_str),
- JValue::from(&selector_params_jstr),
- JValue::from(&payload),
- JValue::from(encoding_id),
- JValue::from(&encoding_schema),
- JValue::from(&attachment_bytes),
- JValue::from(query_ptr as jlong),
- ],
- )
- .map(|_| ())
- .map_err(|err| {
- // The callback could not be invoked, therefore the created kotlin query object won't be
- // used. Since `query_ptr` as well as `key_expr_ptr` was created within this function
- // and remains unaltered, it is safe to reclaim ownership of the memory by converting
- // the raw pointers back into an `Arc` and freeing the memory.
- unsafe {
- Arc::from_raw(query_ptr);
- };
- _ = env.exception_describe();
- zerror!(err)
- });
- result
-}
-
-/// Declare a [KeyExpr] through a [Session] via JNI.
-///
-/// # Parameters:
-/// - `env`: The JNI environment.
-/// - `_class`: The JNI class.
-/// - `session_ptr`: A raw pointer to the Zenoh [Session] from which to declare the key expression.
-/// - `key_expr_str`: A Java String with the intended key expression.
-///
-/// # Returns:
-/// - A raw pointer to the declared key expression. In case of failure, an exception is thrown and null is returned.
-///
-/// # Safety:
-/// - The function is marked as unsafe due to raw pointer manipulation and JNI interaction.
-/// - It assumes that the provided session pointer is valid and has not been modified or freed.
-/// - The session pointer remains valid and the ownership of the session is not transferred,
-/// allowing safe usage of the session after this function call.
-/// - The function may throw an exception in case of failure, which should be handled by the caller.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNISession_declareKeyExprViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- session_ptr: *const Session,
- key_expr_str: JString,
-) -> *const KeyExpr<'static> {
- let session: Arc = Arc::from_raw(session_ptr);
- let key_expr_ptr = || -> ZResult<*const KeyExpr<'static>> {
- let key_expr_str = decode_string(&mut env, &key_expr_str)?;
- let key_expr = session
- .declare_keyexpr(key_expr_str.to_owned())
- .wait()
- .map_err(|err| {
- zerror!(
- "Unable to declare key expression '{}': {}",
- key_expr_str,
- err
- )
- })?;
- Ok(Arc::into_raw(Arc::new(key_expr)))
- }()
- .unwrap_or_else(|err| {
- throw_exception!(env, err);
- null()
- });
- mem::forget(session);
- key_expr_ptr
-}
-
-/// Undeclare a [KeyExpr] through a [Session] via JNI.
-///
-/// The key expression must have been previously declared on the specified session, otherwise an
-/// exception is thrown.
-///
-/// This functions frees the key expression pointer provided.
-///
-/// # Parameters:
-/// - `env`: The JNI environment.
-/// - `_class`: The JNI class.
-/// - `session_ptr`: A raw pointer to the Zenoh [Session] from which to undeclare the key expression.
-/// - `key_expr_ptr`: A raw pointer to the [KeyExpr] to undeclare.
-///
-/// # Safety:
-/// - The function is marked as unsafe due to raw pointer manipulation and JNI interaction.
-/// - It assumes that the provided session and keyexpr pointers are valid and have not been modified or freed.
-/// - The session pointer remains valid after this function call.
-/// - The key expression pointer is voided after this function call.
-/// - The function may throw an exception in case of failure, which should be handled by the caller.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNISession_undeclareKeyExprViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- session_ptr: *const Session,
- key_expr_ptr: *const KeyExpr<'static>,
-) {
- let session = Arc::from_raw(session_ptr);
- let key_expr = Arc::from_raw(key_expr_ptr);
- let key_expr_clone = key_expr.deref().clone();
- match session.undeclare(key_expr_clone).wait() {
- Ok(_) => {}
- Err(err) => {
- throw_exception!(
- env,
- zerror!("Unable to declare key expression '{}': {}", key_expr, err)
- );
- }
- }
- std::mem::forget(session);
- // `key_expr` is intentionally left to be freed by Rust
-}
-
-/// Performs a `get` operation in the Zenoh session via JNI with Value.
-///
-/// # Parameters:
-/// - `env`: The JNI environment.
-/// - `_class`: The JNI class.
-/// - `key_expr_ptr`: Raw pointer to a declared [KeyExpr] to be used for the query. May be null in case
-/// of using a non declared key expression, in which case the `key_expr_str` parameter will be used instead.
-/// - `key_expr_str`: String representation of the key expression to be used to declare the query. It is not
-/// considered if a `key_expr_ptr` is provided.
-/// - `selector_params`: Optional parameters of the selector.
-/// - `session_ptr`: A raw pointer to the Zenoh [Session].
-/// - `callback`: A Java/Kotlin callback to be called upon receiving a reply.
-/// - `on_close`: A Java/Kotlin `JNIOnCloseCallback` function interface to be called when no more replies will be received.
-/// - `timeout_ms`: The timeout in milliseconds.
-/// - `target`: The query target as the ordinal of the enum.
-/// - `consolidation`: The consolidation mode as the ordinal of the enum.
-/// - `attachment`: An optional attachment encoded into a byte array.
-/// - `payload`: Optional payload for the query.
-/// - `encoding_id`: The encoding of the payload.
-/// - `encoding_schema`: The encoding schema of the payload, may be null.
-/// - `congestion_control`: The ordinal value of the congestion control enum value.
-/// - `priority`: The ordinal value of the priority enum value.
-/// - `is_express`: The boolean express value of the QoS provided.
-///
-/// Safety:
-/// - The function is marked as unsafe due to raw pointer manipulation and JNI interaction.
-/// - It assumes that the provided session pointer is valid and has not been modified or freed.
-/// - The session pointer remains valid and the ownership of the session is not transferred,
-/// allowing safe usage of the session after this function call.
-/// - The function may throw a JNI exception in case of failure, which should be handled by the caller.
-///
-/// Throws:
-/// - An exception in case of failure handling the query.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNISession_getViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- key_expr_ptr: /*nullable*/ *const KeyExpr<'static>,
- key_expr_str: JString,
- selector_params: /*nullable*/ JString,
- session_ptr: *const Session,
- callback: JObject,
- on_close: JObject,
- timeout_ms: jlong,
- target: jint,
- consolidation: jint,
- attachment: /*nullable*/ JByteArray,
- payload: /*nullable*/ JByteArray,
- encoding_id: jint,
- encoding_schema: /*nullable*/ JString,
- congestion_control: jint,
- priority: jint,
- is_express: jboolean,
- accept_replies: jint,
-) {
- let session = Arc::from_raw(session_ptr);
- let _ = || -> ZResult<()> {
- let key_expr = process_kotlin_key_expr(&mut env, &key_expr_str, key_expr_ptr)?;
- let java_vm = Arc::new(get_java_vm(&mut env)?);
- let callback_global_ref = get_callback_global_ref(&mut env, callback)?;
- let on_close_global_ref = get_callback_global_ref(&mut env, on_close)?;
- let query_target = decode_query_target(target)?;
- let consolidation = decode_consolidation(consolidation)?;
- let timeout = Duration::from_millis(timeout_ms as u64);
- let congestion_control = decode_congestion_control(congestion_control)?;
- let priority = decode_priority(priority)?;
- let reply_key_expr = decode_reply_key_expr(accept_replies)?;
- let on_close = load_on_close(&java_vm, on_close_global_ref);
- let selector_params = if selector_params.is_null() {
- String::new()
- } else {
- decode_string(&mut env, &selector_params)?
- };
- let selector = Selector::owned(&key_expr, selector_params);
- let mut get_builder = session
- .get(selector)
- .congestion_control(congestion_control)
- .priority(priority)
- .express(is_express != 0)
- .callback(move |reply| {
- || -> ZResult<()> {
- on_close.noop(); // Does nothing, but moves `on_close` inside the closure so it gets destroyed with the closure
- tracing::debug!("Receiving reply through JNI: {:?}", reply);
- let mut env = java_vm.attach_current_thread_as_daemon().map_err(|err| {
- zerror!("Unable to attach thread for GET query callback: {}.", err)
- })?;
-
- match reply.result() {
- Ok(sample) => on_reply_success(
- &mut env,
- reply.replier_id(),
- sample,
- &callback_global_ref,
- ),
- Err(error) => on_reply_error(
- &mut env,
- reply.replier_id(),
- error,
- &callback_global_ref,
- ),
- }
- }()
- .unwrap_or_else(|err| tracing::error!("Error on get callback: {err}"));
- })
- .target(query_target)
- .timeout(timeout)
- .consolidation(consolidation)
- .accept_replies(reply_key_expr);
-
- if !payload.is_null() {
- let encoding = decode_encoding(&mut env, encoding_id, &encoding_schema)?;
- get_builder = get_builder.encoding(encoding);
- get_builder = get_builder.payload(decode_byte_array(&env, payload)?);
- }
-
- if !attachment.is_null() {
- let attachment = decode_byte_array(&env, attachment)?;
- get_builder = get_builder.attachment::>(attachment);
- }
-
- get_builder
- .wait()
- .map(|_| tracing::trace!("Performing get on '{key_expr}'.",))
- .map_err(|err| zerror!(err))
- }()
- .map_err(|err| throw_exception!(env, err));
- std::mem::forget(session);
-}
-
-pub(crate) fn on_reply_success(
- env: &mut JNIEnv,
- replier_id: Option,
- sample: &Sample,
- callback_global_ref: &GlobalRef,
-) -> ZResult<()> {
- let zenoh_id = replier_id
- .map_or_else(
- || Ok(JByteArray::default()),
- |replier_id| {
- env.byte_array_from_slice(&replier_id.zid().to_le_bytes())
- .map_err(|err| zerror!(err))
- },
- )
- .map(|value| env.auto_local(value))?;
- let eid = replier_id.map_or_else(|| 0, |replier_id| replier_id.eid() as jint);
-
- let byte_array =
- bytes_to_java_array(env, sample.payload()).map(|value| env.auto_local(value))?;
- let encoding: jint = sample.encoding().id() as jint;
- let encoding_schema = sample
- .encoding()
- .schema()
- .map_or_else(
- || Ok(JString::default()),
- |schema| slice_to_java_string(env, schema),
- )
- .map(|value| env.auto_local(value))?;
- let kind = sample.kind() as jint;
-
- let (timestamp, is_valid) = sample
- .timestamp()
- .map(|timestamp| (timestamp.get_time().as_u64(), true))
- .unwrap_or((0, false));
-
- let attachment_bytes = sample
- .attachment()
- .map_or_else(
- || Ok(JByteArray::default()),
- |attachment| bytes_to_java_array(env, attachment),
- )
- .map(|value| env.auto_local(value))
- .map_err(|err| zerror!("Error processing attachment of reply: {}.", err))?;
-
- let key_expr_str = env
- .new_string(sample.key_expr().to_string())
- .map(|value| env.auto_local(value))
- .map_err(|err| {
- zerror!(
- "Could not create a JString through JNI for the Sample key expression. {}",
- err
- )
- })?;
-
- let express = sample.express();
- let priority = sample.priority() as jint;
- let cc = sample.congestion_control() as jint;
-
- let result = match env.call_method(
- callback_global_ref,
- "run",
- "([BIZLjava/lang/String;[BILjava/lang/String;IJZ[BZII)V",
- &[
- JValue::from(&zenoh_id),
- JValue::from(eid),
- JValue::from(true),
- JValue::from(&key_expr_str),
- JValue::from(&byte_array),
- JValue::from(encoding),
- JValue::from(&encoding_schema),
- JValue::from(kind),
- JValue::from(timestamp as i64),
- JValue::from(is_valid),
- JValue::from(&attachment_bytes),
- JValue::from(express),
- JValue::from(priority),
- JValue::from(cc),
- ],
- ) {
- Ok(_) => Ok(()),
- Err(err) => {
- _ = env.exception_describe();
- Err(zerror!("On GET callback error: {}", err))
- }
- };
- result
-}
-
-pub(crate) fn on_reply_error(
- env: &mut JNIEnv,
- replier_id: Option,
- reply_error: &ReplyError,
- callback_global_ref: &GlobalRef,
-) -> ZResult<()> {
- let zenoh_id = replier_id
- .map_or_else(
- || Ok(JByteArray::default()),
- |replier_id| {
- env.byte_array_from_slice(&replier_id.zid().to_le_bytes())
- .map_err(|err| zerror!(err))
- },
- )
- .map(|value| env.auto_local(value))?;
- let eid = replier_id.map_or_else(|| 0, |replier_id| replier_id.eid() as jint);
-
- let payload =
- bytes_to_java_array(env, reply_error.payload()).map(|value| env.auto_local(value))?;
- let encoding_id: jint = reply_error.encoding().id() as jint;
- let encoding_schema = reply_error
- .encoding()
- .schema()
- .map_or_else(
- || Ok(JString::default()),
- |schema| slice_to_java_string(env, schema),
- )
- .map(|value| env.auto_local(value))?;
- let result = match env.call_method(
- callback_global_ref,
- "run",
- "([BIZLjava/lang/String;[BILjava/lang/String;IJZ[BZII)V",
- &[
- JValue::from(&zenoh_id),
- JValue::from(eid),
- JValue::from(false),
- JValue::from(&JString::default()),
- JValue::from(&payload),
- JValue::from(encoding_id),
- JValue::from(&encoding_schema),
- // The remaining parameters aren't used in case of replying error, so we set them to default.
- JValue::from(0 as jint),
- JValue::from(0_i64),
- JValue::from(false),
- JValue::from(&JByteArray::default()),
- JValue::from(false),
- JValue::from(0 as jint),
- JValue::from(0 as jint),
- ],
- ) {
- Ok(_) => Ok(()),
- Err(err) => {
- _ = env.exception_describe();
- Err(zerror!("On GET callback error: {}", err))
- }
- };
- result
-}
-
-/// Returns a list of zenoh ids as byte arrays corresponding to the peers connected to the session provided.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNISession_getPeersZidViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- session_ptr: *const Session,
-) -> jobject {
- let session = Arc::from_raw(session_ptr);
- let ids = {
- let peers_zid = session.info().peers_zid().wait();
- let ids = peers_zid.collect::>();
- ids_to_java_list(&mut env, ids).map_err(|err| zerror!(err))
- }
- .unwrap_or_else(|err| {
- throw_exception!(env, err);
- JObject::default().as_raw()
- });
- std::mem::forget(session);
- ids
-}
-
-/// Returns a list of zenoh ids as byte arrays corresponding to the routers connected to the session provided.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNISession_getRoutersZidViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- session_ptr: *const Session,
-) -> jobject {
- let session = Arc::from_raw(session_ptr);
- let ids = {
- let peers_zid = session.info().routers_zid().wait();
- let ids = peers_zid.collect::>();
- ids_to_java_list(&mut env, ids).map_err(|err| zerror!(err))
- }
- .unwrap_or_else(|err| {
- throw_exception!(env, err);
- JObject::default().as_raw()
- });
- std::mem::forget(session);
- ids
-}
-
-/// Returns the Zenoh ID as a byte array of the session.
-#[no_mangle]
-#[allow(non_snake_case)]
-pub unsafe extern "C" fn Java_io_zenoh_jni_JNISession_getZidViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- session_ptr: *const Session,
-) -> jbyteArray {
- let session = Arc::from_raw(session_ptr);
- let ids = {
- let zid = session.info().zid().wait();
- env.byte_array_from_slice(&zid.to_le_bytes())
- .map(|x| x.as_raw())
- .map_err(|err| zerror!(err))
- }
- .unwrap_or_else(|err| {
- throw_exception!(env, err);
- JByteArray::default().as_raw()
- });
- std::mem::forget(session);
- ids
-}
-
-fn ids_to_java_list(env: &mut JNIEnv, ids: Vec) -> jni::errors::Result {
- let array_list = env.new_object("java/util/ArrayList", "()V", &[])?;
- let jlist = JList::from_env(env, &array_list)?;
- for id in ids {
- let value = &mut env.byte_array_from_slice(&id.to_le_bytes())?;
- jlist.add(env, value)?;
- }
- Ok(array_list.as_raw())
-}
diff --git a/zenoh-jni/src/subscriber.rs b/zenoh-jni/src/subscriber.rs
deleted file mode 100644
index 3462ec7e..00000000
--- a/zenoh-jni/src/subscriber.rs
+++ /dev/null
@@ -1,41 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-use std::sync::Arc;
-
-use jni::{objects::JClass, JNIEnv};
-use zenoh::pubsub::Subscriber;
-
-/// Frees the [Subscriber].
-///
-/// # Parameters:
-/// - `_env`: The JNI environment.
-/// - `_class`: The JNI class.
-/// - `subscriber_ptr`: The raw pointer to the Zenoh subscriber ([Subscriber]).
-///
-/// # Safety:
-/// - The function is marked as unsafe due to raw pointer manipulation.
-/// - It assumes that the provided subscriber pointer is valid and has not been modified or freed.
-/// - The function takes ownership of the raw pointer and releases the associated memory.
-/// - After calling this function, the subscriber pointer becomes invalid and should not be used anymore.
-///
-#[no_mangle]
-#[allow(non_snake_case)]
-pub(crate) unsafe extern "C" fn Java_io_zenoh_jni_JNISubscriber_freePtrViaJNI(
- _env: JNIEnv,
- _: JClass,
- subscriber_ptr: *const Subscriber<()>,
-) {
- Arc::from_raw(subscriber_ptr);
-}
diff --git a/zenoh-jni/src/utils.rs b/zenoh-jni/src/utils.rs
deleted file mode 100644
index e60add13..00000000
--- a/zenoh-jni/src/utils.rs
+++ /dev/null
@@ -1,189 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-use std::sync::Arc;
-
-use crate::{errors::ZResult, throw_exception, zerror};
-use jni::{
- objects::{JByteArray, JObject, JString},
- sys::jint,
- JNIEnv, JavaVM,
-};
-use zenoh::{
- bytes::{Encoding, ZBytes},
- internal::buffers::ZSlice,
- qos::{CongestionControl, Priority, Reliability},
- query::{ConsolidationMode, QueryTarget, ReplyKeyExpr},
-};
-
-/// Converts a JString into a rust String.
-pub(crate) fn decode_string(env: &mut JNIEnv, string: &JString) -> ZResult {
- let binding = env
- .get_string(string)
- .map_err(|err| zerror!("Error while retrieving JString: {}", err))?;
- let value = binding
- .to_str()
- .map_err(|err| zerror!("Error decoding JString: {}", err))?;
- Ok(value.to_string())
-}
-
-pub(crate) fn decode_encoding(
- env: &mut JNIEnv,
- encoding: jint,
- schema: &JString,
-) -> ZResult {
- let schema: Option = if schema.is_null() {
- None
- } else {
- Some(decode_string(env, schema)?.into_bytes().into())
- };
- let encoding_id =
- u16::try_from(encoding).map_err(|err| zerror!("Failed to decode encoding: {}", err))?;
- Ok(Encoding::new(encoding_id, schema))
-}
-
-pub(crate) fn get_java_vm(env: &mut JNIEnv) -> ZResult {
- env.get_java_vm()
- .map_err(|err| zerror!("Unable to retrieve JVM reference: {}", err))
-}
-
-pub(crate) fn get_callback_global_ref(
- env: &mut JNIEnv,
- callback: JObject,
-) -> crate::errors::ZResult {
- env.new_global_ref(callback)
- .map_err(|err| zerror!("Unable to get reference to the provided callback: {}", err))
-}
-
-/// Helper function to convert a JByteArray into a Vec.
-pub(crate) fn decode_byte_array(env: &JNIEnv<'_>, payload: JByteArray) -> ZResult> {
- let payload_len = env
- .get_array_length(&payload)
- .map(|length| length as usize)
- .map_err(|err| zerror!(err))?;
- let mut buff = vec![0; payload_len];
- env.get_byte_array_region(payload, 0, &mut buff[..])
- .map_err(|err| zerror!(err))?;
- let buff: Vec = unsafe { std::mem::transmute::, Vec>(buff) };
- Ok(buff)
-}
-
-pub(crate) fn decode_priority(priority: jint) -> ZResult {
- Priority::try_from(priority as u8).map_err(|err| zerror!("Error retrieving priority: {}.", err))
-}
-
-pub(crate) fn decode_congestion_control(congestion_control: jint) -> ZResult {
- match congestion_control {
- 1 => Ok(CongestionControl::Block),
- 0 => Ok(CongestionControl::Drop),
- value => Err(zerror!("Unknown congestion control '{}'.", value)),
- }
-}
-
-pub(crate) fn decode_query_target(target: jint) -> ZResult {
- match target {
- 0 => Ok(QueryTarget::BestMatching),
- 1 => Ok(QueryTarget::All),
- 2 => Ok(QueryTarget::AllComplete),
- value => Err(zerror!("Unable to decode QueryTarget '{}'.", value)),
- }
-}
-
-pub(crate) fn decode_reply_key_expr(reply_key_expr: jint) -> ZResult {
- match reply_key_expr {
- 0 => Ok(ReplyKeyExpr::Any),
- 1 => Ok(ReplyKeyExpr::MatchingQuery),
- value => Err(zerror!("Unable to decode ReplyKeyExpr '{}'.", value)),
- }
-}
-
-pub(crate) fn decode_consolidation(consolidation: jint) -> ZResult {
- match consolidation {
- 0 => Ok(ConsolidationMode::Auto),
- 1 => Ok(ConsolidationMode::None),
- 2 => Ok(ConsolidationMode::Monotonic),
- 3 => Ok(ConsolidationMode::Latest),
- value => Err(zerror!("Unable to decode consolidation '{}'", value)),
- }
-}
-
-pub(crate) fn decode_reliability(reliability: jint) -> ZResult {
- match reliability {
- 0 => Ok(Reliability::BestEffort),
- 1 => Ok(Reliability::Reliable),
- value => Err(zerror!("Unable to decode reliability '{}'", value)),
- }
-}
-
-pub(crate) fn bytes_to_java_array<'a>(env: &JNIEnv<'a>, slice: &ZBytes) -> ZResult> {
- env.byte_array_from_slice(&slice.to_bytes())
- .map_err(|err| zerror!(err))
-}
-
-pub(crate) fn slice_to_java_string<'a>(env: &JNIEnv<'a>, slice: &ZSlice) -> ZResult> {
- env.new_string(
- String::from_utf8(slice.to_vec())
- .map_err(|err| zerror!("Unable to decode string: {}", err))?,
- )
- .map_err(|err| zerror!(err))
-}
-
-/// A type that calls a function when dropped
-pub(crate) struct CallOnDrop(core::mem::MaybeUninit);
-impl CallOnDrop {
- /// Constructs a value that calls `f` when dropped.
- pub fn new(f: F) -> Self {
- Self(core::mem::MaybeUninit::new(f))
- }
- /// Does nothing, but tricks closures into moving the value inside,
- /// so that the closure's destructor will call `drop(self)`.
- pub fn noop(&self) {}
-}
-impl Drop for CallOnDrop {
- fn drop(&mut self) {
- // Take ownership of the closure that is always initialized,
- // since the only constructor uses `MaybeUninit::new`
- let f = unsafe { self.0.assume_init_read() };
- // Call the now owned function
- f();
- }
-}
-
-pub(crate) fn load_on_close(
- java_vm: &Arc,
- on_close_global_ref: jni::objects::GlobalRef,
-) -> CallOnDrop {
- CallOnDrop::new({
- let java_vm = java_vm.clone();
- move || {
- let mut env = match java_vm.attach_current_thread_as_daemon() {
- Ok(env) => env,
- Err(err) => {
- tracing::error!("Unable to attach thread for 'onClose' callback: {}", err);
- return;
- }
- };
- match env.call_method(on_close_global_ref, "run", "()V", &[]) {
- Ok(_) => (),
- Err(err) => {
- _ = env.exception_describe();
- throw_exception!(
- env,
- zerror!("Error while running 'onClose' callback: {}", err)
- );
- }
- }
- }
- })
-}
diff --git a/zenoh-jni/src/zbytes.rs b/zenoh-jni/src/zbytes.rs
deleted file mode 100644
index 0a1b0443..00000000
--- a/zenoh-jni/src/zbytes.rs
+++ /dev/null
@@ -1,571 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-use jni::{
- objects::{AutoLocal, JByteArray, JClass, JList, JMap, JObject, JString, JValue},
- sys::jobject,
- JNIEnv,
-};
-use zenoh::bytes::ZBytes;
-use zenoh_ext::{VarInt, ZDeserializeError, ZDeserializer, ZSerializer};
-
-use crate::{
- errors::ZResult,
- throw_exception,
- utils::{bytes_to_java_array, decode_byte_array},
- zerror,
-};
-
-enum KotlinType {
- Boolean,
- String,
- ByteArray,
- Byte,
- Short,
- Int,
- Long,
- Float,
- Double,
- UByte,
- UShort,
- UInt,
- ULong,
- List(Box),
- Map(Box, Box),
- Pair(Box, Box),
- Triple(Box, Box, Box),
-}
-
-fn decode_ktype(env: &mut JNIEnv, ktype: JObject) -> ZResult {
- let classifier_obj = env
- .call_method(
- &ktype,
- "getClassifier",
- "()Lkotlin/reflect/KClassifier;",
- &[],
- )
- .map_err(|err| zerror!(err))?
- .l()
- .map_err(|err| zerror!(err))?;
- let classifier_obj = AutoLocal::new(classifier_obj, env);
-
- let kclass_class = env
- .find_class("kotlin/reflect/KClass")
- .map_err(|err| zerror!(err))?;
- let is_kclass = env
- .is_instance_of(&classifier_obj, kclass_class)
- .map_err(|err| zerror!(err))?;
- if is_kclass {
- let qualified_name_jobject = env
- .call_method(
- &classifier_obj,
- "getQualifiedName",
- "()Ljava/lang/String;",
- &[],
- )
- .map_err(|err| zerror!(err))?
- .l()
- .map_err(|err| zerror!(err))?;
-
- let qualified_name: String = env
- .get_string(&JString::from(qualified_name_jobject))
- .map_err(|err| zerror!(err))?
- .into();
-
- match qualified_name.as_str() {
- "kotlin.Boolean" => Ok(KotlinType::Boolean),
- "kotlin.String" => Ok(KotlinType::String),
- "kotlin.ByteArray" => Ok(KotlinType::ByteArray),
- "kotlin.Byte" => Ok(KotlinType::Byte),
- "kotlin.Short" => Ok(KotlinType::Short),
- "kotlin.Int" => Ok(KotlinType::Int),
- "kotlin.Long" => Ok(KotlinType::Long),
- "kotlin.Float" => Ok(KotlinType::Float),
- "kotlin.Double" => Ok(KotlinType::Double),
- "kotlin.UByte" => Ok(KotlinType::UByte),
- "kotlin.UShort" => Ok(KotlinType::UShort),
- "kotlin.UInt" => Ok(KotlinType::UInt),
- "kotlin.ULong" => Ok(KotlinType::ULong),
- "kotlin.collections.List" => Ok(KotlinType::List(Box::new(decode_ktype_arg(
- env, &ktype, 0,
- )?))),
- "kotlin.collections.Map" => Ok(KotlinType::Map(
- Box::new(decode_ktype_arg(env, &ktype, 0)?),
- Box::new(decode_ktype_arg(env, &ktype, 1)?),
- )),
- "kotlin.Pair" => Ok(KotlinType::Pair(
- Box::new(decode_ktype_arg(env, &ktype, 0)?),
- Box::new(decode_ktype_arg(env, &ktype, 1)?),
- )),
- "kotlin.Triple" => Ok(KotlinType::Triple(
- Box::new(decode_ktype_arg(env, &ktype, 0)?),
- Box::new(decode_ktype_arg(env, &ktype, 1)?),
- Box::new(decode_ktype_arg(env, &ktype, 2)?),
- )),
- _ => Err(zerror!("Unsupported type: {}", qualified_name)),
- }
- } else {
- Err(zerror!("Classifier is not a KClass"))
- }
-}
-
-fn decode_ktype_arg(env: &mut JNIEnv, ktype: &JObject, idx: i32) -> ZResult {
- let arguments = env
- .call_method(ktype, "getArguments", "()Ljava/util/List;", &[])
- .map_err(|err| zerror!(err))?
- .l()
- .map_err(|err| zerror!(err))?;
- let arg = env
- .call_method(
- &arguments,
- "get",
- "(I)Ljava/lang/Object;",
- &[JValue::Int(idx)],
- )
- .map_err(|err| zerror!(err))?
- .l()
- .map_err(|err| zerror!(err))?;
- let ktype = env
- .call_method(arg, "getType", "()Lkotlin/reflect/KType;", &[])
- .map_err(|err| zerror!(err))?
- .l()
- .map_err(|err| zerror!(err))?;
- decode_ktype(env, ktype)
-}
-
-#[no_mangle]
-#[allow(non_snake_case)]
-pub extern "C" fn Java_io_zenoh_jni_JNIZBytes_serializeViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- any: JObject,
- ktype: JObject,
-) -> jobject {
- || -> ZResult {
- let mut serializer = ZSerializer::new();
- let ktype = decode_ktype(&mut env, ktype)?;
- serialize(&mut env, &mut serializer, any, &ktype)?;
- let zbytes = serializer.finish();
-
- let byte_array = bytes_to_java_array(&env, &zbytes).map_err(|err| zerror!(err))?;
- let zbytes_obj = env
- .new_object(
- "io/zenoh/bytes/ZBytes",
- "([B)V",
- &[JValue::Object(&JObject::from(byte_array))],
- )
- .map_err(|err| zerror!(err))?;
-
- Ok(zbytes_obj.as_raw())
- }()
- .unwrap_or_else(|err| {
- throw_exception!(env, err);
- JObject::default().as_raw()
- })
-}
-
-fn serialize(
- env: &mut JNIEnv,
- serializer: &mut ZSerializer,
- any: JObject,
- ktype: &KotlinType,
-) -> ZResult<()> {
- match ktype {
- KotlinType::Byte => {
- let byte_value = env
- .call_method(any, "byteValue", "()B", &[])
- .map_err(|err| zerror!(err))?
- .b()
- .map_err(|err| zerror!(err))?;
- serializer.serialize(byte_value);
- }
- KotlinType::Short => {
- let short_value = env
- .call_method(any, "shortValue", "()S", &[])
- .map_err(|err| zerror!(err))?
- .s()
- .map_err(|err| zerror!(err))?;
- serializer.serialize(short_value);
- }
- KotlinType::Int => {
- let int_value = env
- .call_method(any, "intValue", "()I", &[])
- .map_err(|err| zerror!(err))?
- .i()
- .map_err(|err| zerror!(err))?;
- serializer.serialize(int_value);
- }
- KotlinType::Long => {
- let long_value = env
- .call_method(any, "longValue", "()J", &[])
- .map_err(|err| zerror!(err))?
- .j()
- .map_err(|err| zerror!(err))?;
- serializer.serialize(long_value);
- }
- KotlinType::Float => {
- let float_value = env
- .call_method(any, "floatValue", "()F", &[])
- .map_err(|err| zerror!(err))?
- .f()
- .map_err(|err| zerror!(err))?;
- serializer.serialize(float_value);
- }
- KotlinType::Double => {
- let double_value = env
- .call_method(any, "doubleValue", "()D", &[])
- .map_err(|err| zerror!(err))?
- .d()
- .map_err(|err| zerror!(err))?;
- serializer.serialize(double_value);
- }
- KotlinType::Boolean => {
- let boolean_value = env
- .call_method(any, "booleanValue", "()Z", &[])
- .map_err(|err| zerror!(err))?
- .z()
- .map_err(|err| zerror!(err))?;
- serializer.serialize(boolean_value);
- }
- KotlinType::String => {
- let jstring = JString::from(any);
- let string_value: String = env.get_string(&jstring).map_err(|err| zerror!(err))?.into();
- serializer.serialize(string_value);
- }
- KotlinType::ByteArray => {
- let jbyte_array = JByteArray::from(any);
- let bytes = decode_byte_array(env, jbyte_array).map_err(|err| zerror!(err))?;
- serializer.serialize(bytes);
- }
- KotlinType::UByte => {
- let byte = env
- .get_field(any, "data", "B")
- .map_err(|err| zerror!(err))?
- .b()
- .map_err(|err| zerror!(err))?;
- serializer.serialize(byte as u8);
- }
- KotlinType::UShort => {
- let short = env
- .get_field(any, "data", "S")
- .map_err(|err| zerror!(err))?
- .s()
- .map_err(|err| zerror!(err))?;
- serializer.serialize(short as u16);
- }
- KotlinType::UInt => {
- let int = env
- .get_field(any, "data", "I")
- .map_err(|err| zerror!(err))?
- .i()
- .map_err(|err| zerror!(err))?;
- serializer.serialize(int as u32);
- }
- KotlinType::ULong => {
- let long = env
- .get_field(any, "data", "J")
- .map_err(|err| zerror!(err))?
- .j()
- .map_err(|err| zerror!(err))?;
- serializer.serialize(long as u64);
- }
- KotlinType::List(kotlin_type) => {
- let jlist: JList<'_, '_, '_> =
- JList::from_env(env, &any).map_err(|err| zerror!(err))?;
- let mut iterator = jlist.iter(env).map_err(|err| zerror!(err))?;
- let list_size = jlist.size(env).unwrap();
- serializer.serialize(zenoh_ext::VarInt(list_size as usize));
- while let Some(value) = iterator.next(env).map_err(|err| zerror!(err))? {
- serialize(env, serializer, value, kotlin_type)?;
- }
- }
- KotlinType::Map(key_type, value_type) => {
- let jmap = JMap::from_env(env, &any).map_err(|err| zerror!(err))?;
-
- let map_size = env
- .call_method(&jmap, "size", "()I", &[])
- .map_err(|err| zerror!(err))?
- .i()
- .map_err(|err| zerror!(err))?;
-
- serializer.serialize(zenoh_ext::VarInt(map_size as usize));
-
- let mut iterator = jmap.iter(env).map_err(|err| zerror!(err))?;
- while let Some((key, value)) = iterator.next(env).map_err(|err| zerror!(err))? {
- serialize(env, serializer, key, key_type)?;
- serialize(env, serializer, value, value_type)?;
- }
- }
- KotlinType::Pair(first_type, second_type) => {
- let first = env
- .call_method(&any, "getFirst", "()Ljava/lang/Object;", &[])
- .map_err(|err| zerror!(err))?
- .l()
- .map_err(|err| zerror!(err))?;
- let second = env
- .call_method(&any, "getSecond", "()Ljava/lang/Object;", &[])
- .map_err(|err| zerror!(err))?
- .l()
- .map_err(|err| zerror!(err))?;
- serialize(env, serializer, first, first_type)?;
- serialize(env, serializer, second, second_type)?;
- }
- KotlinType::Triple(first_type, second_type, third_type) => {
- let first = env
- .call_method(&any, "getFirst", "()Ljava/lang/Object;", &[])
- .map_err(|err| zerror!(err))?
- .l()
- .map_err(|err| zerror!(err))?;
- let second = env
- .call_method(&any, "getSecond", "()Ljava/lang/Object;", &[])
- .map_err(|err| zerror!(err))?
- .l()
- .map_err(|err| zerror!(err))?;
- let third = env
- .call_method(&any, "getThird", "()Ljava/lang/Object;", &[])
- .map_err(|err| zerror!(err))?
- .l()
- .map_err(|err| zerror!(err))?;
- serialize(env, serializer, first, first_type)?;
- serialize(env, serializer, second, second_type)?;
- serialize(env, serializer, third, third_type)?;
- }
- }
- Ok(())
-}
-
-#[no_mangle]
-#[allow(non_snake_case)]
-pub extern "C" fn Java_io_zenoh_jni_JNIZBytes_deserializeViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- zbytes: JObject,
- ktype: JObject,
-) -> jobject {
- || -> ZResult {
- let payload = env
- .get_field(zbytes, "bytes", "[B")
- .map_err(|err| zerror!(err))?;
- let decoded_bytes: Vec =
- decode_byte_array(&env, JByteArray::from(payload.l().unwrap()))?;
- let zbytes = ZBytes::from(decoded_bytes);
- let mut deserializer = ZDeserializer::new(&zbytes);
- let ktype = decode_ktype(&mut env, ktype)?;
- let obj = deserialize(&mut env, &mut deserializer, &ktype)?;
- if !deserializer.done() {
- return Err(zerror!(ZDeserializeError));
- }
- Ok(obj)
- }()
- .unwrap_or_else(|err| {
- throw_exception!(env, err);
- JObject::default().as_raw()
- })
-}
-
-fn deserialize(
- env: &mut JNIEnv,
- deserializer: &mut ZDeserializer,
- ktype: &KotlinType,
-) -> ZResult {
- match ktype {
- KotlinType::Byte => {
- let byte = deserializer
- .deserialize::()
- .map_err(|err| zerror!(err))?;
- let byte_obj = env
- .new_object("java/lang/Byte", "(B)V", &[JValue::Byte(byte)])
- .map_err(|err| zerror!(err))?;
- Ok(byte_obj.as_raw())
- }
- KotlinType::Short => {
- let short = deserializer
- .deserialize::()
- .map_err(|err| zerror!(err))?;
- let short_obj = env
- .new_object("java/lang/Short", "(S)V", &[JValue::Short(short)])
- .map_err(|err| zerror!(err))?;
- Ok(short_obj.as_raw())
- }
- KotlinType::Int => {
- let integer = deserializer
- .deserialize::()
- .map_err(|err| zerror!(err))?;
- let integer_obj = env
- .new_object("java/lang/Integer", "(I)V", &[JValue::Int(integer)])
- .map_err(|err| zerror!(err))?;
- Ok(integer_obj.as_raw())
- }
- KotlinType::Long => {
- let long = deserializer
- .deserialize::()
- .map_err(|err| zerror!(err))?;
- let long_obj = env
- .new_object("java/lang/Long", "(J)V", &[JValue::Long(long)])
- .map_err(|err| zerror!(err))?;
- Ok(long_obj.as_raw())
- }
- KotlinType::Float => {
- let float = deserializer
- .deserialize::()
- .map_err(|err| zerror!(err))?;
- let float_obj = env
- .new_object("java/lang/Float", "(F)V", &[JValue::Float(float)])
- .map_err(|err| zerror!(err))?;
- Ok(float_obj.as_raw())
- }
- KotlinType::Double => {
- let double = deserializer
- .deserialize::()
- .map_err(|err| zerror!(err))?;
- let double_obj = env
- .new_object("java/lang/Double", "(D)V", &[JValue::Double(double)])
- .map_err(|err| zerror!(err))?;
- Ok(double_obj.as_raw())
- }
- KotlinType::Boolean => {
- let boolean_value = deserializer
- .deserialize::()
- .map_err(|err| zerror!(err))?;
- let jboolean = if boolean_value { 1u8 } else { 0u8 };
- let boolean_obj = env
- .new_object("java/lang/Boolean", "(Z)V", &[JValue::Bool(jboolean)])
- .map_err(|err| zerror!(err))?;
- Ok(boolean_obj.as_raw())
- }
- KotlinType::String => {
- let deserialized_string = deserializer
- .deserialize::()
- .map_err(|err| zerror!(err))?;
- let jstring = env
- .new_string(&deserialized_string)
- .map_err(|err| zerror!(err))?;
- Ok(jstring.into_raw())
- }
- KotlinType::ByteArray => {
- let deserialized_bytes = deserializer
- .deserialize::>()
- .map_err(|err| zerror!(err))?;
- let jbytes = env
- .byte_array_from_slice(deserialized_bytes.as_slice())
- .map_err(|err| zerror!(err))?;
- Ok(jbytes.into_raw())
- }
- KotlinType::UByte => {
- let ubyte = deserializer
- .deserialize::()
- .map_err(|err| zerror!(err))?;
- let ubyte_obj = env
- .new_object("kotlin/UByte", "(B)V", &[JValue::Byte(ubyte as i8)])
- .map_err(|err| zerror!(err))?;
- Ok(ubyte_obj.as_raw())
- }
- KotlinType::UShort => {
- let ushort = deserializer
- .deserialize::()
- .map_err(|err| zerror!(err))?;
- let ushort_obj = env
- .new_object("kotlin/UShort", "(S)V", &[JValue::Short(ushort as i16)])
- .map_err(|err| zerror!(err))?;
- Ok(ushort_obj.as_raw())
- }
- KotlinType::UInt => {
- let uint = deserializer
- .deserialize::()
- .map_err(|err| zerror!(err))?;
- let uint_obj = env
- .new_object("kotlin/UInt", "(I)V", &[JValue::Int(uint as i32)])
- .map_err(|err| zerror!(err))?;
- Ok(uint_obj.as_raw())
- }
- KotlinType::ULong => {
- let ulong = deserializer
- .deserialize::()
- .map_err(|err| zerror!(err))?;
- let ulong_obj = env
- .new_object("kotlin/ULong", "(J)V", &[JValue::Long(ulong as i64)])
- .map_err(|err| zerror!(err))?;
- Ok(ulong_obj.as_raw())
- }
- KotlinType::List(kotlin_type) => {
- let list_size = deserializer
- .deserialize::>()
- .map_err(|err| zerror!(err))?
- .0;
- let array_list = env
- .new_object("java/util/ArrayList", "()V", &[])
- .map_err(|err| zerror!(err))?;
- let jlist = JList::from_env(env, &array_list).map_err(|err| zerror!(err))?;
-
- for _ in 0..list_size {
- let item = deserialize(env, deserializer, kotlin_type)?;
- let item_obj = unsafe { JObject::from_raw(item) };
- jlist.add(env, &item_obj).map_err(|err| zerror!(err))?;
- }
- Ok(array_list.as_raw())
- }
- KotlinType::Map(key_type, value_type) => {
- let map_size = deserializer
- .deserialize::>()
- .map_err(|err| zerror!(err))?
- .0;
- let map = env
- .new_object("java/util/HashMap", "()V", &[])
- .map_err(|err| zerror!(err))?;
- let jmap = JMap::from_env(env, &map).map_err(|err| zerror!(err))?;
-
- for _ in 0..map_size {
- let key = deserialize(env, deserializer, key_type)?;
- let key_obj = unsafe { JObject::from_raw(key) };
- let value = deserialize(env, deserializer, value_type)?;
- let value_obj = unsafe { JObject::from_raw(value) };
- jmap.put(env, &key_obj, &value_obj)
- .map_err(|err| zerror!(err))?;
- }
- Ok(map.as_raw())
- }
- KotlinType::Pair(first_type, second_type) => {
- let first = deserialize(env, deserializer, first_type)?;
- let second = deserialize(env, deserializer, second_type)?;
- let pair = env
- .new_object(
- "kotlin/Pair",
- "(Ljava/lang/Object;Ljava/lang/Object;)V",
- &[
- JValue::Object(&unsafe { JObject::from_raw(first) }),
- JValue::Object(&unsafe { JObject::from_raw(second) }),
- ],
- )
- .map_err(|err| zerror!(err))?;
- Ok(pair.as_raw())
- }
- KotlinType::Triple(first_type, second_type, third_type) => {
- let first = deserialize(env, deserializer, first_type)?;
- let second = deserialize(env, deserializer, second_type)?;
- let third = deserialize(env, deserializer, third_type)?;
- let triple = env
- .new_object(
- "kotlin/Triple",
- "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V",
- &[
- JValue::Object(&unsafe { JObject::from_raw(first) }),
- JValue::Object(&unsafe { JObject::from_raw(second) }),
- JValue::Object(&unsafe { JObject::from_raw(third) }),
- ],
- )
- .map_err(|err| zerror!(err))?;
- Ok(triple.as_raw())
- }
- }
-}
diff --git a/zenoh-jni/src/zenoh_id.rs b/zenoh-jni/src/zenoh_id.rs
deleted file mode 100644
index 6647f86f..00000000
--- a/zenoh-jni/src/zenoh_id.rs
+++ /dev/null
@@ -1,42 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-use crate::{errors::ZResult, throw_exception, utils::decode_byte_array, zerror};
-use jni::{
- objects::{JByteArray, JClass, JString},
- sys::jstring,
- JNIEnv,
-};
-use zenoh::session::ZenohId;
-
-/// Returns the string representation of a ZenohID.
-#[no_mangle]
-#[allow(non_snake_case)]
-pub extern "C" fn Java_io_zenoh_jni_JNIZenohId_toStringViaJNI(
- mut env: JNIEnv,
- _class: JClass,
- zenoh_id: JByteArray,
-) -> jstring {
- || -> ZResult {
- let bytes = decode_byte_array(&env, zenoh_id)?;
- let zenohid = ZenohId::try_from(bytes.as_slice()).map_err(|err| zerror!(err))?;
- env.new_string(zenohid.to_string())
- .map_err(|err| zerror!(err))
- }()
- .unwrap_or_else(|err| {
- throw_exception!(env, err);
- JString::default()
- })
- .as_raw()
-}
diff --git a/zenoh-kotlin/build.gradle.kts b/zenoh-kotlin/build.gradle.kts
index f17c3e73..6c5e766b 100644
--- a/zenoh-kotlin/build.gradle.kts
+++ b/zenoh-kotlin/build.gradle.kts
@@ -12,8 +12,6 @@
// ZettaScale Zenoh Team,
//
-import com.nishtahir.CargoExtension
-
plugins {
kotlin("multiplatform")
kotlin("plugin.serialization")
@@ -24,19 +22,13 @@ plugins {
}
val androidEnabled = project.findProperty("android")?.toString()?.toBoolean() == true
-val release = project.findProperty("release")?.toString()?.toBoolean() == true
// If the publication is meant to be done on a remote repository (Maven central).
// Modifying this property will affect the release workflows!
val isRemotePublication = project.findProperty("remotePublication")?.toString()?.toBoolean() == true
-var buildMode = if (release) BuildMode.RELEASE else BuildMode.DEBUG
-
if (androidEnabled) {
apply(plugin = "com.android.library")
- apply(plugin = "org.mozilla.rust-android-gradle.rust-android")
-
- configureCargo()
configureAndroid()
}
@@ -60,7 +52,7 @@ kotlin {
implementation("commons-net:commons-net:3.9.0")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0")
- implementation("org.jetbrains.kotlin:kotlin-reflect")
+ implementation("org.eclipse.zenoh:zenoh-jni-runtime:${property("zenohJniRuntimeVersion")}")
}
}
val commonTest by getting {
@@ -71,25 +63,21 @@ kotlin {
implementation("org.junit.jupiter:junit-jupiter-params:5.10.0")
}
}
+ // jvmAndAndroidMain is an intermediate source set between commonMain and both jvmMain/androidMain.
+ // It holds code that uses kotlin-reflect — available on JVM and Android (ART),
+ // but absent on Kotlin/Native and Kotlin/JS targets.
+ val jvmAndAndroidMain by creating { dependsOn(commonMain) }
+ val jvmMain by getting {
+ dependsOn(jvmAndAndroidMain)
+ }
if (androidEnabled) {
+ val androidMain by getting { dependsOn(jvmAndAndroidMain) }
val androidUnitTest by getting {
dependencies {
implementation(kotlin("test-junit"))
}
}
}
- val jvmMain by getting {
- if (isRemotePublication) {
- // The line below is intended to load the native libraries that are crosscompiled on GitHub actions when publishing a JVM package.
- resources.srcDir("../jni-libs").include("*/**")
- } else {
- resources.srcDir("../zenoh-jni/target/$buildMode").include(arrayListOf("*.dylib", "*.so", "*.dll"))
- }
- }
-
- val jvmTest by getting {
- resources.srcDir("../zenoh-jni/target/$buildMode").include(arrayListOf("*.dylib", "*.so", "*.dll"))
- }
}
val javadocJar by tasks.registering(Jar::class) {
@@ -164,65 +152,6 @@ tasks.withType().configureEach {
dependsOn(tasks.withType())
}
-tasks.withType {
- doFirst {
- // The line below is added for the Android Unit tests which are equivalent to the JVM tests.
- // For them to work we need to specify the path to the native library as a system property and not as a jvmArg.
- systemProperty("java.library.path", "../zenoh-jni/target/$buildMode")
- }
-}
-
-tasks.whenObjectAdded {
- if ((this.name == "mergeDebugJniLibFolders" || this.name == "mergeReleaseJniLibFolders")) {
- this.dependsOn("cargoBuild")
- }
-}
-
-tasks.named("compileKotlinJvm") {
- dependsOn("buildZenohJni")
-}
-
-tasks.register("buildZenohJni") {
- doLast {
- if (!isRemotePublication) {
- // This is intended for local publications. For publications done through GitHub workflows,
- // the zenoh-jni build is achieved and loaded differently from the CI
- buildZenohJNI(buildMode)
- }
- }
-}
-
-fun buildZenohJNI(mode: BuildMode = BuildMode.DEBUG) {
- val cargoCommand = mutableListOf("cargo", "build")
-
- if (mode == BuildMode.RELEASE) {
- cargoCommand.add("--release")
- }
-
- val result = project.exec {
- commandLine(*(cargoCommand.toTypedArray()), "--manifest-path", "../zenoh-jni/Cargo.toml")
- }
-
- if (result.exitValue != 0) {
- throw GradleException("Failed to build Zenoh-JNI.")
- }
-
- Thread.sleep(1000)
-}
-
-enum class BuildMode {
- DEBUG {
- override fun toString(): String {
- return "debug"
- }
- },
- RELEASE {
- override fun toString(): String {
- return "release"
- }
- }
-}
-
fun Project.configureAndroid() {
extensions.configure("android") {
namespace = "io.zenoh"
@@ -260,20 +189,3 @@ fun Project.configureAndroid() {
}
}
}
-
-fun Project.configureCargo() {
- extensions.configure("cargo") {
- pythonCommand = "python3"
- module = "../zenoh-jni"
- libname = "zenoh-jni"
- targetIncludes = arrayOf("libzenoh_jni.so")
- targetDirectory = "../zenoh-jni/target/"
- profile = "release"
- targets = arrayListOf(
- "arm",
- "arm64",
- "x86",
- "x86_64",
- )
- }
-}
diff --git a/zenoh-kotlin/src/androidMain/kotlin/io.zenoh/Zenoh.kt b/zenoh-kotlin/src/androidMain/kotlin/io.zenoh/Zenoh.kt
deleted file mode 100644
index 74d42e51..00000000
--- a/zenoh-kotlin/src/androidMain/kotlin/io.zenoh/Zenoh.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-package io.zenoh
-
-/**
- * Static singleton class to load the Zenoh native library once and only once, as well as the logger in function of the
- * log level configuration.
- */
-internal actual object ZenohLoad {
- private const val ZENOH_LIB_NAME = "zenoh_jni"
-
- init {
- System.loadLibrary(ZENOH_LIB_NAME)
- }
-}
diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/Config.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/Config.kt
index a6f69f44..1a653c37 100644
--- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/Config.kt
+++ b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/Config.kt
@@ -132,7 +132,7 @@ class Config internal constructor(internal val jniConfig: JNIConfig) {
* Returns the default config.
*/
fun default(): Config {
- return JNIConfig.loadDefaultConfig()
+ return Config(JNIConfig.loadDefault())
}
/**
@@ -143,7 +143,7 @@ class Config internal constructor(internal val jniConfig: JNIConfig) {
* @return A result with the [Config].
*/
fun fromFile(file: File): Result {
- return JNIConfig.loadConfigFile(file)
+ return runCatching { Config(JNIConfig.loadFromFile(file.toPath().toString())) }
}
/**
@@ -154,7 +154,7 @@ class Config internal constructor(internal val jniConfig: JNIConfig) {
* @return A result with the [Config].
*/
fun fromFile(path: Path): Result {
- return JNIConfig.loadConfigFile(path)
+ return runCatching { Config(JNIConfig.loadFromFile(path.toString())) }
}
/**
@@ -190,7 +190,7 @@ class Config internal constructor(internal val jniConfig: JNIConfig) {
* @return A result with the [Config].
*/
fun fromJson(config: String): Result {
- return JNIConfig.loadJsonConfig(config)
+ return runCatching { Config(JNIConfig.loadFromJson(config)) }
}
/**
@@ -226,7 +226,7 @@ class Config internal constructor(internal val jniConfig: JNIConfig) {
* @return A result with the [Config].
*/
fun fromJson5(config: String): Result {
- return JNIConfig.loadJson5Config(config)
+ return runCatching { Config(JNIConfig.loadFromJson(config)) }
}
/**
@@ -258,7 +258,7 @@ class Config internal constructor(internal val jniConfig: JNIConfig) {
* @return A result with the [Config].
*/
fun fromYaml(config: String): Result {
- return JNIConfig.loadYamlConfig(config)
+ return runCatching { Config(JNIConfig.loadFromYaml(config)) }
}
/**
@@ -267,7 +267,7 @@ class Config internal constructor(internal val jniConfig: JNIConfig) {
* @param jsonElement The zenoh config as a [JsonElement].
*/
fun fromJsonElement(jsonElement: JsonElement): Result {
- return JNIConfig.loadJsonConfig(jsonElement.toString())
+ return runCatching { Config(JNIConfig.loadFromJson(jsonElement.toString())) }
}
/**
@@ -289,7 +289,7 @@ class Config internal constructor(internal val jniConfig: JNIConfig) {
* Returns the json value associated to the [key].
*/
fun getJson(key: String): Result {
- return jniConfig.getJson(key)
+ return runCatching { jniConfig.getJson(key) }
}
/**
@@ -313,7 +313,7 @@ class Config internal constructor(internal val jniConfig: JNIConfig) {
* @return A result with the status of the operation.
*/
fun insertJson5(key: String, value: String): Result {
- return jniConfig.insertJson5(key, value)
+ return runCatching { jniConfig.insertJson5(key, value) }
}
protected fun finalize() {
diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/Logger.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/Logger.kt
index 540e004c..86aa4845 100644
--- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/Logger.kt
+++ b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/Logger.kt
@@ -14,7 +14,7 @@
package io.zenoh
-import io.zenoh.exceptions.ZError
+import io.zenoh.jni.JNILogger
/** Logger class to redirect the Rust logs from Zenoh to the kotlin environment. */
internal class Logger {
@@ -24,16 +24,7 @@ internal class Logger {
internal const val LOG_ENV: String = "RUST_LOG"
fun start(filter: String) = runCatching {
- startLogsViaJNI(filter)
+ JNILogger.startLogs(filter)
}
-
- /**
- * Redirects the rust logs either to logcat for Android systems or to the standard output (for non-android
- * systems).
- *
- * See https://docs.rs/env_logger/latest/env_logger/index.html for accepted filter format.
- */
- @Throws(ZError::class)
- private external fun startLogsViaJNI(filter: String)
}
}
diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/Session.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/Session.kt
index c3ad5ccc..11db22fb 100644
--- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/Session.kt
+++ b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/Session.kt
@@ -15,13 +15,23 @@
package io.zenoh
import io.zenoh.annotations.Unstable
+import io.zenoh.config.EntityGlobalId
import io.zenoh.exceptions.ZError
+import io.zenoh.ext.HeartbeatMode
+import io.zenoh.ext.RecoveryMode
import io.zenoh.handlers.Callback
import io.zenoh.handlers.ChannelHandler
import io.zenoh.handlers.Handler
+import io.zenoh.jni.JNIQuery
import io.zenoh.jni.JNISession
+import io.zenoh.jni.callbacks.JNIGetCallback
+import io.zenoh.jni.callbacks.JNIOnCloseCallback
+import io.zenoh.jni.callbacks.JNIQueryableCallback
+import io.zenoh.jni.callbacks.JNISubscriberCallback
import io.zenoh.keyexpr.KeyExpr
import io.zenoh.bytes.Encoding
+import io.zenoh.qos.CongestionControl
+import io.zenoh.qos.Priority
import io.zenoh.qos.QoS
import io.zenoh.bytes.IntoZBytes
import io.zenoh.bytes.ZBytes
@@ -39,7 +49,9 @@ import io.zenoh.pubsub.Put
import io.zenoh.query.*
import io.zenoh.query.Query
import io.zenoh.query.Queryable
+import io.zenoh.query.ReplyError
import io.zenoh.sample.Sample
+import io.zenoh.sample.SampleKind
import io.zenoh.query.Selector
import io.zenoh.qos.Reliability
import io.zenoh.session.SessionDeclaration
@@ -48,6 +60,7 @@ import io.zenoh.pubsub.Subscriber
import kotlinx.coroutines.channels.Channel
import java.lang.ref.WeakReference
import java.time.Duration
+import org.apache.commons.net.ntp.TimeStamp
/**
* A Zenoh Session, the core interaction point with a Zenoh network.
@@ -654,7 +667,8 @@ class Session private constructor(private val config: Config) : AutoCloseable {
*/
fun declareKeyExpr(keyExpr: String): Result {
return jniSession?.run {
- declareKeyExpr(keyExpr).onSuccess { strongDeclarations.add(it) }
+ runCatching { KeyExpr(keyExpr, declareKeyExpr(keyExpr)) }
+ .onSuccess { strongDeclarations.add(it) }
} ?: Result.failure(sessionClosedException)
}
@@ -669,7 +683,12 @@ class Session private constructor(private val config: Config) : AutoCloseable {
*/
fun undeclare(keyExpr: KeyExpr): Result {
return jniSession?.run {
- undeclareKeyExpr(keyExpr)
+ val jniKeyExpr = keyExpr.jniKeyExpr
+ ?: return Result.failure(ZError("Key expression is not declared through a session."))
+ runCatching {
+ undeclareKeyExpr(jniKeyExpr)
+ keyExpr.jniKeyExpr = null
+ }
} ?: Result.failure(sessionClosedException)
}
@@ -1076,7 +1095,12 @@ class Session private constructor(private val config: Config) : AutoCloseable {
reliability: Reliability
): Result {
return jniSession?.run {
- declarePublisher(keyExpr, qos, encoding, reliability).onSuccess { weakDeclarations.add(WeakReference(it)) }
+ runCatching {
+ Publisher(keyExpr, qos, encoding, declarePublisher(
+ keyExpr.jniKeyExpr, keyExpr.keyExpr,
+ qos.congestionControl.value, qos.priority.value, qos.express, reliability.ordinal
+ ))
+ }.onSuccess { weakDeclarations.add(WeakReference(it)) }
} ?: Result.failure(sessionClosedException)
}
@@ -1091,8 +1115,27 @@ class Session private constructor(private val config: Config) : AutoCloseable {
publisherDetection: Boolean = false
): Result {
return jniSession?.run {
- declareAdvancedPublisher(keyExpr, qos, encoding, reliability,
- cacheConfig, sampleMissDetection, publisherDetection).onSuccess { weakDeclarations.add(WeakReference(it)) }
+ runCatching {
+ val cacheEnabled = cacheConfig != null
+ val cacheMaxSamples = cacheConfig?.maxSamples ?: 1L
+ val cacheRepliesQoS = cacheConfig?.repliesQoS ?: QoS.defaultPush
+ val smdEnabled = sampleMissDetection != null
+ val heartbeat = sampleMissDetection?.heartbeat
+ val smdEnableHeartbeat = heartbeat != null
+ val heartbeatMs = when (heartbeat) {
+ is HeartbeatMode.PeriodicHeartbeat -> heartbeat.milliseconds
+ is HeartbeatMode.SporadicHeartbeat -> heartbeat.milliseconds
+ else -> 0L
+ }
+ val heartbeatIsSporadic = heartbeat is HeartbeatMode.SporadicHeartbeat
+ AdvancedPublisher(keyExpr, qos, encoding, declareAdvancedPublisher(
+ keyExpr.jniKeyExpr, keyExpr.keyExpr,
+ qos.congestionControl.value, qos.priority.value, qos.express, reliability.ordinal,
+ cacheEnabled, cacheMaxSamples,
+ cacheRepliesQoS.priority.value, cacheRepliesQoS.congestionControl.value, cacheRepliesQoS.express,
+ smdEnabled, smdEnableHeartbeat, heartbeatMs, heartbeatIsSporadic, publisherDetection
+ ))
+ }.onSuccess { weakDeclarations.add(WeakReference(it)) }
} ?: Result.failure(sessionClosedException)
}
@@ -1103,7 +1146,20 @@ class Session private constructor(private val config: Config) : AutoCloseable {
receiver: R
): Result> {
return jniSession?.run {
- declareSubscriber(keyExpr, callback, onClose, receiver).onSuccess { strongDeclarations.add(it) }
+ runCatching {
+ val jniCallback = JNISubscriberCallback { keyExpr1, payload, encodingId, encodingSchema, kind, timestampNTP64, timestampIsValid, attachmentBytes, express, priority, congestionControl ->
+ val timestamp = if (timestampIsValid) TimeStamp(timestampNTP64) else null
+ callback.run(Sample(
+ KeyExpr(keyExpr1), ZBytes.from(payload), Encoding(encodingId, schema = encodingSchema),
+ SampleKind.fromInt(kind), timestamp,
+ QoS(CongestionControl.fromInt(congestionControl), Priority.fromInt(priority), express),
+ attachmentBytes?.let { ZBytes.from(it) }
+ ))
+ }
+ Subscriber(keyExpr, receiver, declareSubscriber(
+ keyExpr.jniKeyExpr, keyExpr.keyExpr, jniCallback, JNIOnCloseCallback { onClose() }
+ ))
+ }.onSuccess { strongDeclarations.add(it) }
} ?: Result.failure(sessionClosedException)
}
@@ -1118,7 +1174,30 @@ class Session private constructor(private val config: Config) : AutoCloseable {
receiver: R
): Result> {
return jniSession?.run {
- declareAdvancedSubscriber(keyExpr, history, recovery, subscriberDetection, callback, onClose, receiver).onSuccess { strongDeclarations.add(it) }
+ runCatching {
+ val jniCallback = JNISubscriberCallback { keyExpr1, payload, encodingId, encodingSchema, kind, timestampNTP64, timestampIsValid, attachmentBytes, express, priority, congestionControl ->
+ val timestamp = if (timestampIsValid) TimeStamp(timestampNTP64) else null
+ callback.run(Sample(
+ KeyExpr(keyExpr1), ZBytes.from(payload), Encoding(encodingId, schema = encodingSchema),
+ SampleKind.fromInt(kind), timestamp,
+ QoS(CongestionControl.fromInt(congestionControl), Priority.fromInt(priority), express),
+ attachmentBytes?.let { ZBytes.from(it) }
+ ))
+ }
+ val historyEnabled = history != null
+ val historyDetectLate = history?.detectLatePublishers ?: false
+ val historyMaxSamples = history?.maxSamples ?: 0L
+ val historyMaxAgeSecs = history?.maxAgeSeconds ?: 0.0
+ val recoveryEnabled = recovery != null
+ val isHeartbeat = recovery?.mode is RecoveryMode.Heartbeat
+ val recoveryQueryPeriodMs = (recovery?.mode as? RecoveryMode.PeriodicQuery)?.milliseconds ?: 0L
+ AdvancedSubscriber(keyExpr, receiver, declareAdvancedSubscriber(
+ keyExpr.jniKeyExpr, keyExpr.keyExpr,
+ historyEnabled, historyDetectLate, historyMaxSamples, historyMaxAgeSecs,
+ recoveryEnabled, isHeartbeat, recoveryQueryPeriodMs,
+ subscriberDetection, jniCallback, JNIOnCloseCallback { onClose() }
+ ))
+ }.onSuccess { strongDeclarations.add(it) }
} ?: Result.failure(sessionClosedException)
}
@@ -1130,7 +1209,25 @@ class Session private constructor(private val config: Config) : AutoCloseable {
complete: Boolean
): Result> {
return jniSession?.run {
- declareQueryable(keyExpr, callback, onClose, receiver, complete).onSuccess { strongDeclarations.add(it) }
+ runCatching {
+ val jniCallback = JNIQueryableCallback { keyExpr1, selectorParams, payload, encodingId, encodingSchema, attachmentBytes, queryPtr, acceptReplies ->
+ val jniQuery = JNIQuery(queryPtr)
+ val keyExpr2 = KeyExpr(keyExpr1)
+ val selector = if (selectorParams.isEmpty()) Selector(keyExpr2)
+ else Selector(keyExpr2, Parameters.from(selectorParams).getOrThrow())
+ callback.run(Query(
+ keyExpr2, selector,
+ payload?.let { ZBytes.from(it) },
+ payload?.let { Encoding(encodingId, schema = encodingSchema) },
+ attachmentBytes?.let { ZBytes.from(it) },
+ jniQuery,
+ ReplyKeyExpr.entries[acceptReplies]
+ ))
+ }
+ Queryable(keyExpr, receiver, declareQueryable(
+ keyExpr.jniKeyExpr, keyExpr.keyExpr, jniCallback, JNIOnCloseCallback { onClose() }, complete
+ ))
+ }.onSuccess { strongDeclarations.add(it) }
} ?: Result.failure(sessionClosedException)
}
@@ -1143,7 +1240,14 @@ class Session private constructor(private val config: Config) : AutoCloseable {
acceptReplies: ReplyKeyExpr
): Result {
return jniSession?.run {
- declareQuerier(keyExpr, target, consolidation, qos, timeout, acceptReplies).onSuccess { weakDeclarations.add(WeakReference(it)) }
+ runCatching {
+ Querier(keyExpr, qos, declareQuerier(
+ keyExpr.jniKeyExpr, keyExpr.keyExpr,
+ target.ordinal, consolidation.ordinal,
+ qos.congestionControl.value, qos.priority.value, qos.express,
+ timeout.toMillis(), acceptReplies.ordinal
+ ))
+ }.onSuccess { weakDeclarations.add(WeakReference(it)) }
} ?: Result.failure(sessionClosedException)
}
@@ -1162,48 +1266,78 @@ class Session private constructor(private val config: Config) : AutoCloseable {
acceptReplies: ReplyKeyExpr
): Result {
return jniSession?.run {
- performGet(
- selector,
- callback,
- onClose,
- receiver,
- timeout,
- target,
- consolidation,
- payload,
- encoding,
- attachment,
- qos,
- acceptReplies
- )
+ runCatching {
+ val jniCallback = JNIGetCallback { replierZid, replierEid, success, replyKeyExpr, replyPayload, encodingId, encodingSchema, kind, timestampNTP64, timestampIsValid, replyAttachment, express, priority, congestionControl ->
+ val reply = if (success) {
+ val timestamp = if (timestampIsValid) TimeStamp(timestampNTP64) else null
+ Reply(
+ replierZid?.let { EntityGlobalId(ZenohId(it), replierEid.toUInt()) },
+ Result.success(Sample(
+ KeyExpr(replyKeyExpr!!), ZBytes.from(replyPayload),
+ Encoding(encodingId, schema = encodingSchema),
+ SampleKind.fromInt(kind), timestamp,
+ QoS(CongestionControl.fromInt(congestionControl), Priority.fromInt(priority), express),
+ replyAttachment?.let { ZBytes.from(it) }
+ ))
+ )
+ } else {
+ Reply(
+ replierZid?.let { EntityGlobalId(ZenohId(it), replierEid.toUInt()) },
+ Result.failure(ReplyError(ZBytes.from(replyPayload), Encoding(encodingId, schema = encodingSchema)))
+ )
+ }
+ callback.run(reply)
+ }
+ val resolvedEncoding = encoding ?: Encoding.default()
+ get(
+ selector.keyExpr.jniKeyExpr, selector.keyExpr.keyExpr, selector.parameters?.toString(),
+ jniCallback, JNIOnCloseCallback { onClose() },
+ timeout.toMillis(), target.ordinal, consolidation.ordinal,
+ attachment?.into()?.bytes, payload?.into()?.bytes,
+ resolvedEncoding.id, resolvedEncoding.schema,
+ qos.congestionControl.value, qos.priority.value, qos.express, acceptReplies.ordinal
+ )
+ receiver
+ }
} ?: Result.failure(sessionClosedException)
}
private fun resolvePut(keyExpr: KeyExpr, put: Put): Result = runCatching {
- jniSession?.run { performPut(keyExpr, put) }
+ jniSession?.run {
+ put(
+ keyExpr.jniKeyExpr, keyExpr.keyExpr,
+ put.payload.bytes, put.encoding.id, put.encoding.schema,
+ put.qos.congestionControl.value, put.qos.priority.value, put.qos.express,
+ put.attachment?.bytes, put.reliability.ordinal
+ )
+ }
}
private fun resolveDelete(keyExpr: KeyExpr, delete: Delete): Result = runCatching {
- jniSession?.run { performDelete(keyExpr, delete) }
+ jniSession?.run {
+ delete(
+ keyExpr.jniKeyExpr, keyExpr.keyExpr,
+ delete.qos.congestionControl.value, delete.qos.priority.value, delete.qos.express,
+ delete.attachment?.bytes, delete.reliability.ordinal
+ )
+ }
}
internal fun zid(): Result {
- return jniSession?.zid() ?: Result.failure(sessionClosedException)
+ return jniSession?.run { runCatching { ZenohId(getZid()) } } ?: Result.failure(sessionClosedException)
}
internal fun getPeersId(): Result> {
- return jniSession?.peersZid() ?: Result.failure(sessionClosedException)
+ return jniSession?.run { runCatching { getPeersZid().map { ZenohId(it) } } } ?: Result.failure(sessionClosedException)
}
internal fun getRoutersId(): Result> {
- return jniSession?.routersZid() ?: Result.failure(sessionClosedException)
+ return jniSession?.run { runCatching { getRoutersZid().map { ZenohId(it) } } } ?: Result.failure(sessionClosedException)
}
/** Launches the session through the jni session, returning the [Session] on success. */
private fun launch(): Result = runCatching {
- jniSession = JNISession()
- return jniSession!!.open(config)
- .map { this@Session }
- .onFailure { jniSession = null }
+ jniSession = JNISession.open(config.jniConfig)
+ this@Session
}
}
diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/Zenoh.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/Zenoh.kt
index 12049903..b45409fd 100644
--- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/Zenoh.kt
+++ b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/Zenoh.kt
@@ -15,14 +15,17 @@
package io.zenoh
import io.zenoh.Logger.Companion.LOG_ENV
+import io.zenoh.config.WhatAmI
+import io.zenoh.config.WhatAmI.*
+import io.zenoh.config.ZenohId
import io.zenoh.handlers.Callback
import io.zenoh.handlers.ChannelHandler
import io.zenoh.handlers.Handler
import io.zenoh.jni.JNIScout
+import io.zenoh.jni.callbacks.JNIOnCloseCallback
+import io.zenoh.jni.callbacks.JNIScoutCallback
import io.zenoh.scouting.Hello
import io.zenoh.scouting.Scout
-import io.zenoh.config.WhatAmI
-import io.zenoh.config.WhatAmI.*
import kotlinx.coroutines.channels.Channel
object Zenoh {
@@ -54,7 +57,13 @@ object Zenoh {
config: Config? = null
): Result> {
ZenohLoad
- return JNIScout.scout(whatAmI = whatAmI, callback = callback, receiver = Unit, onClose = {}, config = config)
+ return runCatching {
+ val binaryWhatAmI = whatAmI.map { it.value }.reduce { acc, it -> acc or it }
+ val jniCallback = JNIScoutCallback { whatAmI2, zid, locators ->
+ callback.run(Hello(WhatAmI.fromInt(whatAmI2), ZenohId(zid), locators))
+ }
+ Scout(Unit, JNIScout.scout(binaryWhatAmI, jniCallback, JNIOnCloseCallback {}, config?.jniConfig))
+ }
}
/**
@@ -74,13 +83,13 @@ object Zenoh {
config: Config? = null
): Result> {
ZenohLoad
- return JNIScout.scout(
- whatAmI = whatAmI,
- callback = { hello -> handler.handle(hello) },
- receiver = handler.receiver(),
- onClose = handler::onClose,
- config = config
- )
+ return runCatching {
+ val binaryWhatAmI = whatAmI.map { it.value }.reduce { acc, it -> acc or it }
+ val jniCallback = JNIScoutCallback { whatAmI2, zid, locators ->
+ handler.handle(Hello(WhatAmI.fromInt(whatAmI2), ZenohId(zid), locators))
+ }
+ Scout(handler.receiver(), JNIScout.scout(binaryWhatAmI, jniCallback, JNIOnCloseCallback { handler.onClose() }, config?.jniConfig))
+ }
}
/**
@@ -101,13 +110,13 @@ object Zenoh {
): Result>> {
ZenohLoad
val handler = ChannelHandler(channel)
- return JNIScout.scout(
- whatAmI = whatAmI,
- callback = { hello -> handler.handle(hello) },
- receiver = handler.receiver(),
- onClose = handler::onClose,
- config = config
- )
+ return runCatching {
+ val binaryWhatAmI = whatAmI.map { it.value }.reduce { acc, it -> acc or it }
+ val jniCallback = JNIScoutCallback { whatAmI2, zid, locators ->
+ handler.handle(Hello(WhatAmI.fromInt(whatAmI2), ZenohId(zid), locators))
+ }
+ Scout(handler.receiver(), JNIScout.scout(binaryWhatAmI, jniCallback, JNIOnCloseCallback { handler.onClose() }, config?.jniConfig))
+ }
}
/**
@@ -143,9 +152,3 @@ object Zenoh {
logLevelProp?.let { Logger.start(it) } ?: Logger.start(fallbackFilter)
}
}
-
-/**
- * Static singleton class to load the Zenoh native library once and only once, as well as the logger in function of the
- * log level configuration.
- */
-internal expect object ZenohLoad
diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/config/ZenohId.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/config/ZenohId.kt
index d9848514..e60f9078 100644
--- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/config/ZenohId.kt
+++ b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/config/ZenohId.kt
@@ -22,7 +22,7 @@ import io.zenoh.jni.JNIZenohId
data class ZenohId internal constructor(internal val bytes: ByteArray) {
override fun toString(): String {
- return JNIZenohId.toStringViaJNI(bytes)
+ return JNIZenohId.toString(bytes)
}
override fun equals(other: Any?): Boolean {
diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/exceptions/ZError.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/exceptions/ZError.kt
deleted file mode 100644
index c63a19ce..00000000
--- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/exceptions/ZError.kt
+++ /dev/null
@@ -1,20 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-package io.zenoh.exceptions
-
-/**
- * A Zenoh Error.
- */
-class ZError(override val message: String? = null): Exception()
diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIAdvancedPublisher.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIAdvancedPublisher.kt
deleted file mode 100644
index b629f6d0..00000000
--- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIAdvancedPublisher.kt
+++ /dev/null
@@ -1,124 +0,0 @@
-//
-// Copyright (c) 2025 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-package io.zenoh.jni
-
-import io.zenoh.exceptions.ZError
-import io.zenoh.bytes.Encoding
-import io.zenoh.bytes.IntoZBytes
-import io.zenoh.handlers.MatchingCallback
-import io.zenoh.jni.callbacks.JNIMatchingListenerCallback
-import io.zenoh.jni.callbacks.JNIOnCloseCallback
-import io.zenoh.pubsub.AdvancedPublisher
-import io.zenoh.pubsub.MatchingListener
-
-/**
- * Adapter class to handle the interactions with Zenoh through JNI for an [AdvancedPublisher].
- *
- * @property ptr: raw pointer to the underlying native Publisher.
- */
-internal class JNIAdvancedPublisher(private val ptr: Long) {
-
- fun declareMatchingListener(
- callback: MatchingCallback, onClose: () -> Unit
- ): Result = runCatching {
- val matchingListenerCallback =
- JNIMatchingListenerCallback { matching: Boolean ->
- callback.run(matching)
- }
- val matchingListenerRawPtr = declareMatchingListenerViaJNI(
- ptr, matchingListenerCallback, onClose
- )
- MatchingListener(JNIMatchingListener(matchingListenerRawPtr))
- }
-
- fun declareBackgroundMatchingListener(
- callback: MatchingCallback, onClose: () -> Unit
- ): Result = runCatching {
- val matchingListenerCallback =
- JNIMatchingListenerCallback { matching: Boolean ->
- callback.run(matching)
- }
- declareBackgroundMatchingListenerViaJNI(
- ptr, matchingListenerCallback, onClose
- )
- }
-
- /**
- * Return the matching status of the publisher.
- *
- * Will return true if there exist Subscribers matching the Publisher's key expression and false otherwise.
- */
- fun getMatchingStatus(): Result = runCatching {
- getMatchingStatusViaJNI(ptr)
- }
-
- /**
- * Put operation.
- *
- * @param payload Payload of the put.
- * @param encoding Encoding of the payload.
- * @param attachment Optional attachment.
- */
- fun put(payload: IntoZBytes, encoding: Encoding?, attachment: IntoZBytes?): Result = runCatching {
- val resolvedEncoding = encoding ?: Encoding.default()
- putViaJNI(payload.into().bytes, resolvedEncoding.id, resolvedEncoding.schema, attachment?.into()?.bytes, ptr)
- }
-
- /**
- * Delete operation.
- *
- * @param attachment Optional attachment.
- */
- fun delete(attachment: IntoZBytes?): Result = runCatching {
- deleteViaJNI(attachment?.into()?.bytes, ptr)
- }
-
- /**
- * Close and free the underlying publisher pointer.
- *
- * Further operations with this publisher should not be performed anymore.
- */
- fun close() {
- freePtrViaJNI(ptr)
- }
-
- @Throws(ZError::class)
- private external fun declareMatchingListenerViaJNI(
- ptr: Long,
- callback: JNIMatchingListenerCallback,
- onClose: JNIOnCloseCallback,
- ): Long
-
- @Throws(ZError::class)
- private external fun declareBackgroundMatchingListenerViaJNI(
- ptr: Long,
- callback: JNIMatchingListenerCallback,
- onClose: JNIOnCloseCallback,
- )
-
- @Throws(ZError::class)
- private external fun getMatchingStatusViaJNI(ptr: Long): Boolean
-
- @Throws(ZError::class)
- private external fun putViaJNI(
- valuePayload: ByteArray, encodingId: Int, encodingSchema: String?, attachment: ByteArray?, ptr: Long
- )
-
- @Throws(ZError::class)
- private external fun deleteViaJNI(attachment: ByteArray?, ptr: Long)
-
- private external fun freePtrViaJNI(ptr: Long)
-
-}
diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIAdvancedSubscriber.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIAdvancedSubscriber.kt
deleted file mode 100644
index 99a396e5..00000000
--- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIAdvancedSubscriber.kt
+++ /dev/null
@@ -1,168 +0,0 @@
-//
-// Copyright (c) 2025 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-package io.zenoh.jni
-
-import io.zenoh.bytes.Encoding
-import io.zenoh.bytes.into
-import io.zenoh.exceptions.ZError
-import io.zenoh.handlers.Callback
-import io.zenoh.handlers.MatchingCallback
-import io.zenoh.handlers.SampleMissCallback
-import io.zenoh.jni.callbacks.JNIMatchingListenerCallback
-import io.zenoh.jni.callbacks.JNIOnCloseCallback
-import io.zenoh.jni.callbacks.JNISampleMissListenerCallback
-import io.zenoh.jni.callbacks.JNISubscriberCallback
-import io.zenoh.keyexpr.KeyExpr
-import io.zenoh.pubsub.AdvancedSubscriber
-import io.zenoh.pubsub.MatchingListener
-import io.zenoh.pubsub.SampleMiss
-import io.zenoh.pubsub.SampleMissListener
-import io.zenoh.pubsub.Subscriber
-import io.zenoh.qos.CongestionControl
-import io.zenoh.qos.Priority
-import io.zenoh.qos.QoS
-import io.zenoh.sample.Sample
-import io.zenoh.sample.SampleKind
-import org.apache.commons.net.ntp.TimeStamp
-
-/**
- * Adapter class to handle the interactions with Zenoh through JNI for an [AdvancedSubscriber]
- *
- * @property ptr: raw pointer to the underlying native Subscriber.
- */
-internal class JNIAdvancedSubscriber(private val ptr: Long) {
-
- fun declareDetectPublishersSubscriber(
- keyExpr: KeyExpr,
- history: Boolean,
- callback: Callback,
- onClose: () -> Unit, receiver: R
- ): Result> = runCatching {
- val subCallback =
- JNISubscriberCallback { keyExpr, payload, encodingId, encodingSchema, kind, timestampNTP64, timestampIsValid, attachmentBytes, express: Boolean, priority: Int, congestionControl: Int ->
- val timestamp = if (timestampIsValid) TimeStamp(timestampNTP64) else null
- val sample = Sample(
- KeyExpr(keyExpr, null),
- payload.into(),
- Encoding(encodingId, schema = encodingSchema),
- SampleKind.fromInt(kind),
- timestamp,
- QoS(CongestionControl.fromInt(congestionControl), Priority.fromInt(priority), express),
- attachmentBytes?.into()
- )
- callback.run(sample)
- }
- val subscriberRawPtr = declareDetectPublishersSubscriberViaJNI(
- ptr, history, subCallback, onClose
- )
- Subscriber(keyExpr, receiver, JNISubscriber(subscriberRawPtr))
- }
-
- fun declareBackgroundDetectPublishersSubscriber(
- keyExpr: KeyExpr,
- history: Boolean,
- callback: Callback,
- onClose: () -> Unit
- ): Result = runCatching {
- val subCallback =
- JNISubscriberCallback { keyExpr, payload, encodingId, encodingSchema, kind, timestampNTP64, timestampIsValid, attachmentBytes, express: Boolean, priority: Int, congestionControl: Int ->
- val timestamp = if (timestampIsValid) TimeStamp(timestampNTP64) else null
- val sample = Sample(
- KeyExpr(keyExpr, null),
- payload.into(),
- Encoding(encodingId, schema = encodingSchema),
- SampleKind.fromInt(kind),
- timestamp,
- QoS(CongestionControl.fromInt(congestionControl), Priority.fromInt(priority), express),
- attachmentBytes?.into()
- )
- callback.run(sample)
- }
- declareBackgroundDetectPublishersSubscriberViaJNI(
- ptr, history, subCallback, onClose
- )
- }
-
- fun declareSampleMissListener(
- callback: SampleMissCallback, onClose: () -> Unit
- ): Result = runCatching {
- val sampleMissListenerCallback =
- JNISampleMissListenerCallback { zidLower: Long,
- zidUpper: Long,
- eid: Long,
- missedCount: Long ->
- val miss = SampleMiss(zidLower, zidUpper, eid, missedCount)
- callback.run(miss)
- }
- val sampleMissListenerRawPtr = declareSampleMissListenerViaJNI(
- ptr, sampleMissListenerCallback, onClose
- )
- SampleMissListener(JNISampleMissListener(sampleMissListenerRawPtr))
- }
-
- fun declareBackgroundSampleMissListener(
- callback: SampleMissCallback, onClose: () -> Unit
- ): Result = runCatching {
- val sampleMissListenerCallback =
- JNISampleMissListenerCallback { zidLower: Long,
- zidUpper: Long,
- eid: Long,
- missedCount: Long ->
- val miss = SampleMiss(zidLower, zidUpper, eid, missedCount)
- callback.run(miss)
- }
- declareBackgroundSampleMissListenerViaJNI(
- ptr, sampleMissListenerCallback, onClose
- )
- }
-
- fun close() {
- freePtrViaJNI(ptr)
- }
-
- @Throws(ZError::class)
- private external fun declareBackgroundDetectPublishersSubscriberViaJNI(
- advancedSubscriberPtr: Long,
- history: Boolean,
- callback: JNISubscriberCallback,
- onClose: JNIOnCloseCallback,
- )
-
- @Throws(ZError::class)
- private external fun declareDetectPublishersSubscriberViaJNI(
- advancedSubscriberPtr: Long,
- history: Boolean,
- callback: JNISubscriberCallback,
- onClose: JNIOnCloseCallback,
- ): Long
-
- @Throws(ZError::class)
- private external fun declareBackgroundSampleMissListenerViaJNI(
- ptr: Long,
- callback: JNISampleMissListenerCallback,
- onClose: JNIOnCloseCallback,
- )
-
- @Throws(ZError::class)
- private external fun declareSampleMissListenerViaJNI(
- ptr: Long,
- callback: JNISampleMissListenerCallback,
- onClose: JNIOnCloseCallback,
- ): Long
-
- /** Frees the underlying native Subscriber. */
- private external fun freePtrViaJNI(ptr: Long)
-
-}
diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIConfig.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIConfig.kt
deleted file mode 100644
index 4c7c0344..00000000
--- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIConfig.kt
+++ /dev/null
@@ -1,94 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-package io.zenoh.jni
-
-import io.zenoh.Config
-import io.zenoh.ZenohLoad
-import io.zenoh.exceptions.ZError
-import java.io.File
-import java.nio.file.Path
-
-internal class JNIConfig(internal val ptr: Long) {
-
- companion object {
-
- init {
- ZenohLoad
- }
-
- fun loadDefaultConfig(): Config {
- val cfgPtr = loadDefaultConfigViaJNI()
- return Config(JNIConfig(cfgPtr))
- }
-
- fun loadConfigFile(path: Path): Result = runCatching {
- val cfgPtr = loadConfigFileViaJNI(path.toString())
- Config(JNIConfig(cfgPtr))
- }
-
- fun loadConfigFile(file: File): Result = loadConfigFile(file.toPath())
-
- fun loadJsonConfig(rawConfig: String): Result = runCatching {
- val cfgPtr = loadJsonConfigViaJNI(rawConfig)
- Config(JNIConfig(cfgPtr))
- }
-
- fun loadJson5Config(rawConfig: String): Result = runCatching {
- val cfgPtr = loadJsonConfigViaJNI(rawConfig)
- Config(JNIConfig(cfgPtr))
- }
-
- fun loadYamlConfig(rawConfig: String): Result = runCatching {
- val cfgPtr = loadYamlConfigViaJNI(rawConfig)
- Config(JNIConfig(cfgPtr))
- }
-
- @Throws(ZError::class)
- private external fun loadDefaultConfigViaJNI(): Long
-
- @Throws(ZError::class)
- private external fun loadConfigFileViaJNI(path: String): Long
-
- @Throws(ZError::class)
- private external fun loadJsonConfigViaJNI(rawConfig: String): Long
-
- @Throws(ZError::class)
- private external fun loadYamlConfigViaJNI(rawConfig: String): Long
-
- @Throws(ZError::class)
- private external fun getIdViaJNI(ptr: Long): ByteArray
-
- @Throws(ZError::class)
- private external fun insertJson5ViaJNI(ptr: Long, key: String, value: String): Long
-
- /** Frees the underlying native config. */
- private external fun freePtrViaJNI(ptr: Long)
-
- @Throws(ZError::class)
- private external fun getJsonViaJNI(ptr: Long, key: String): String
- }
-
- fun close() {
- freePtrViaJNI(ptr)
- }
-
- fun getJson(key: String): Result = runCatching {
- getJsonViaJNI(ptr, key)
- }
-
- fun insertJson5(key: String, value: String): Result = runCatching {
- insertJson5ViaJNI(this.ptr, key, value)
- }
-}
diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIKeyExpr.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIKeyExpr.kt
deleted file mode 100644
index 7022e521..00000000
--- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIKeyExpr.kt
+++ /dev/null
@@ -1,97 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-package io.zenoh.jni
-
-import io.zenoh.ZenohLoad
-import io.zenoh.exceptions.ZError
-import io.zenoh.keyexpr.KeyExpr
-import io.zenoh.keyexpr.SetIntersectionLevel
-
-internal class JNIKeyExpr(internal val ptr: Long) {
-
- companion object {
- init {
- ZenohLoad
- }
-
- fun tryFrom(keyExpr: String): Result = runCatching {
- KeyExpr(tryFromViaJNI(keyExpr))
- }
-
- fun autocanonize(keyExpr: String): Result = runCatching {
- KeyExpr(autocanonizeViaJNI(keyExpr))
- }
-
- fun intersects(keyExprA: KeyExpr, keyExprB: KeyExpr): Boolean = intersectsViaJNI(
- keyExprA.jniKeyExpr?.ptr ?: 0,
- keyExprA.keyExpr,
- keyExprB.jniKeyExpr?.ptr ?: 0,
- keyExprB.keyExpr
- )
-
- fun includes(keyExprA: KeyExpr, keyExprB: KeyExpr): Boolean = includesViaJNI(
- keyExprA.jniKeyExpr?.ptr ?: 0,
- keyExprA.keyExpr,
- keyExprB.jniKeyExpr?.ptr ?: 0,
- keyExprB.keyExpr
- )
-
- fun relationTo(keyExpr: KeyExpr, other: KeyExpr): SetIntersectionLevel {
- val intersection = relationToViaJNI(
- keyExpr.jniKeyExpr?.ptr ?: 0,
- keyExpr.keyExpr,
- other.jniKeyExpr?.ptr ?: 0,
- other.keyExpr
- )
- return SetIntersectionLevel.fromInt(intersection)
- }
-
- fun joinViaJNI(keyExpr: KeyExpr, other: String): Result = runCatching {
- KeyExpr(joinViaJNI(keyExpr.jniKeyExpr?.ptr ?: 0, keyExpr.keyExpr, other))
- }
-
- fun concatViaJNI(keyExpr: KeyExpr, other: String): Result = runCatching {
- KeyExpr(concatViaJNI(keyExpr.jniKeyExpr?.ptr ?: 0, keyExpr.keyExpr, other))
- }
-
- @Throws(ZError::class)
- private external fun tryFromViaJNI(keyExpr: String): String
-
- @Throws(ZError::class)
- private external fun autocanonizeViaJNI(keyExpr: String): String
-
- @Throws(ZError::class)
- private external fun intersectsViaJNI(ptrA: Long, keyExprA: String, ptrB: Long, keyExprB: String): Boolean
-
- @Throws(ZError::class)
- private external fun includesViaJNI(ptrA: Long, keyExprA: String, ptrB: Long, keyExprB: String): Boolean
-
- @Throws(ZError::class)
- private external fun relationToViaJNI(ptrA: Long, keyExprA: String, ptrB: Long, keyExprB: String): Int
-
- @Throws(ZError::class)
- private external fun joinViaJNI(ptrA: Long, keyExprA: String, other: String): String
-
- @Throws(ZError::class)
- private external fun concatViaJNI(ptrA: Long, keyExprA: String, other: String): String
- }
-
- fun close() {
- freePtrViaJNI(ptr)
- }
-
- /** Frees the underlying native KeyExpr. */
- private external fun freePtrViaJNI(ptr: Long)
-}
diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNILiveliness.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNILiveliness.kt
index 9434e257..2914d5bb 100644
--- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNILiveliness.kt
+++ b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNILiveliness.kt
@@ -15,7 +15,7 @@
package io.zenoh.jni
import io.zenoh.bytes.Encoding
-import io.zenoh.bytes.into
+import io.zenoh.bytes.ZBytes
import io.zenoh.config.EntityGlobalId
import io.zenoh.config.ZenohId
import io.zenoh.handlers.Callback
@@ -49,14 +49,14 @@ internal object JNILiveliness {
replierZid: ByteArray?,
replierEid: Int,
success: Boolean,
- keyExpr2: String?,
- payload: ByteArray,
+ replyKeyExpr: String?,
+ replyPayload: ByteArray,
encodingId: Int,
encodingSchema: String?,
kind: Int,
timestampNTP64: Long,
timestampIsValid: Boolean,
- attachmentBytes: ByteArray?,
+ replyAttachment: ByteArray?,
express: Boolean,
priority: Int,
congestionControl: Int,
@@ -65,20 +65,20 @@ internal object JNILiveliness {
if (success) {
val timestamp = if (timestampIsValid) TimeStamp(timestampNTP64) else null
val sample = Sample(
- KeyExpr(keyExpr2!!, null),
- payload.into(),
+ KeyExpr(replyKeyExpr!!, null),
+ ZBytes.from(replyPayload),
Encoding(encodingId, schema = encodingSchema),
SampleKind.fromInt(kind),
timestamp,
QoS(CongestionControl.fromInt(congestionControl), Priority.fromInt(priority), express),
- attachmentBytes?.into()
+ replyAttachment?.let { ZBytes.from(it) }
)
reply = Reply(replierZid?.let { EntityGlobalId(ZenohId(it), replierEid.toUInt()) }, Result.success(sample))
} else {
reply = Reply(
replierZid?.let { EntityGlobalId(ZenohId(it), replierEid.toUInt()) }, Result.failure(
ReplyError(
- payload.into(),
+ ZBytes.from(replyPayload),
Encoding(encodingId, schema = encodingSchema)
)
)
@@ -86,20 +86,18 @@ internal object JNILiveliness {
}
callback.run(reply)
}
- getViaJNI(
- jniSession.sessionPtr.get(),
- keyExpr.jniKeyExpr?.ptr ?: 0,
+ jniSession.livelinessGet(
+ keyExpr.jniKeyExpr,
keyExpr.keyExpr,
getCallback,
timeout.toMillis(),
- onClose
+ JNIOnCloseCallback { onClose() }
)
receiver
}
fun declareToken(jniSession: JNISession, keyExpr: KeyExpr): LivelinessToken {
- val ptr = declareTokenViaJNI(jniSession.sessionPtr.get(), keyExpr.jniKeyExpr?.ptr ?: 0, keyExpr.keyExpr)
- return LivelinessToken(JNILivelinessToken(ptr))
+ return LivelinessToken(jniSession.declareLivelinessToken(keyExpr.jniKeyExpr, keyExpr.keyExpr))
}
fun declareSubscriber(
@@ -115,43 +113,22 @@ internal object JNILiveliness {
val timestamp = if (timestampIsValid) TimeStamp(timestampNTP64) else null
val sample = Sample(
KeyExpr(keyExpr2, null),
- payload.into(),
+ ZBytes.from(payload),
Encoding(encodingId, schema = encodingSchema),
SampleKind.fromInt(kind),
timestamp,
QoS(CongestionControl.fromInt(congestionControl), Priority.fromInt(priority), express),
- attachmentBytes?.into()
+ attachmentBytes?.let { ZBytes.from(it) }
)
callback.run(sample)
}
- val ptr = declareSubscriberViaJNI(
- jniSession.sessionPtr.get(),
- keyExpr.jniKeyExpr?.ptr ?: 0,
+ val jniSubscriber = jniSession.declareLivelinessSubscriber(
+ keyExpr.jniKeyExpr,
keyExpr.keyExpr,
subCallback,
history,
- onClose
+ JNIOnCloseCallback { onClose() }
)
- Subscriber(keyExpr, receiver, JNISubscriber(ptr))
+ Subscriber(keyExpr, receiver, jniSubscriber)
}
-
- private external fun getViaJNI(
- sessionPtr: Long,
- keyExprPtr: Long,
- keyExprString: String,
- callback: JNIGetCallback,
- timeoutMs: Long,
- onClose: JNIOnCloseCallback
- )
-
- private external fun declareTokenViaJNI(sessionPtr: Long, keyExprPtr: Long, keyExprString: String): Long
-
- private external fun declareSubscriberViaJNI(
- sessionPtr: Long,
- keyExprPtr: Long,
- keyExprString: String,
- callback: JNISubscriberCallback,
- history: Boolean,
- onClose: JNIOnCloseCallback
- ): Long
}
diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNILivelinessToken.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNILivelinessToken.kt
deleted file mode 100644
index 991c860a..00000000
--- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNILivelinessToken.kt
+++ /dev/null
@@ -1,12 +0,0 @@
-package io.zenoh.jni
-
-internal class JNILivelinessToken(val ptr: Long) {
-
- fun undeclare() {
- undeclareViaJNI(this.ptr)
- }
-
- companion object {
- external fun undeclareViaJNI(ptr: Long)
- }
-}
diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIMatchingListener.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIMatchingListener.kt
deleted file mode 100644
index c2895378..00000000
--- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIMatchingListener.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-//
-// Copyright (c) 2025 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-package io.zenoh.jni
-
-import io.zenoh.pubsub.MatchingListener
-
-/**
- * Adapter class to handle the interactions with Zenoh through JNI for a [MatchingListener].
- *
- * @property ptr: raw pointer to the underlying native Publisher.
- */
-internal class JNIMatchingListener(private val ptr: Long) {
-
- /**
- * Close and free the underlying matching listener pointer.
- *
- * Further operations with this publisher should not be performed anymore.
- */
- fun close() {
- freePtrViaJNI(ptr)
- }
-
- private external fun freePtrViaJNI(ptr: Long)
-
-}
diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIPublisher.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIPublisher.kt
deleted file mode 100644
index a5c3ea9c..00000000
--- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIPublisher.kt
+++ /dev/null
@@ -1,69 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-package io.zenoh.jni
-
-import io.zenoh.exceptions.ZError
-import io.zenoh.bytes.Encoding
-import io.zenoh.bytes.IntoZBytes
-import io.zenoh.pubsub.Publisher
-
-/**
- * Adapter class to handle the interactions with Zenoh through JNI for a [Publisher].
- *
- * @property ptr: raw pointer to the underlying native Publisher.
- */
-internal class JNIPublisher(private val ptr: Long) {
-
- /**
- * Put operation.
- *
- * @param payload Payload of the put.
- * @param encoding Encoding of the payload.
- * @param attachment Optional attachment.
- */
- fun put(payload: IntoZBytes, encoding: Encoding?, attachment: IntoZBytes?): Result = runCatching {
- val resolvedEncoding = encoding ?: Encoding.default()
- putViaJNI(payload.into().bytes, resolvedEncoding.id, resolvedEncoding.schema, attachment?.into()?.bytes, ptr)
- }
-
- /**
- * Delete operation.
- *
- * @param attachment Optional attachment.
- */
- fun delete(attachment: IntoZBytes?): Result = runCatching {
- deleteViaJNI(attachment?.into()?.bytes, ptr)
- }
-
- /**
- * Close and free the underlying publisher pointer.
- *
- * Further operations with this publisher should not be performed anymore.
- */
- fun close() {
- freePtrViaJNI(ptr)
- }
-
- @Throws(ZError::class)
- private external fun putViaJNI(
- valuePayload: ByteArray, encodingId: Int, encodingSchema: String?, attachment: ByteArray?, ptr: Long
- )
-
- @Throws(ZError::class)
- private external fun deleteViaJNI(attachment: ByteArray?, ptr: Long)
-
- private external fun freePtrViaJNI(ptr: Long)
-
-}
diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIQuerier.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIQuerier.kt
deleted file mode 100644
index 28a195e0..00000000
--- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIQuerier.kt
+++ /dev/null
@@ -1,123 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-package io.zenoh.jni
-
-import io.zenoh.bytes.Encoding
-import io.zenoh.bytes.IntoZBytes
-import io.zenoh.bytes.into
-import io.zenoh.config.EntityGlobalId
-import io.zenoh.config.ZenohId
-import io.zenoh.exceptions.ZError
-import io.zenoh.handlers.Callback
-import io.zenoh.jni.callbacks.JNIGetCallback
-import io.zenoh.jni.callbacks.JNIOnCloseCallback
-import io.zenoh.keyexpr.KeyExpr
-import io.zenoh.qos.CongestionControl
-import io.zenoh.qos.Priority
-import io.zenoh.qos.QoS
-import io.zenoh.query.Parameters
-import io.zenoh.query.Reply
-import io.zenoh.query.ReplyError
-import io.zenoh.sample.Sample
-import io.zenoh.sample.SampleKind
-import org.apache.commons.net.ntp.TimeStamp
-
-internal class JNIQuerier(val ptr: Long) {
-
- fun performGet(
- keyExpr: KeyExpr,
- parameters: Parameters?,
- callback: Callback,
- onClose: () -> Unit,
- receiver: R,
- attachment: IntoZBytes?,
- payload: IntoZBytes?,
- encoding: Encoding?
- ): Result = runCatching {
- val getCallback = JNIGetCallback {
- replierZid: ByteArray?,
- replierEid: Int,
- success: Boolean,
- keyExpr: String?,
- payload: ByteArray,
- encodingId: Int,
- encodingSchema: String?,
- kind: Int,
- timestampNTP64: Long,
- timestampIsValid: Boolean,
- attachmentBytes: ByteArray?,
- express: Boolean,
- priority: Int,
- congestionControl: Int,
- ->
- val reply: Reply
- if (success) {
- val timestamp = if (timestampIsValid) TimeStamp(timestampNTP64) else null
- val sample = Sample(
- KeyExpr(keyExpr!!, null),
- payload.into(),
- Encoding(encodingId, schema = encodingSchema),
- SampleKind.fromInt(kind),
- timestamp,
- QoS(CongestionControl.fromInt(congestionControl), Priority.fromInt(priority), express),
- attachmentBytes?.into()
- )
- reply = Reply(replierZid?.let { EntityGlobalId(ZenohId(it), replierEid.toUInt()) }, Result.success(sample))
- } else {
- reply = Reply(
- replierZid?.let { EntityGlobalId(ZenohId(it), replierEid.toUInt()) }, Result.failure(
- ReplyError(
- payload.into(),
- Encoding(encodingId, schema = encodingSchema)
- )
- )
- )
- }
- callback.run(reply)
- }
- getViaJNI(this.ptr,
- keyExpr.jniKeyExpr?.ptr ?: 0,
- keyExpr.keyExpr,
- parameters?.toString(),
- getCallback,
- onClose,
- attachment?.into()?.bytes,
- payload?.into()?.bytes,
- encoding?.id ?: Encoding.default().id,
- encoding?.schema
- )
- receiver
- }
-
- fun close() {
- freePtrViaJNI(ptr)
- }
-
- @Throws(ZError::class)
- private external fun getViaJNI(
- querierPtr: Long,
- keyExprPtr: Long,
- keyExprString: String,
- parameters: String?,
- callback: JNIGetCallback,
- onClose: JNIOnCloseCallback,
- attachmentBytes: ByteArray?,
- payload: ByteArray?,
- encodingId: Int,
- encodingSchema: String?,
- )
-
- private external fun freePtrViaJNI(ptr: Long)
-}
diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIQuery.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIQuery.kt
deleted file mode 100644
index b176b970..00000000
--- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIQuery.kt
+++ /dev/null
@@ -1,107 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-package io.zenoh.jni
-
-import io.zenoh.exceptions.ZError
-import io.zenoh.keyexpr.KeyExpr
-import io.zenoh.bytes.Encoding
-import io.zenoh.qos.QoS
-import io.zenoh.bytes.IntoZBytes
-import io.zenoh.sample.Sample
-import org.apache.commons.net.ntp.TimeStamp
-
-/**
- * Adapter class for interacting with a Query using JNI.
- *
- * This class serves as an adapter for interacting with a Query through JNI (Java Native Interface).
- *
- * @property ptr The raw pointer to the underlying native query.
- */
-internal class JNIQuery(private val ptr: Long) {
-
- fun replySuccess(sample: Sample): Result = runCatching {
- val timestampEnabled = sample.timestamp != null
- replySuccessViaJNI(
- ptr,
- sample.keyExpr.jniKeyExpr?.ptr ?: 0,
- sample.keyExpr.keyExpr,
- sample.payload.bytes,
- sample.encoding.id,
- sample.encoding.schema,
- timestampEnabled,
- if (timestampEnabled) sample.timestamp!!.ntpValue() else 0,
- sample.attachment?.bytes,
- sample.qos.express,
- )
- }
-
- fun replyError(error: IntoZBytes, encoding: Encoding): Result = runCatching {
- replyErrorViaJNI(ptr, error.into().bytes, encoding.id, encoding.schema)
- }
-
- fun replyDelete(keyExpr: KeyExpr, timestamp: TimeStamp?, attachment: IntoZBytes?, qos: QoS): Result =
- runCatching {
- val timestampEnabled = timestamp != null
- replyDeleteViaJNI(
- ptr,
- keyExpr.jniKeyExpr?.ptr ?: 0,
- keyExpr.keyExpr,
- timestampEnabled,
- if (timestampEnabled) timestamp!!.ntpValue() else 0,
- attachment?.into()?.bytes,
- qos.express,
- )
- }
-
- fun close() {
- freePtrViaJNI(ptr)
- }
-
- @Throws(ZError::class)
- private external fun replySuccessViaJNI(
- queryPtr: Long,
- keyExprPtr: Long,
- keyExprString: String,
- valuePayload: ByteArray,
- valueEncodingId: Int,
- valueEncodingSchema: String?,
- timestampEnabled: Boolean,
- timestampNtp64: Long,
- attachment: ByteArray?,
- qosExpress: Boolean,
- )
-
- @Throws(ZError::class)
- private external fun replyErrorViaJNI(
- queryPtr: Long,
- errorValuePayload: ByteArray,
- errorValueEncoding: Int,
- encodingSchema: String?,
- )
-
- @Throws(ZError::class)
- private external fun replyDeleteViaJNI(
- queryPtr: Long,
- keyExprPtr: Long,
- keyExprString: String,
- timestampEnabled: Boolean,
- timestampNtp64: Long,
- attachment: ByteArray?,
- qosExpress: Boolean,
- )
-
- /** Frees the underlying native Query. */
- private external fun freePtrViaJNI(ptr: Long)
-}
diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIQueryable.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIQueryable.kt
deleted file mode 100644
index e5f7d3ce..00000000
--- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIQueryable.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-package io.zenoh.jni
-
-/**
- * Adapter class to handle the interactions with Zenoh through JNI for a [io.zenoh.query.Queryable]
- *
- * @property ptr: raw pointer to the underlying native Queryable.
- */
-internal class JNIQueryable(val ptr: Long) {
-
- fun close() {
- freePtrViaJNI(ptr)
- }
-
- /** Frees the underlying native Queryable. */
- private external fun freePtrViaJNI(ptr: Long)
-}
diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNISampleMissListener.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNISampleMissListener.kt
deleted file mode 100644
index b7f5b5ed..00000000
--- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNISampleMissListener.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-//
-// Copyright (c) 2025 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-package io.zenoh.jni
-
-import io.zenoh.pubsub.SampleMissListener
-
-/**
- * Adapter class to handle the interactions with Zenoh through JNI for a [SampleMissListener].
- *
- * @property ptr: raw pointer to the underlying native Publisher.
- */
-internal class JNISampleMissListener(private val ptr: Long) {
-
- /**
- * Close and free the underlying matching listener pointer.
- *
- * Further operations with this publisher should not be performed anymore.
- */
- fun close() {
- freePtrViaJNI(ptr)
- }
-
- private external fun freePtrViaJNI(ptr: Long)
-
-}
diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIScout.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIScout.kt
deleted file mode 100644
index cdc3f5e2..00000000
--- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIScout.kt
+++ /dev/null
@@ -1,65 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-package io.zenoh.jni
-
-import io.zenoh.Config
-import io.zenoh.exceptions.ZError
-import io.zenoh.handlers.Callback
-import io.zenoh.jni.callbacks.JNIScoutCallback
-import io.zenoh.config.ZenohId
-import io.zenoh.scouting.Hello
-import io.zenoh.scouting.Scout
-import io.zenoh.config.WhatAmI
-import io.zenoh.jni.callbacks.JNIOnCloseCallback
-
-/**
- * Adapter class to handle the interactions with Zenoh through JNI for a [io.zenoh.scouting.Scout]
- *
- * @property ptr: raw pointer to the underlying native scout.
- */
-internal class JNIScout(private val ptr: Long) {
-
- companion object {
- fun scout(
- whatAmI: Set,
- callback: Callback,
- onClose: () -> Unit,
- config: Config?,
- receiver: R
- ): Result> = runCatching {
- val scoutCallback = JNIScoutCallback { whatAmI2: Int, id: ByteArray, locators: List ->
- callback.run(Hello(WhatAmI.fromInt(whatAmI2), ZenohId(id), locators))
- }
- val binaryWhatAmI: Int = whatAmI.map { it.value }.reduce { acc, it -> acc or it }
- val ptr = scoutViaJNI(binaryWhatAmI, scoutCallback, onClose,config?.jniConfig?.ptr ?: 0)
- Scout(receiver, JNIScout(ptr))
- }
-
- @Throws(ZError::class)
- private external fun scoutViaJNI(
- whatAmI: Int,
- callback: JNIScoutCallback,
- onCloseCallback: JNIOnCloseCallback,
- configPtr: Long,
- ): Long
-
- @Throws(ZError::class)
- external fun freePtrViaJNI(ptr: Long)
- }
-
- fun close() {
- freePtrViaJNI(ptr)
- }
-}
diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNISession.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNISession.kt
deleted file mode 100644
index 214abe06..00000000
--- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNISession.kt
+++ /dev/null
@@ -1,552 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-package io.zenoh.jni
-
-import io.zenoh.*
-import io.zenoh.bytes.Encoding
-import io.zenoh.exceptions.ZError
-import io.zenoh.handlers.Callback
-import io.zenoh.jni.callbacks.JNIOnCloseCallback
-import io.zenoh.jni.callbacks.JNIGetCallback
-import io.zenoh.jni.callbacks.JNIQueryableCallback
-import io.zenoh.jni.callbacks.JNISubscriberCallback
-import io.zenoh.keyexpr.KeyExpr
-import io.zenoh.bytes.IntoZBytes
-import io.zenoh.config.ZenohId
-import io.zenoh.bytes.into
-import io.zenoh.Config
-import io.zenoh.config.EntityGlobalId
-import io.zenoh.pubsub.AdvancedSubscriber
-import io.zenoh.pubsub.AdvancedPublisher
-import io.zenoh.pubsub.Delete
-import io.zenoh.pubsub.Publisher
-import io.zenoh.pubsub.Put
-import io.zenoh.pubsub.Subscriber
-import io.zenoh.qos.CongestionControl
-import io.zenoh.qos.Priority
-import io.zenoh.qos.QoS
-import io.zenoh.query.*
-import io.zenoh.query.Query
-import io.zenoh.query.Queryable
-import io.zenoh.sample.Sample
-import io.zenoh.query.Parameters
-import io.zenoh.query.Selector
-import io.zenoh.qos.Reliability
-import io.zenoh.sample.SampleKind
-import io.zenoh.ext.CacheConfig
-import io.zenoh.ext.HeartbeatMode
-import io.zenoh.ext.MissDetectionConfig
-import io.zenoh.ext.HistoryConfig
-import io.zenoh.ext.RecoveryConfig
-import io.zenoh.ext.RecoveryMode
-import org.apache.commons.net.ntp.TimeStamp
-import java.time.Duration
-import java.util.concurrent.atomic.AtomicLong
-
-/** Adapter class to handle the communication with the Zenoh JNI code for a [Session]. */
-internal class JNISession {
-
- companion object {
- init {
- ZenohLoad
- }
- }
-
- /* Pointer to the underlying Rust zenoh session. */
- internal var sessionPtr: AtomicLong = AtomicLong(0)
-
- fun open(config: Config): Result = runCatching {
- val session = openSessionViaJNI(config.jniConfig.ptr)
- sessionPtr.set(session)
- }
-
- fun close(): Result = runCatching {
- closeSessionViaJNI(sessionPtr.get())
- }
-
- fun declarePublisher(keyExpr: KeyExpr, qos: QoS, encoding: Encoding, reliability: Reliability): Result = runCatching {
- val publisherRawPtr = declarePublisherViaJNI(
- keyExpr.jniKeyExpr?.ptr ?: 0,
- keyExpr.keyExpr,
- sessionPtr.get(),
- qos.congestionControl.value,
- qos.priority.value,
- qos.express,
- reliability.ordinal
- )
- Publisher(
- keyExpr,
- qos,
- encoding,
- JNIPublisher(publisherRawPtr),
- )
- }
-
- fun declareAdvancedPublisher(
- keyExpr: KeyExpr,
- qos: QoS,
- encoding: Encoding,
- reliability: Reliability,
- cache: CacheConfig?,
- sampleMissDetection: MissDetectionConfig?,
- publisherDetection: Boolean
- ): Result = runCatching {
-
- val publisherRawPtr = declareAdvancedPublisherViaJNI(
- keyExpr.jniKeyExpr?.ptr ?: 0,
- keyExpr.keyExpr,
- sessionPtr.get(),
- qos.congestionControl.value,
- qos.priority.value,
- qos.express,
- reliability.ordinal,
- cache != null,
- cache?.maxSamples ?: 0,
- cache?.repliesQoS?.priority?.value ?: 0,
- cache?.repliesQoS?.congestionControl?.value ?: 0,
- cache?.repliesQoS?.express ?: false,
- sampleMissDetection != null,
- sampleMissDetection?.heartbeat != null,
- when(val heartbeat = sampleMissDetection?.heartbeat) {
- is HeartbeatMode.PeriodicHeartbeat -> heartbeat.milliseconds
- is HeartbeatMode.SporadicHeartbeat -> heartbeat.milliseconds
- null -> 0
- },
- when(sampleMissDetection?.heartbeat) {
- is HeartbeatMode.PeriodicHeartbeat -> false
- is HeartbeatMode.SporadicHeartbeat -> true
- null -> false
- },
- publisherDetection
- )
- AdvancedPublisher(
- keyExpr,
- qos,
- encoding,
- JNIAdvancedPublisher(publisherRawPtr),
- )
- }
-
- fun declareSubscriber(
- keyExpr: KeyExpr, callback: Callback, onClose: () -> Unit, receiver: R
- ): Result> = runCatching {
- val subCallback =
- JNISubscriberCallback { keyExpr, payload, encodingId, encodingSchema, kind, timestampNTP64, timestampIsValid, attachmentBytes, express: Boolean, priority: Int, congestionControl: Int ->
- val timestamp = if (timestampIsValid) TimeStamp(timestampNTP64) else null
- val sample = Sample(
- KeyExpr(keyExpr, null),
- payload.into(),
- Encoding(encodingId, schema = encodingSchema),
- SampleKind.fromInt(kind),
- timestamp,
- QoS(CongestionControl.fromInt(congestionControl), Priority.fromInt(priority), express),
- attachmentBytes?.into()
- )
- callback.run(sample)
- }
- val subscriberRawPtr = declareSubscriberViaJNI(
- keyExpr.jniKeyExpr?.ptr ?: 0, keyExpr.keyExpr, sessionPtr.get(), subCallback, onClose
- )
- Subscriber(keyExpr, receiver, JNISubscriber(subscriberRawPtr))
- }
-
- fun declareAdvancedSubscriber(
- keyExpr: KeyExpr,
- history: HistoryConfig?,
- recovery: RecoveryConfig?,
- subscriberDetection: Boolean,
- callback: Callback,
- onClose: () -> Unit,
- receiver: R
- ): Result> = runCatching {
- val subCallback =
- JNISubscriberCallback { keyExpr, payload, encodingId, encodingSchema, kind, timestampNTP64, timestampIsValid, attachmentBytes, express: Boolean, priority: Int, congestionControl: Int ->
- val timestamp = if (timestampIsValid) TimeStamp(timestampNTP64) else null
- val sample = Sample(
- KeyExpr(keyExpr, null),
- payload.into(),
- Encoding(encodingId, schema = encodingSchema),
- SampleKind.fromInt(kind),
- timestamp,
- QoS(CongestionControl.fromInt(congestionControl), Priority.fromInt(priority), express),
- attachmentBytes?.into()
- )
- callback.run(sample)
- }
- val subscriberRawPtr = declareAdvancedSubscriberViaJNI(
- keyExpr.jniKeyExpr?.ptr ?: 0,
- keyExpr.keyExpr,
- sessionPtr.get(),
- history != null,
- history?.detectLatePublishers ?: false,
- history?.maxSamples ?: 0,
- history?.maxAgeSeconds ?: 0.0,
- recovery != null,
- when(recovery?.mode){
- is RecoveryMode.Heartbeat -> true
- is RecoveryMode.PeriodicQuery -> false
- null -> false
- },
- when(val mode = recovery?.mode){
- is RecoveryMode.Heartbeat -> 0
- is RecoveryMode.PeriodicQuery -> mode.milliseconds
- null -> 0
- },
- subscriberDetection,
- subCallback,
- onClose
- )
- AdvancedSubscriber(keyExpr, receiver, JNIAdvancedSubscriber(subscriberRawPtr))
- }
-
- fun declareQueryable(
- keyExpr: KeyExpr, callback: Callback, onClose: () -> Unit, receiver: R, complete: Boolean
- ): Result> = runCatching {
- val queryCallback =
- JNIQueryableCallback { keyExpr: String, selectorParams: String, payload: ByteArray?, encodingId: Int, encodingSchema: String?, attachmentBytes: ByteArray?, queryPtr: Long ->
- val jniQuery = JNIQuery(queryPtr)
- val keyExpr2 = KeyExpr(keyExpr, null)
- val selector = if (selectorParams.isEmpty()) {
- Selector(keyExpr2)
- } else {
- Selector(keyExpr2, Parameters.from(selectorParams).getOrThrow())
- }
- val query = Query(
- keyExpr2,
- selector,
- payload?.into(),
- payload?.let { Encoding(encodingId, schema = encodingSchema) },
- attachmentBytes?.into(),
- jniQuery
- )
- callback.run(query)
- }
- val queryableRawPtr = declareQueryableViaJNI(
- keyExpr.jniKeyExpr?.ptr ?: 0, keyExpr.keyExpr, sessionPtr.get(), queryCallback, onClose, complete
- )
- Queryable(keyExpr, receiver, JNIQueryable(queryableRawPtr))
- }
-
- fun declareQuerier(
- keyExpr: KeyExpr,
- target: QueryTarget,
- consolidation: ConsolidationMode,
- qos: QoS,
- timeout: Duration,
- acceptReplies: ReplyKeyExpr
- ): Result = runCatching {
- val querierRawPtr = declareQuerierViaJNI(
- keyExpr.jniKeyExpr?.ptr ?: 0, keyExpr.keyExpr, sessionPtr.get(), target.ordinal, consolidation.ordinal,
- qos.congestionControl.value, qos.priority.value, qos.express, timeout.toMillis(), acceptReplies.ordinal
- )
- Querier(keyExpr, qos, JNIQuerier(querierRawPtr))
- }
-
- fun performGet(
- selector: Selector,
- callback: Callback,
- onClose: () -> Unit,
- receiver: R,
- timeout: Duration,
- target: QueryTarget,
- consolidation: ConsolidationMode,
- payload: IntoZBytes?,
- encoding: Encoding?,
- attachment: IntoZBytes?,
- qos: QoS,
- acceptReplies: ReplyKeyExpr
- ): Result = runCatching {
- val getCallback = JNIGetCallback {
- replierZid: ByteArray?,
- replierEid: Int,
- success: Boolean,
- keyExpr: String?,
- payload: ByteArray,
- encodingId: Int,
- encodingSchema: String?,
- kind: Int,
- timestampNTP64: Long,
- timestampIsValid: Boolean,
- attachmentBytes: ByteArray?,
- express: Boolean,
- priority: Int,
- congestionControl: Int,
- ->
- val reply: Reply
- if (success) {
- val timestamp = if (timestampIsValid) TimeStamp(timestampNTP64) else null
- val sample = Sample(
- KeyExpr(keyExpr!!, null),
- payload.into(),
- Encoding(encodingId, schema = encodingSchema),
- SampleKind.fromInt(kind),
- timestamp,
- QoS(CongestionControl.fromInt(congestionControl), Priority.fromInt(priority), express),
- attachmentBytes?.into()
- )
- reply = Reply(replierZid?.let { EntityGlobalId(ZenohId(it), replierEid.toUInt()) }, Result.success(sample))
- } else {
- reply = Reply(
- replierZid?.let { EntityGlobalId(ZenohId(it), replierEid.toUInt()) }, Result.failure(
- ReplyError(
- payload.into(),
- Encoding(encodingId, schema = encodingSchema)
- )
- )
- )
- }
- callback.run(reply)
- }
-
- getViaJNI(
- selector.keyExpr.jniKeyExpr?.ptr ?: 0,
- selector.keyExpr.keyExpr,
- selector.parameters?.toString(),
- sessionPtr.get(),
- getCallback,
- onClose,
- timeout.toMillis(),
- target.ordinal,
- consolidation.ordinal,
- attachment?.into()?.bytes,
- payload?.into()?.bytes,
- encoding?.id ?: Encoding.default().id,
- encoding?.schema,
- qos.congestionControl.value,
- qos.priority.value,
- qos.express,
- acceptReplies.ordinal,
- )
- receiver
- }
-
- fun declareKeyExpr(keyExpr: String): Result = runCatching {
- val ptr = declareKeyExprViaJNI(sessionPtr.get(), keyExpr)
- return Result.success(KeyExpr(keyExpr, JNIKeyExpr(ptr)))
- }
-
- fun undeclareKeyExpr(keyExpr: KeyExpr): Result = runCatching {
- keyExpr.jniKeyExpr?.run {
- undeclareKeyExprViaJNI(sessionPtr.get(), this.ptr)
- keyExpr.jniKeyExpr = null
- } ?: throw ZError("Attempting to undeclare a non declared key expression.")
- }
-
- @Throws(ZError::class)
- fun performPut(
- keyExpr: KeyExpr,
- put: Put,
- ) {
- putViaJNI(
- keyExpr.jniKeyExpr?.ptr ?: 0,
- keyExpr.keyExpr,
- sessionPtr.get(),
- put.payload.bytes,
- put.encoding.id,
- put.encoding.schema,
- put.qos.congestionControl.value,
- put.qos.priority.value,
- put.qos.express,
- put.attachment?.bytes,
- put.reliability.ordinal
- )
- }
-
- @Throws(ZError::class)
- fun performDelete(
- keyExpr: KeyExpr,
- delete: Delete,
- ) {
- deleteViaJNI(
- keyExpr.jniKeyExpr?.ptr ?: 0,
- keyExpr.keyExpr,
- sessionPtr.get(),
- delete.qos.congestionControl.value,
- delete.qos.priority.value,
- delete.qos.express,
- delete.attachment?.bytes,
- delete.reliability.ordinal
- )
- }
-
- fun zid(): Result = runCatching {
- ZenohId(getZidViaJNI(sessionPtr.get()))
- }
-
- fun peersZid(): Result> = runCatching {
- getPeersZidViaJNI(sessionPtr.get()).map { ZenohId(it) }
- }
-
- fun routersZid(): Result> = runCatching {
- getRoutersZidViaJNI(sessionPtr.get()).map { ZenohId(it) }
- }
-
- @Throws(ZError::class)
- private external fun getZidViaJNI(ptr: Long): ByteArray
-
- @Throws(ZError::class)
- private external fun getPeersZidViaJNI(ptr: Long): List
-
- @Throws(ZError::class)
- private external fun getRoutersZidViaJNI(ptr: Long): List
-
- @Throws(ZError::class)
- private external fun openSessionViaJNI(configPtr: Long): Long
-
- @Throws(ZError::class)
- private external fun closeSessionViaJNI(ptr: Long)
-
- @Throws(ZError::class)
- private external fun declarePublisherViaJNI(
- keyExprPtr: Long,
- keyExprString: String,
- sessionPtr: Long,
- congestionControl: Int,
- priority: Int,
- express: Boolean,
- reliability: Int
- ): Long
-
- @Throws(ZError::class)
- private external fun declareAdvancedPublisherViaJNI(
- keyExprPtr: Long,
- keyExprString: String,
- sessionPtr: Long,
- congestionControl: Int,
- priority: Int,
- express: Boolean,
- reliability: Int,
- // CacheConfig
- cacheEnabled: Boolean,
- cacheMaxSamples: Long,
- cacheRepliesPriority: Int,
- cacheRepliesCongestionControl: Int,
- cacheRepliesIsExpress: Boolean,
- // MissDetectionConfig
- sampleMissDetectionEnabled: Boolean,
- sampleMissDetectionEnableHeartbeat: Boolean,
- sampleMissDetectionHeartbeatMs: Long,
- sampleMissDetectionHeartbeatIsSporadic: Boolean,
-
- publisherDetection: Boolean,
- ): Long
-
- @Throws(ZError::class)
- private external fun declareSubscriberViaJNI(
- keyExprPtr: Long,
- keyExprString: String,
- sessionPtr: Long,
- callback: JNISubscriberCallback,
- onClose: JNIOnCloseCallback,
- ): Long
-
- @Throws(ZError::class)
- private external fun declareAdvancedSubscriberViaJNI(
- keyExprPtr: Long,
- keyExprString: String,
- sessionPtr: Long,
- // HistoryConfig
- historyConfigEnabled: Boolean,
- historyDetectLatePublishers: Boolean,
- historyMaxSamples: Long,
- historyMaxAgeSeconds: Double,
- // RecoveryConfig
- recoveryConfigEnabled: Boolean,
- recoveryConfigIsHeartbeat: Boolean,
- recoveryQueryPeriodMs: Long,
-
- subscriberDetection: Boolean,
- callback: JNISubscriberCallback,
- onClose: JNIOnCloseCallback,
- ): Long
-
- @Throws(ZError::class)
- private external fun declareQueryableViaJNI(
- keyExprPtr: Long,
- keyExprString: String,
- sessionPtr: Long,
- callback: JNIQueryableCallback,
- onClose: JNIOnCloseCallback,
- complete: Boolean
- ): Long
-
- @Throws(ZError::class)
- private external fun declareQuerierViaJNI(
- keyExprPtr: Long,
- keyExprString: String,
- sessionPtr: Long,
- target: Int,
- consolidation: Int,
- congestionControl: Int,
- priority: Int,
- express: Boolean,
- timeoutMs: Long,
- acceptReplies: Int
- ): Long
-
- @Throws(ZError::class)
- private external fun declareKeyExprViaJNI(sessionPtr: Long, keyExpr: String): Long
-
- @Throws(ZError::class)
- private external fun undeclareKeyExprViaJNI(sessionPtr: Long, keyExprPtr: Long)
-
- @Throws(ZError::class)
- private external fun getViaJNI(
- keyExprPtr: Long,
- keyExprString: String,
- selectorParams: String?,
- sessionPtr: Long,
- callback: JNIGetCallback,
- onClose: JNIOnCloseCallback,
- timeoutMs: Long,
- target: Int,
- consolidation: Int,
- attachmentBytes: ByteArray?,
- payload: ByteArray?,
- encodingId: Int,
- encodingSchema: String?,
- congestionControl: Int,
- priority: Int,
- express: Boolean,
- acceptReplies: Int,
- )
-
- @Throws(ZError::class)
- private external fun putViaJNI(
- keyExprPtr: Long,
- keyExprString: String,
- sessionPtr: Long,
- valuePayload: ByteArray,
- valueEncoding: Int,
- valueEncodingSchema: String?,
- congestionControl: Int,
- priority: Int,
- express: Boolean,
- attachmentBytes: ByteArray?,
- reliability: Int
- )
-
- @Throws(ZError::class)
- private external fun deleteViaJNI(
- keyExprPtr: Long,
- keyExprString: String,
- sessionPtr: Long,
- congestionControl: Int,
- priority: Int,
- express: Boolean,
- attachmentBytes: ByteArray?,
- reliability: Int
- )
-}
diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNISubscriber.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNISubscriber.kt
deleted file mode 100644
index 957c13e1..00000000
--- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNISubscriber.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-package io.zenoh.jni
-
-import io.zenoh.pubsub.Subscriber
-
-/**
- * Adapter class to handle the interactions with Zenoh through JNI for a [Subscriber]
- *
- * @property ptr: raw pointer to the underlying native Subscriber.
- */
-internal class JNISubscriber(private val ptr: Long) {
-
- fun close() {
- freePtrViaJNI(ptr)
- }
-
- /** Frees the underlying native Subscriber. */
- private external fun freePtrViaJNI(ptr: Long)
-
-}
diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIZBytes.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIZBytes.kt
deleted file mode 100644
index 8e9e94b2..00000000
--- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIZBytes.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-package io.zenoh.jni
-
-import io.zenoh.ZenohLoad
-import io.zenoh.bytes.ZBytes
-import kotlin.reflect.KType
-
-@PublishedApi
-internal object JNIZBytes {
-
- init {
- ZenohLoad
- }
-
- external fun serializeViaJNI(any: Any, kType: KType): ZBytes
-
- external fun deserializeViaJNI(zBytes: ZBytes, kType: KType): Any
-}
diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIZenohId.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIZenohId.kt
deleted file mode 100644
index 53ecb5dc..00000000
--- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/JNIZenohId.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-package io.zenoh.jni
-
-import io.zenoh.ZenohLoad
-
-internal object JNIZenohId {
-
- init {
- ZenohLoad
- }
-
- external fun toStringViaJNI(bytes: ByteArray): String
-
-}
diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/callbacks/JNIGetCallback.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/callbacks/JNIGetCallback.kt
deleted file mode 100644
index 14f3c8e9..00000000
--- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/callbacks/JNIGetCallback.kt
+++ /dev/null
@@ -1,35 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-package io.zenoh.jni.callbacks
-
-internal fun interface JNIGetCallback {
-
- fun run(
- replierZid: ByteArray?,
- replierEid: Int,
- success: Boolean,
- keyExpr: String?,
- payload: ByteArray,
- encodingId: Int,
- encodingSchema: String?,
- kind: Int,
- timestampNTP64: Long,
- timestampIsValid: Boolean,
- attachment: ByteArray?,
- express: Boolean,
- priority: Int,
- congestionControl: Int,
- )
-}
diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/callbacks/JNIMatchingListenerCallback.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/callbacks/JNIMatchingListenerCallback.kt
deleted file mode 100644
index d056c47d..00000000
--- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/callbacks/JNIMatchingListenerCallback.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-//
-// Copyright (c) 2025 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-package io.zenoh.jni.callbacks
-
-internal fun interface JNIMatchingListenerCallback {
- fun run(
- matching: Boolean,
- )
-}
diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/callbacks/JNIOnCloseCallback.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/callbacks/JNIOnCloseCallback.kt
deleted file mode 100644
index b58fa23d..00000000
--- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/callbacks/JNIOnCloseCallback.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-package io.zenoh.jni.callbacks
-
-internal fun interface JNIOnCloseCallback {
-
- fun run()
-
-}
diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/callbacks/JNIQueryableCallback.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/callbacks/JNIQueryableCallback.kt
deleted file mode 100644
index 31f5885f..00000000
--- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/callbacks/JNIQueryableCallback.kt
+++ /dev/null
@@ -1,25 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-package io.zenoh.jni.callbacks
-
-internal fun interface JNIQueryableCallback {
- fun run(keyExpr: String,
- selectorParams: String,
- payload: ByteArray?,
- encodingId: Int,
- encodingSchema: String?,
- attachmentBytes: ByteArray?,
- queryPtr: Long)
-}
diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/callbacks/JNISampleMissListenerCallback.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/callbacks/JNISampleMissListenerCallback.kt
deleted file mode 100644
index a2111f4b..00000000
--- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/callbacks/JNISampleMissListenerCallback.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-//
-// Copyright (c) 2025 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-package io.zenoh.jni.callbacks
-
-internal fun interface JNISampleMissListenerCallback {
- fun run(
- zidLower: Long,
- zidUpper: Long,
- eid: Long,
- missedCount: Long
- )
-}
diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/callbacks/JNIScoutCallback.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/callbacks/JNIScoutCallback.kt
deleted file mode 100644
index 0a8b20e9..00000000
--- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/callbacks/JNIScoutCallback.kt
+++ /dev/null
@@ -1,20 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-package io.zenoh.jni.callbacks
-
-internal fun interface JNIScoutCallback {
-
- fun run(whatAmI: Int, zid: ByteArray, locators: List)
-}
diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/callbacks/JNISubscriberCallback.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/callbacks/JNISubscriberCallback.kt
deleted file mode 100644
index 76373c72..00000000
--- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/jni/callbacks/JNISubscriberCallback.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-//
-// Copyright (c) 2023 ZettaScale Technology
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License 2.0 which is available at
-// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-//
-// Contributors:
-// ZettaScale Zenoh Team,
-//
-
-package io.zenoh.jni.callbacks
-
-internal fun interface JNISubscriberCallback {
- fun run(
- keyExpr: String,
- payload: ByteArray,
- encodingId: Int,
- encodingSchema: String?,
- kind: Int,
- timestampNTP64: Long,
- timestampIsValid: Boolean,
- attachment: ByteArray?,
- express: Boolean,
- priority: Int,
- congestionControl: Int,
- )
-}
diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/keyexpr/KeyExpr.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/keyexpr/KeyExpr.kt
index 4a2cae3a..0085139c 100644
--- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/keyexpr/KeyExpr.kt
+++ b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/keyexpr/KeyExpr.kt
@@ -70,7 +70,7 @@ class KeyExpr internal constructor(internal val keyExpr: String, internal var jn
* @return a [Result] with the [KeyExpr] in case of success.
*/
fun tryFrom(keyExpr: String) : Result {
- return JNIKeyExpr.tryFrom(keyExpr)
+ return runCatching { KeyExpr(JNIKeyExpr.tryFrom(keyExpr)) }
}
/**
@@ -83,7 +83,7 @@ class KeyExpr internal constructor(internal val keyExpr: String, internal var jn
* @return a [Result] with the canonized [KeyExpr] in case of success.
*/
fun autocanonize(keyExpr: String): Result {
- return JNIKeyExpr.autocanonize(keyExpr)
+ return runCatching { KeyExpr(JNIKeyExpr.autocanonize(keyExpr)) }
}
}
@@ -93,7 +93,7 @@ class KeyExpr internal constructor(internal val keyExpr: String, internal var jn
* This method returns `True` if there exists at least one key that belongs to both sets defined by `this` and the `other` key expressions.
*/
fun intersects(other: KeyExpr): Boolean {
- return JNIKeyExpr.intersects(this, other)
+ return JNIKeyExpr.intersects(this.jniKeyExpr, this.keyExpr, other.jniKeyExpr, other.keyExpr)
}
/**
@@ -102,7 +102,7 @@ class KeyExpr internal constructor(internal val keyExpr: String, internal var jn
* This method returns `true` when all the keys defined by `other` also belong to the set defined by `this`.
*/
fun includes(other: KeyExpr): Boolean {
- return JNIKeyExpr.includes(this, other)
+ return JNIKeyExpr.includes(this.jniKeyExpr, this.keyExpr, other.jniKeyExpr, other.keyExpr)
}
/**
@@ -111,7 +111,7 @@ class KeyExpr internal constructor(internal val keyExpr: String, internal var jn
* so you should favor these methods for most applications.
*/
fun relationTo(other: KeyExpr): SetIntersectionLevel {
- return JNIKeyExpr.relationTo(this, other)
+ return SetIntersectionLevel.fromInt(JNIKeyExpr.relationTo(this.jniKeyExpr, this.keyExpr, other.jniKeyExpr, other.keyExpr))
}
/**
@@ -119,7 +119,7 @@ class KeyExpr internal constructor(internal val keyExpr: String, internal var jn
* This should be your preferred method when concatenating path segments.
*/
fun join(other: String): Result {
- return JNIKeyExpr.joinViaJNI(this, other)
+ return runCatching { KeyExpr(JNIKeyExpr.join(this.jniKeyExpr, this.keyExpr, other)) }
}
/**
@@ -127,7 +127,7 @@ class KeyExpr internal constructor(internal val keyExpr: String, internal var jn
* You should probably prefer [join] as Zenoh may then take advantage of the hierarchical separation it inserts.
*/
fun concat(other: String): Result {
- return JNIKeyExpr.concatViaJNI(this, other)
+ return runCatching { KeyExpr(JNIKeyExpr.concat(this.jniKeyExpr, this.keyExpr, other)) }
}
override fun toString(): String {
diff --git a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/pubsub/AdvancedPublisher.kt b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/pubsub/AdvancedPublisher.kt
index 765ba626..ead60816 100644
--- a/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/pubsub/AdvancedPublisher.kt
+++ b/zenoh-kotlin/src/commonMain/kotlin/io/zenoh/pubsub/AdvancedPublisher.kt
@@ -17,6 +17,8 @@ package io.zenoh.pubsub
import io.zenoh.annotations.Unstable
import io.zenoh.exceptions.ZError
import io.zenoh.jni.JNIAdvancedPublisher
+import io.zenoh.jni.callbacks.JNIMatchingListenerCallback
+import io.zenoh.jni.callbacks.JNIOnCloseCallback
import io.zenoh.keyexpr.KeyExpr
import io.zenoh.bytes.Encoding
import io.zenoh.qos.QoS
@@ -59,10 +61,15 @@ class AdvancedPublisher internal constructor(
* */
fun declareMatchingListener(callback: MatchingCallback,
onClose: (() -> Unit)? = null,): Result