├── libsql ├── consumer-rules.pro ├── src │ ├── main │ │ ├── rust │ │ │ ├── .gitignore │ │ │ ├── Cargo.toml │ │ │ ├── build.rs │ │ │ ├── src │ │ │ │ └── lib.rs │ │ │ └── Cargo.lock │ │ ├── AndroidManifest.xml │ │ ├── kotlin │ │ │ └── tech │ │ │ │ └── turso │ │ │ │ └── libsql │ │ │ │ ├── EmbeddedReplicaDatabase.kt │ │ │ │ ├── RowsIterator.kt │ │ │ │ ├── Database.kt │ │ │ │ ├── Connection.kt │ │ │ │ ├── Rows.kt │ │ │ │ ├── Libsql.kt │ │ │ │ ├── ConnectionImpl.kt │ │ │ │ └── Transaction.kt │ │ └── proto │ │ │ └── libsql.proto │ └── androidTest │ │ └── java │ │ └── tech │ │ └── turso │ │ └── libsql │ │ └── LibsqlTest.java ├── .gitignore ├── proguard-rules.pro └── build.gradle.kts ├── examples └── todo │ ├── .gitignore │ ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ └── kotlin │ │ └── tech │ │ └── turso │ │ └── libsql │ │ └── examples │ │ └── todo │ │ ├── ui │ │ └── theme │ │ │ └── Theme.kt │ │ └── MainActivity.kt │ └── build.gradle.kts ├── .github └── cover.png ├── gradle ├── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties └── libs.versions.toml ├── rust-toolchain.toml ├── .gitignore ├── settings.gradle.kts ├── LICENSE ├── gradle.properties ├── CONTRIBUTING.md ├── gradlew.bat ├── README.md └── gradlew /libsql/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/todo/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /libsql/src/main/rust/.gitignore: -------------------------------------------------------------------------------- 1 | target/ -------------------------------------------------------------------------------- /libsql/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | .lastDeploymentsId 3 | -------------------------------------------------------------------------------- /.github/cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tursodatabase/libsql-android/HEAD/.github/cover.png -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tursodatabase/libsql-android/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "stable" 3 | targets = [ 4 | "aarch64-linux-android", 5 | "armv7-linux-androideabi", 6 | "i686-linux-android", 7 | "x86_64-linux-android", 8 | ] 9 | -------------------------------------------------------------------------------- /libsql/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat May 11 16:20:35 CEST 2024 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /libsql/src/main/kotlin/tech/turso/libsql/EmbeddedReplicaDatabase.kt: -------------------------------------------------------------------------------- 1 | package tech.turso.libsql 2 | 3 | class EmbeddedReplicaDatabase(inner: Long) : Database(inner) { 4 | fun sync() { 5 | require(this.inner != 0L) { "Attempted to sync a closed Database" } 6 | nativeSync(this.inner) 7 | } 8 | 9 | private external fun nativeSync(db: Long) 10 | } 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .idea/ 11 | .DS_Store 12 | /build 13 | /captures 14 | .externalNativeBuild 15 | .project 16 | .settings 17 | .classpath 18 | .kotlin 19 | .cxx 20 | local.properties 21 | kls_database.db 22 | -------------------------------------------------------------------------------- /libsql/src/main/kotlin/tech/turso/libsql/RowsIterator.kt: -------------------------------------------------------------------------------- 1 | package tech.turso.libsql 2 | 3 | class RowsIterator(val rows: Rows): Iterator { 4 | private var currentRow: Row = rows.next() 5 | 6 | override fun hasNext(): Boolean = currentRow.isNotEmpty() 7 | 8 | override fun next(): Row { 9 | val previousRow = this.currentRow 10 | this.currentRow = this.rows.next() 11 | return previousRow 12 | } 13 | } -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | google { 4 | content { 5 | includeGroupByRegex("com\\.android.*") 6 | includeGroupByRegex("com\\.google.*") 7 | includeGroupByRegex("androidx.*") 8 | } 9 | } 10 | mavenCentral() 11 | gradlePluginPortal() 12 | } 13 | } 14 | dependencyResolutionManagement { 15 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 16 | repositories { 17 | google() 18 | mavenCentral() 19 | } 20 | } 21 | 22 | rootProject.name = "libsql" 23 | include(":libsql") 24 | include(":examples:todo") 25 | -------------------------------------------------------------------------------- /libsql/src/main/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "libsql_android" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [lib] 7 | crate-type = ["dylib"] 8 | 9 | [profile.dev] 10 | panic = "unwind" 11 | 12 | [profile.release] 13 | panic = "unwind" 14 | 15 | [dependencies] 16 | tokio = { version = "1", features = ["full"] } 17 | hyper-rustls = { version = "0.25", features = ["webpki-roots"]} 18 | jni-mangle = "0.1.2" 19 | jni_fn = "0.1.2" 20 | jni = { version = "0.21.1", default-features = false } 21 | prost = "0.13.*" 22 | prost-types = "0.13.*" 23 | lazy_static = "1.5.0" 24 | catch_panic = { git = "https://github.com/sorz/catch_panic.git", branch = "fix-jni-0.21" } 25 | anyhow = "1.0.86" 26 | libsql = "0.9.11" 27 | 28 | [build-dependencies] 29 | prost-build = "0.13.1" 30 | -------------------------------------------------------------------------------- /libsql/src/main/kotlin/tech/turso/libsql/Database.kt: -------------------------------------------------------------------------------- 1 | package tech.turso.libsql 2 | 3 | open class Database internal constructor(protected var inner: Long) : AutoCloseable { 4 | init { 5 | require(this.inner != 0L) { "Attempted to construct a Database with a null pointer" } 6 | } 7 | 8 | fun connect(): Connection { 9 | require(this.inner != 0L) { "Attempted to connect to a closed Database" } 10 | return ConnectionImpl(nativeConnect(this.inner)) 11 | } 12 | 13 | override fun close() { 14 | require(this.inner != 0L) { "Database already closed" } 15 | nativeClose(this.inner) 16 | this.inner = 0L 17 | } 18 | 19 | private external fun nativeClose(db: Long) 20 | 21 | private external fun nativeConnect(db: Long): Long 22 | } 23 | -------------------------------------------------------------------------------- /libsql/src/main/proto/libsql.proto: -------------------------------------------------------------------------------- 1 | 2 | syntax = "proto3"; 3 | 4 | option java_package = "tech.turso.libsql.proto"; 5 | option java_outer_classname = "Proto"; 6 | option java_multiple_files = true; 7 | 8 | message Parameters { 9 | oneof parameters { 10 | NamedParameters named = 1; 11 | PositionalParameters positional = 2; 12 | } 13 | } 14 | 15 | message NamedParameters { 16 | map parameters = 1; 17 | } 18 | 19 | message PositionalParameters { 20 | repeated Value parameters = 1; 21 | } 22 | 23 | message Row { 24 | repeated Value values = 1; 25 | } 26 | 27 | message Value { 28 | oneof value { 29 | Null null = 1; 30 | sint64 integer = 2; 31 | double real = 3; 32 | string text = 4; 33 | bytes blob = 5; 34 | } 35 | 36 | message Null {} 37 | } 38 | -------------------------------------------------------------------------------- /libsql/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /libsql/src/main/kotlin/tech/turso/libsql/Connection.kt: -------------------------------------------------------------------------------- 1 | package tech.turso.libsql 2 | 3 | interface Connection : AutoCloseable { 4 | fun execute(sql: String) 5 | 6 | fun executeBatch(sql: String) 7 | 8 | fun executeBatch(sql: List) { 9 | executeBatch(sql.joinToString("; ")) 10 | } 11 | 12 | fun execute( 13 | sql: String, 14 | params: Map, 15 | ) 16 | 17 | fun execute( 18 | sql: String, 19 | vararg params: Any?, 20 | ) 21 | 22 | fun query(sql: String): Rows 23 | 24 | fun query( 25 | sql: String, 26 | params: Map, 27 | ): Rows 28 | 29 | fun query( 30 | sql: String, 31 | vararg params: Any?, 32 | ): Rows 33 | 34 | fun transaction(): Transaction 35 | 36 | override fun close() 37 | } 38 | -------------------------------------------------------------------------------- /examples/todo/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /examples/todo/src/main/kotlin/tech/turso/libsql/examples/todo/ui/theme/Theme.kt: -------------------------------------------------------------------------------- 1 | package tech.turso.libsql.examples.todo.ui.theme 2 | 3 | import androidx.compose.material3.MaterialTheme 4 | import androidx.compose.material3.darkColorScheme 5 | import androidx.compose.runtime.Composable 6 | import androidx.compose.ui.graphics.Color 7 | 8 | private val DarkColorScheme = darkColorScheme( 9 | primary = Color(0XFF4FF8D2), 10 | 11 | primaryContainer = Color(0XFF4FF8D2), 12 | onPrimaryContainer = Color(0xFF00483b), 13 | 14 | secondaryContainer = Color(0xFFCC454F), 15 | onSecondaryContainer = Color(0xFFFFFFFF), 16 | 17 | surfaceVariant = Color(0xFF15262B), 18 | ) 19 | 20 | @Composable 21 | fun TodoTheme( 22 | content: @Composable () -> Unit 23 | ) { 24 | MaterialTheme( 25 | colorScheme = DarkColorScheme, 26 | content = content, 27 | ) 28 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Turso (libSQL) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /libsql/src/main/kotlin/tech/turso/libsql/Rows.kt: -------------------------------------------------------------------------------- 1 | package tech.turso.libsql 2 | 3 | import java.util.function.Consumer 4 | import tech.turso.libsql.proto.Row as ProtoRow 5 | 6 | typealias Row = List 7 | 8 | class Rows internal constructor(private var inner: Long) : AutoCloseable, Iterable { 9 | init { 10 | require(this.inner != 0L) { "Attempted to construct a Rows with a null pointer" } 11 | } 12 | 13 | fun next(): Row { 14 | val buf: ByteArray = nativeNext(this.inner) 15 | return ProtoRow.parseFrom(buf).valuesList.map { 16 | when { 17 | it.hasInteger() -> it.integer 18 | it.hasText() -> it.text 19 | it.hasReal() -> it.real 20 | it.hasBlob() -> it.blob.toByteArray() 21 | it.hasNull() -> null 22 | else -> RuntimeException("Invalid Row") 23 | } 24 | } 25 | } 26 | 27 | override fun close() { 28 | require(this.inner != 0L) { "Rows object already closed" } 29 | nativeClose(this.inner) 30 | this.inner = 0 31 | } 32 | 33 | override fun iterator(): Iterator = RowsIterator(this) 34 | 35 | private external fun nativeNext(rows: Long): ByteArray 36 | 37 | private external fun nativeClose(rows: Long) 38 | } 39 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. For more details, visit 12 | # https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app's APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Enables namespacing of each library's R class so that its R class includes only the 19 | # resources declared in the library itself and none from the library's dependencies, 20 | # thereby reducing the size of the R class for that library 21 | android.nonTransitiveRClass=true -------------------------------------------------------------------------------- /examples/todo/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias(libs.plugins.android.application) 3 | alias(libs.plugins.jetbrains.kotlin.android) 4 | id("org.jetbrains.kotlin.plugin.compose") version "2.0.10" 5 | } 6 | 7 | android { 8 | namespace = "tech.turso.lisbql.examples.todo" 9 | compileSdk = 34 10 | 11 | defaultConfig { 12 | applicationId = "tech.turso.lisbql.examples.todo" 13 | minSdk = 24 14 | targetSdk = 34 15 | versionCode = 1 16 | versionName = "1.0" 17 | 18 | testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" 19 | vectorDrawables { 20 | useSupportLibrary = true 21 | } 22 | } 23 | 24 | buildTypes { 25 | release { 26 | isMinifyEnabled = true 27 | } 28 | } 29 | compileOptions { 30 | sourceCompatibility = JavaVersion.VERSION_1_8 31 | targetCompatibility = JavaVersion.VERSION_1_8 32 | } 33 | kotlinOptions { 34 | jvmTarget = "1.8" 35 | } 36 | packaging { 37 | resources { 38 | excludes += "/META-INF/{AL2.0,LGPL2.1}" 39 | } 40 | } 41 | } 42 | 43 | dependencies { 44 | implementation(project(":libsql")) 45 | implementation(libs.androidx.core.ktx) 46 | implementation(libs.androidx.lifecycle.runtime.ktx) 47 | implementation(libs.androidx.activity.compose) 48 | implementation(platform(libs.androidx.compose.bom)) 49 | implementation(libs.androidx.ui) 50 | implementation(libs.androidx.ui.graphics) 51 | implementation(libs.androidx.ui.tooling.preview) 52 | implementation(libs.androidx.material3) 53 | testImplementation(libs.junit) 54 | androidTestImplementation(libs.androidx.junit) 55 | androidTestImplementation(libs.androidx.espresso.core) 56 | androidTestImplementation(platform(libs.androidx.compose.bom)) 57 | androidTestImplementation(libs.androidx.ui.test.junit4) 58 | debugImplementation(libs.androidx.ui.tooling) 59 | debugImplementation(libs.androidx.ui.test.manifest) 60 | } -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributor Manual 2 | 3 | Turso welcomes contributions from the community. This manual provides guidelines for contributing to `libsql-android` SDK. 4 | 5 | Make sure to [join us on Discord](https://tur.so/discord-php) — (`#libsql-android` channel) to discuss your ideas and get help. 6 | 7 | ## Prerequisites 8 | 9 | - Android Studio (latest version recommended) 10 | - Java Development Kit (JDK) 17 or higher 11 | - Android SDK (API level 21 or higher) 12 | - Rust and Cargo (latest stable version) 13 | - Android NDK (version 26.1.10909125 or compatible) 14 | 15 | ## Making Changes 16 | 17 | 1. Create a new branch for your feature or bug fix: `git switch -c my-new-feature` 18 | 2. Make changes and commit them with a clear commit message 19 | 3. Push your changes to your fork: `git push origin my-new-feature` 20 | 4. Open a Pull Request on the main repository 21 | 22 | ## Development Setup 23 | 24 | 1. Fork and clone the repository 25 | 2. Open the project in Android Studio 26 | 3. Make sure you have the Rust plugin installed in Android Studio 27 | 4. Set up the `ANDROID_NDK_HOME` environment variable to point to your NDK installation 28 | 5. Sync the project with Gradle files 29 | 30 | ## Running the Project Locally 31 | 32 | 1. Open the project in Android Studio 33 | 2. Wait for the Gradle sync to complete 34 | 3. Select a target device (emulator or physical device) 35 | 4. Click `Run` 36 | 37 | ## Building the Library 38 | 39 | To build the library, run the following command from the project root: 40 | 41 | ```bash 42 | ./gradlew :libsql:assembleRelease 43 | ``` 44 | 45 | This will generate the AAR file in the `libsql/build/outputs/aar/` directory. 46 | 47 | 5. Create a new branch for your feature or bug fix: `git switch -c my-new-feature` 48 | 6. Make changes and commit them with a clear commit message 49 | 7. Push your changes to your fork `git push origin my-new-feature` 50 | 8. Open a Pull Request on the main repository 51 | 52 | ## Running Tests 53 | 54 | To run the instrumented tests, use the following command: 55 | 56 | ```bash 57 | ./gradlew :libsql:connectedAndroidTest 58 | ``` 59 | -------------------------------------------------------------------------------- /libsql/src/main/rust/build.rs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022-2024 Smart Vaults 2 | // Distributed under the MIT software license 3 | 4 | use std::env; 5 | use std::path::Path; 6 | 7 | const DEFAULT_CLANG_VERSION: &str = "18"; 8 | 9 | fn main() { 10 | prost_build::Config::new() 11 | .default_package_filename("proto") 12 | .compile_protos(&["../proto/libsql.proto"], &["../proto"]) 13 | .unwrap(); 14 | setup_x86_64_android_workaround(); 15 | } 16 | 17 | /// Adds a temporary workaround for an issue with the Rust compiler and Android 18 | /// in x86_64 devices: https://github.com/rust-lang/rust/issues/109717. 19 | /// The workaround comes from: https://github.com/mozilla/application-services/pull/5442 20 | fn setup_x86_64_android_workaround() { 21 | let target_os = env::var("CARGO_CFG_TARGET_OS").expect("CARGO_CFG_TARGET_OS not set"); 22 | let target_arch = env::var("CARGO_CFG_TARGET_ARCH").expect("CARGO_CFG_TARGET_ARCH not set"); 23 | if target_arch == "x86_64" && target_os == "android" { 24 | let android_ndk_home = env::var("ANDROID_NDK_HOME").expect("ANDROID_NDK_HOME not set"); 25 | let build_os = match env::consts::OS { 26 | "linux" => "linux", 27 | "macos" => "darwin", 28 | "windows" => "windows", 29 | _ => panic!( 30 | "Unsupported OS. You must use either Linux, MacOS or Windows to build the crate." 31 | ), 32 | }; 33 | let clang_version = 34 | env::var("NDK_CLANG_VERSION").unwrap_or_else(|_| DEFAULT_CLANG_VERSION.to_owned()); 35 | let linux_x86_64_lib_dir = format!( 36 | "toolchains/llvm/prebuilt/{build_os}-x86_64/lib/clang/{clang_version}/lib/linux/" 37 | ); 38 | let linkpath = format!("{android_ndk_home}/{linux_x86_64_lib_dir}"); 39 | if Path::new(&linkpath).exists() { 40 | println!("cargo:rustc-link-search={android_ndk_home}/{linux_x86_64_lib_dir}"); 41 | println!("cargo:rustc-link-lib=static=clang_rt.builtins-x86_64-android"); 42 | } else { 43 | panic!("Path {linkpath} not exists"); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /libsql/src/main/kotlin/tech/turso/libsql/Libsql.kt: -------------------------------------------------------------------------------- 1 | package tech.turso.libsql 2 | 3 | import com.google.protobuf.ByteString 4 | import tech.turso.libsql.proto.Value 5 | 6 | fun Any?.toValue(): Value = when (this) { 7 | is Int -> Value.newBuilder().setInteger(this.toLong()).build() 8 | is Long -> Value.newBuilder().setInteger(this).build() 9 | is String -> Value.newBuilder().setText(this).build() 10 | is Float -> Value.newBuilder().setReal(this.toDouble()).build() 11 | is Double -> Value.newBuilder().setReal(this).build() 12 | is ByteArray -> Value.newBuilder().setBlob(ByteString.copyFrom(this)).build() 13 | null -> Value.newBuilder().setNull(Value.Null.newBuilder().build()).build() 14 | else -> { 15 | throw IllegalArgumentException("${this::class.simpleName} not supported") 16 | } 17 | } 18 | 19 | object Libsql { 20 | init { 21 | System.loadLibrary("libsql_android") 22 | } 23 | 24 | @JvmStatic 25 | fun open(path: String): Database { 26 | return Database(nativeOpenLocal(path)) 27 | } 28 | 29 | @JvmStatic 30 | fun open( 31 | url: String, 32 | authToken: String, 33 | ): Database { 34 | return Database(nativeOpenRemote(url, authToken)) 35 | } 36 | 37 | @JvmStatic 38 | fun open( 39 | path: String, 40 | url: String, 41 | authToken: String, 42 | syncInterval: Long = 0, 43 | readYourWrites: Boolean = true, 44 | withWebpki: Boolean = true, 45 | ): EmbeddedReplicaDatabase { 46 | return EmbeddedReplicaDatabase( 47 | nativeOpenEmbeddedReplica( 48 | path, 49 | url, 50 | authToken, 51 | syncInterval, 52 | readYourWrites, 53 | withWebpki 54 | ) 55 | ) 56 | } 57 | 58 | private external fun nativeOpenLocal(path: String): Long 59 | 60 | private external fun nativeOpenRemote( 61 | url: String, 62 | authToken: String, 63 | ): Long 64 | 65 | private external fun nativeOpenEmbeddedReplica( 66 | path: String, 67 | url: String, 68 | authToken: String, 69 | syncInterval: Long, 70 | readYourWrites: Boolean, 71 | withWebpki: Boolean, 72 | ): Long 73 | } 74 | -------------------------------------------------------------------------------- /gradle/libs.versions.toml: -------------------------------------------------------------------------------- 1 | [versions] 2 | agp = "8.4.2" 3 | junit = "4.13.2" 4 | junitVersion = "1.2.1" 5 | protobufGradlePlugin = "0.9.4" 6 | protobufJava = "3.24.0" 7 | protobufJavalite = "3.19.1" 8 | coreKtx = "1.13.1" 9 | kotlin = "2.0.10" 10 | 11 | espressoCore = "3.5.1" 12 | lifecycleRuntimeKtx = "2.6.1" 13 | activityCompose = "1.8.0" 14 | composeBom = "2024.04.01" 15 | appcompat = "1.7.0" 16 | material = "1.12.0" 17 | 18 | [libraries] 19 | androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } 20 | androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" } 21 | androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } 22 | androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" } 23 | androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" } 24 | androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" } 25 | androidx-ui = { group = "androidx.compose.ui", name = "ui" } 26 | androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" } 27 | androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" } 28 | androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" } 29 | androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } 30 | androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" } 31 | androidx-material3 = { group = "androidx.compose.material3", name = "material3" } 32 | material = { group = "com.google.android.material", name = "material", version.ref = "material" } 33 | 34 | junit = { group = "junit", name = "junit", version.ref = "junit" } 35 | ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" } 36 | protobuf-java = { module = "com.google.protobuf:protobuf-java", version.ref = "protobufJava" } 37 | protobuf-javalite = { module = "com.google.protobuf:protobuf-javalite", version.ref = "protobufJavalite" } 38 | rules = { module = "androidx.test:rules", version = "1.6.1" } 39 | runner = { module = "androidx.test:runner", version = "1.6.1" } 40 | core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } 41 | androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" } 42 | 43 | [plugins] 44 | android-library = { id = "com.android.library", version.ref = "agp" } 45 | rust-android = { id = "org.mozilla.rust-android-gradle.rust-android", version = "0.9.4" } 46 | protobuf = { id = "com.google.protobuf", version.ref = "protobufGradlePlugin" } 47 | jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } 48 | android-application = { id = "com.android.application", version.ref = "agp" } 49 | 50 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | 4 | libSQL Android 5 | 6 | 7 |

libSQL Android

8 |

9 | 10 |

11 | Databases for Android multi-tenant AI Apps. 12 |

13 | 14 |

15 | Turso · 16 | Docs · 17 | Quickstart · 18 | SDK Reference · 19 | Blog & Tutorials 20 |

21 | 22 |

23 | 24 | 25 | MIT License 26 | 27 | 28 | 29 | 30 | Discord 31 | 32 | 33 | 34 | 35 | Contributors 36 | 37 | 38 | 39 | 40 | Total downloads 41 | 42 | 43 | 44 | 45 | Examples 46 | 47 | 48 |

49 | 50 | ## Features 51 | 52 | - 🔌 Works offline with [Embedded Replicas](https://docs.turso.tech/features/embedded-replicas/introduction) 53 | - 🌎 Works with remote Turso databases 54 | - ✨ Works with Turso [AI & Vector Search](https://docs.turso.tech/features/ai-and-embeddings) 55 | 56 | > [!WARNING] 57 | > This SDK is currently in technical preview. Join us in Discord to report any issues. 58 | 59 | ## Install 60 | 61 | Add `libsql` to your Gradle dependencies: 62 | 63 | ```kotlin 64 | dependencies { 65 | implementation("tech.turso.libsql:libsql:0.1.0") 66 | } 67 | ``` 68 | 69 | > [!NOTE] 70 | > This will only work with the Android Gradle Plugin for now. 71 | 72 | ## Quickstart 73 | 74 | The example below uses Embedded Replicas and syncs data every 1000ms from Turso. 75 | 76 | ```kotlin 77 | import tech.turso.libsql.Libsql 78 | 79 | val db = Libsql.open( 80 | path = "./local.db", 81 | url = "TURSO_DATABASE_URL",, 82 | authToken = "TURSO_AUTH_TOKEN", 83 | syncInterval: 1000 84 | ) 85 | 86 | val conn = db.connect() 87 | 88 | db.connect().use { 89 | it.execute_batch(" 90 | CREATE TABLE IF NOT EXISTS users ( 91 | id INTEGER PRIMARY KEY AUTOINCREMENT, 92 | name TEXT 93 | ); 94 | 95 | INSERT INTO users (name) VALUES ('Iku'); 96 | ") 97 | } 98 | 99 | db.connect().use { 100 | it.query("SELECT * FROM users WHERE id = ?", 1) 101 | } 102 | ``` 103 | 104 | ## Documentation 105 | 106 | Visit our [official documentation](https://docs.turso.tech/sdk/kotlin). 107 | 108 | ## Support 109 | 110 | Join us [on Discord](https://tur.so/discord-android) to get help using this SDK. Report security issues [via email](mailto:security@turso.tech). 111 | 112 | ## Contributors 113 | 114 | See the [contributing guide](CONTRIBUTING.md) to learn how to get involved. 115 | 116 | ![Contributors](https://contrib.nn.ci/api?repo=tursodatabase/libsql-android) 117 | 118 | 119 | 120 | good first issue 121 | 122 | 123 | -------------------------------------------------------------------------------- /libsql/src/main/kotlin/tech/turso/libsql/ConnectionImpl.kt: -------------------------------------------------------------------------------- 1 | package tech.turso.libsql 2 | 3 | import tech.turso.libsql.proto.NamedParameters 4 | import tech.turso.libsql.proto.Parameters 5 | import tech.turso.libsql.proto.PositionalParameters 6 | 7 | open class ConnectionImpl internal constructor(private var inner: Long) : Connection { 8 | override fun executeBatch(sql: String) { 9 | require(this.inner != 0L) { "Attempted to batch execute with a closed Connection" } 10 | nativeExecuteBatch(this.inner, sql) 11 | } 12 | 13 | override fun execute(sql: String) { 14 | require(this.inner != 0L) { "Attempted to execute with a closed Connection" } 15 | nativeExecute(this.inner, sql, byteArrayOf()) 16 | } 17 | 18 | override fun execute( 19 | sql: String, 20 | params: Map, 21 | ) { 22 | require(this.inner != 0L) { "Attempted to execute with a closed Connection" } 23 | 24 | val params = params.mapValues { it.value.toValue() } 25 | 26 | val buf = 27 | Parameters.newBuilder() 28 | .setNamed(NamedParameters.newBuilder().putAllParameters(params)) 29 | .build() 30 | .toByteArray() 31 | 32 | nativeExecute(this.inner, sql, buf) 33 | } 34 | 35 | override fun execute( 36 | sql: String, 37 | vararg params: Any?, 38 | ) { 39 | require(this.inner != 0L) { "Attempted to execute with a closed Connection" } 40 | 41 | val params = params.asList().map { it.toValue() } 42 | 43 | val buf = 44 | Parameters.newBuilder() 45 | .setPositional( 46 | PositionalParameters.newBuilder() 47 | .addAllParameters(params), 48 | ) 49 | .build() 50 | .toByteArray() 51 | 52 | nativeQuery(this.inner, sql, buf) 53 | } 54 | 55 | override fun query(sql: String): Rows { 56 | require(this.inner != 0L) { "Attempted to query with a closed Connection" } 57 | return Rows(nativeQuery(this.inner, sql, byteArrayOf())) 58 | } 59 | 60 | override fun query( 61 | sql: String, 62 | params: Map, 63 | ): Rows { 64 | require(this.inner != 0L) { "Attempted to query with a closed Connection" } 65 | 66 | val params = params.mapValues { it.value.toValue() } 67 | 68 | val buf = 69 | Parameters.newBuilder() 70 | .setNamed(NamedParameters.newBuilder().putAllParameters(params)) 71 | .build() 72 | .toByteArray() 73 | 74 | return Rows(nativeQuery(this.inner, sql, buf)) 75 | } 76 | 77 | override fun query( 78 | sql: String, 79 | vararg params: Any?, 80 | ): Rows { 81 | require(this.inner != 0L) { "Attempted to query with a closed Connection" } 82 | 83 | val params = params.asList().map { it.toValue() } 84 | 85 | val buf = 86 | Parameters.newBuilder() 87 | .setPositional( 88 | PositionalParameters.newBuilder() 89 | .addAllParameters(params), 90 | ) 91 | .build() 92 | .toByteArray() 93 | 94 | return Rows(nativeQuery(this.inner, sql, buf)) 95 | } 96 | 97 | override fun transaction(): Transaction { 98 | require(this.inner != 0L) { "Database already closed" } 99 | return Transaction(nativeTransaction(this.inner)) 100 | } 101 | 102 | override fun close() { 103 | require(this.inner != 0L) { "Database already closed" } 104 | nativeClose(this.inner) 105 | this.inner = 0L 106 | } 107 | 108 | private external fun nativeExecute( 109 | conn: Long, 110 | sql: String, 111 | buf: ByteArray, 112 | ) 113 | 114 | private external fun nativeExecuteBatch( 115 | conn: Long, 116 | sql: String, 117 | ) 118 | 119 | private external fun nativeQuery( 120 | conn: Long, 121 | sql: String, 122 | buf: ByteArray, 123 | ): Long 124 | 125 | private external fun nativeTransaction(conn: Long): Long 126 | 127 | private external fun nativeClose(conn: Long) 128 | } 129 | -------------------------------------------------------------------------------- /libsql/src/main/kotlin/tech/turso/libsql/Transaction.kt: -------------------------------------------------------------------------------- 1 | package tech.turso.libsql 2 | 3 | import tech.turso.libsql.proto.NamedParameters 4 | import tech.turso.libsql.proto.Parameters 5 | import tech.turso.libsql.proto.PositionalParameters 6 | 7 | class Transaction internal constructor(private var inner: Long) : Connection { 8 | override fun executeBatch(sql: String) { 9 | require(this.inner != 0L) { "Attempted to execute with a closed Connection" } 10 | nativeExecuteBatch(this.inner, sql) 11 | } 12 | 13 | override fun execute(sql: String) { 14 | require(this.inner != 0L) { "Attempted to execute with a closed Transaction" } 15 | nativeExecute(this.inner, sql, byteArrayOf()) 16 | } 17 | 18 | override fun execute( 19 | sql: String, 20 | params: Map, 21 | ) { 22 | require(this.inner != 0L) { "Attempted to execute with a closed Transaction" } 23 | 24 | val params = params.mapValues { it.value.toValue() } 25 | 26 | val buf = 27 | Parameters.newBuilder() 28 | .setNamed(NamedParameters.newBuilder().putAllParameters(params)) 29 | .build() 30 | .toByteArray() 31 | 32 | nativeExecute(this.inner, sql, buf) 33 | } 34 | 35 | override fun execute( 36 | sql: String, 37 | vararg params: Any?, 38 | ) { 39 | require(this.inner != 0L) { "Attempted to execute with a closed Transaction" } 40 | 41 | val params = 42 | params.asList().map { 43 | it.toValue() 44 | } 45 | 46 | val buf = 47 | Parameters.newBuilder() 48 | .setPositional( 49 | PositionalParameters.newBuilder() 50 | .addAllParameters(params), 51 | ) 52 | .build() 53 | .toByteArray() 54 | 55 | nativeQuery(this.inner, sql, buf) 56 | } 57 | 58 | override fun query(sql: String): Rows { 59 | require(this.inner != 0L) { "Attempted to query with a closed Transaction" } 60 | return Rows(nativeQuery(this.inner, sql, byteArrayOf())) 61 | } 62 | 63 | override fun query( 64 | sql: String, 65 | params: Map, 66 | ): Rows { 67 | require(this.inner != 0L) { "Attempted to query with a closed Transaction" } 68 | 69 | val params = params.mapValues { it.value.toValue() } 70 | 71 | val buf = 72 | Parameters.newBuilder() 73 | .setNamed(NamedParameters.newBuilder().putAllParameters(params)) 74 | .build() 75 | .toByteArray() 76 | 77 | return Rows(nativeQuery(this.inner, sql, buf)) 78 | } 79 | 80 | override fun query( 81 | sql: String, 82 | vararg params: Any?, 83 | ): Rows { 84 | require(this.inner != 0L) { "Attempted to query with a closed Transaction" } 85 | 86 | val params = params.asList().map { it.toValue() } 87 | 88 | val buf = 89 | Parameters.newBuilder() 90 | .setPositional( 91 | PositionalParameters.newBuilder() 92 | .addAllParameters(params), 93 | ) 94 | .build() 95 | .toByteArray() 96 | 97 | return Rows(nativeQuery(this.inner, sql, buf)) 98 | } 99 | 100 | override fun transaction(): Transaction { 101 | require(this.inner != 0L) { "Transaction already closed" } 102 | return Transaction(nativeTransaction(this.inner)) 103 | } 104 | 105 | override fun close() { 106 | require(this.inner != 0L) { "Transaction already closed" } 107 | nativeClose(this.inner) 108 | this.inner = 0L 109 | } 110 | 111 | fun commit() { 112 | require(this.inner != 0L) { "Transaction already closed" } 113 | nativeCommit(this.inner) 114 | this.inner = 0L 115 | } 116 | 117 | fun rollback() { 118 | require(this.inner != 0L) { "Transaction already closed" } 119 | nativeRollback(this.inner) 120 | this.inner = 0L 121 | } 122 | 123 | private external fun nativeExecuteBatch( 124 | conn: Long, 125 | sql: String, 126 | ) 127 | 128 | private external fun nativeExecute( 129 | conn: Long, 130 | sql: String, 131 | buf: ByteArray, 132 | ) 133 | 134 | private external fun nativeQuery( 135 | conn: Long, 136 | sql: String, 137 | buf: ByteArray, 138 | ): Long 139 | 140 | private external fun nativeTransaction(conn: Long): Long 141 | 142 | private external fun nativeCommit(conn: Long) 143 | 144 | private external fun nativeRollback(conn: Long) 145 | 146 | private external fun nativeClose(conn: Long) 147 | } 148 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | 86 | # Determine the Java command to use to start the JVM. 87 | if [ -n "$JAVA_HOME" ] ; then 88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 89 | # IBM's JDK on AIX uses strange locations for the executables 90 | JAVACMD="$JAVA_HOME/jre/sh/java" 91 | else 92 | JAVACMD="$JAVA_HOME/bin/java" 93 | fi 94 | if [ ! -x "$JAVACMD" ] ; then 95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 96 | 97 | Please set the JAVA_HOME variable in your environment to match the 98 | location of your Java installation." 99 | fi 100 | else 101 | JAVACMD="java" 102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 103 | 104 | Please set the JAVA_HOME variable in your environment to match the 105 | location of your Java installation." 106 | fi 107 | 108 | # Increase the maximum file descriptors if we can. 109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 110 | MAX_FD_LIMIT=`ulimit -H -n` 111 | if [ $? -eq 0 ] ; then 112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 113 | MAX_FD="$MAX_FD_LIMIT" 114 | fi 115 | ulimit -n $MAX_FD 116 | if [ $? -ne 0 ] ; then 117 | warn "Could not set maximum file descriptor limit: $MAX_FD" 118 | fi 119 | else 120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 121 | fi 122 | fi 123 | 124 | # For Darwin, add options to specify how the application appears in the dock 125 | if $darwin; then 126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 127 | fi 128 | 129 | # For Cygwin or MSYS, switch paths to Windows format before running java 130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 133 | 134 | JAVACMD=`cygpath --unix "$JAVACMD"` 135 | 136 | # We build the pattern for arguments to be converted via cygpath 137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 138 | SEP="" 139 | for dir in $ROOTDIRSRAW ; do 140 | ROOTDIRS="$ROOTDIRS$SEP$dir" 141 | SEP="|" 142 | done 143 | OURCYGPATTERN="(^($ROOTDIRS))" 144 | # Add a user-defined pattern to the cygpath arguments 145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 147 | fi 148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 149 | i=0 150 | for arg in "$@" ; do 151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 153 | 154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 156 | else 157 | eval `echo args$i`="\"$arg\"" 158 | fi 159 | i=`expr $i + 1` 160 | done 161 | case $i in 162 | 0) set -- ;; 163 | 1) set -- "$args0" ;; 164 | 2) set -- "$args0" "$args1" ;; 165 | 3) set -- "$args0" "$args1" "$args2" ;; 166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 172 | esac 173 | fi 174 | 175 | # Escape application args 176 | save () { 177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 178 | echo " " 179 | } 180 | APP_ARGS=`save "$@"` 181 | 182 | # Collect all arguments for the java command, following the shell quoting and substitution rules 183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 184 | 185 | exec "$JAVACMD" "$@" 186 | -------------------------------------------------------------------------------- /libsql/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import cn.lalaki.pub.BaseCentralPortalPlusExtension 2 | import com.google.protobuf.gradle.id 3 | import com.google.protobuf.gradle.proto 4 | 5 | plugins { 6 | alias(libs.plugins.android.library) 7 | alias(libs.plugins.rust.android) 8 | alias(libs.plugins.jetbrains.kotlin.android) 9 | 10 | id("com.google.protobuf") version "0.9.4" 11 | id("com.diffplug.spotless") version "6.25.0" 12 | 13 | id("cn.lalaki.central") version "1.2.8" 14 | id("maven-publish") 15 | signing 16 | } 17 | 18 | apply(plugin = "org.mozilla.rust-android-gradle.rust-android") 19 | 20 | android { 21 | namespace = "tech.turso.libsql" 22 | compileSdk = 34 23 | 24 | sourceSets { 25 | named("main") { 26 | proto { 27 | srcDir("src/main/proto") 28 | } 29 | } 30 | 31 | named("debug") { 32 | java { 33 | srcDir("build/generated/source/proto/debug") 34 | } 35 | } 36 | 37 | named("release") { 38 | java { 39 | srcDir("build/generated/source/proto/release") 40 | } 41 | } 42 | } 43 | 44 | defaultConfig { 45 | minSdk = 21 46 | consumerProguardFiles("consumer-rules.pro") 47 | 48 | // follow AGP 8.4 default: https://developer.android.com/build/releases/gradle-plugin#compatibility 49 | ndkVersion = "26.1.10909125" 50 | 51 | ndk { 52 | abiFilters += listOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64") 53 | } 54 | 55 | testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" 56 | } 57 | 58 | buildTypes { 59 | getByName("release") { 60 | isMinifyEnabled = false 61 | proguardFiles( 62 | getDefaultProguardFile("proguard-android-optimize.txt"), 63 | "proguard-rules.pro", 64 | ) 65 | } 66 | } 67 | 68 | // follow AGP 8.4 default: https://developer.android.com/build/releases/gradle-plugin#compatibility 69 | compileOptions { 70 | sourceCompatibility = JavaVersion.VERSION_17 71 | targetCompatibility = JavaVersion.VERSION_17 72 | } 73 | 74 | kotlinOptions { 75 | jvmTarget = "17" 76 | } 77 | 78 | publishing { 79 | singleVariant("release") { 80 | withSourcesJar() 81 | withJavadocJar() 82 | } 83 | } 84 | } 85 | 86 | dependencies { 87 | implementation(libs.protobuf.java) 88 | implementation(libs.core.ktx) 89 | androidTestImplementation(libs.ext.junit) 90 | androidTestImplementation(libs.junit) 91 | androidTestImplementation(libs.runner) 92 | androidTestImplementation(libs.rules) 93 | } 94 | 95 | cargo { 96 | if (gradle.startParameter.taskNames.any { it.lowercase().contains("release") }) { 97 | profile = "release" 98 | } else { 99 | profile = "debug" 100 | } 101 | module = "./src/main/rust/" 102 | libname = "libsql_android" 103 | targets = listOf("arm", "arm64", "x86", "x86_64") 104 | exec = { spec, _ -> 105 | spec.environment("ANDROID_NDK_HOME", android.ndkDirectory.path) 106 | 107 | // default clang version for NDK 26.1.10909125, NDK 27^ uses 18 108 | spec.environment("NDK_CLANG_VERSION", 17) 109 | } 110 | } 111 | 112 | // taken from https://github.com/firezone/firezone/blob/e856dc5eb2052eff48212b94a6ebf86b2c1e67df/kotlin/android/app/build.gradle.kts#L247-L250 113 | tasks.matching { it.name.matches(Regex("merge.*JniLibFolders")) }.configureEach { 114 | inputs.dir(layout.buildDirectory.file("rustJniLibs/android")) 115 | dependsOn("cargoBuild") 116 | } 117 | 118 | protobuf { 119 | protoc { 120 | artifact = "com.google.protobuf:protoc:3.17.3" 121 | } 122 | generateProtoTasks { 123 | all().forEach { task -> 124 | task.builtins { 125 | id("java") { 126 | java { } 127 | } 128 | } 129 | } 130 | } 131 | } 132 | 133 | spotless { 134 | java { 135 | target("src/*/java/**/*.java") 136 | importOrder() 137 | cleanthat() 138 | googleJavaFormat().aosp() 139 | formatAnnotations() 140 | } 141 | kotlin { 142 | target("src/*/kotlin/**/*.kt") 143 | ktlint() 144 | } 145 | kotlinGradle { 146 | target("*.gradle.kts") // default target for kotlinGradle 147 | ktlint() 148 | } 149 | } 150 | 151 | var local = uri(layout.buildDirectory.dir("staging-deploy")) 152 | publishing { 153 | publications { 154 | create("release") { 155 | groupId = "tech.turso.libsql" 156 | artifactId = "libsql" 157 | version = "0.1.1" 158 | 159 | afterEvaluate { 160 | from(components.getByName("release")) 161 | } 162 | 163 | pom { 164 | name = artifactId 165 | description = "Java bindings for libSQL" 166 | 167 | url = "https://github.com/tursodatabase/libsql-android" 168 | 169 | licenses { 170 | license { 171 | name = "The MIT License" 172 | url = "https://opensource.org/license/MIT" 173 | } 174 | } 175 | 176 | developers { 177 | developer { 178 | id = "haaawk" 179 | name = "Piotr Jastrzebski" 180 | email = "piotr@turso.tech" 181 | } 182 | 183 | developer { 184 | id = "levydsa" 185 | name = "Levy Albuquerque" 186 | email = "levy@turso.tech" 187 | } 188 | } 189 | 190 | scm { 191 | connection = "scm:git:git://github.com/tursodatabase/libsql_android.git" 192 | developerConnection = "scm:git:ssh://github.com:tursodatabase/libsql_android.git" 193 | url = "https://github.com/tursodatabase/libsql_android" 194 | } 195 | } 196 | } 197 | } 198 | 199 | repositories { 200 | maven { 201 | name = "stagingDeploy" 202 | url = local 203 | } 204 | } 205 | } 206 | 207 | signing { 208 | useGpgCmd() 209 | sign(publishing.publications.getByName("release")) 210 | } 211 | 212 | tasks.withType().configureEach { 213 | dependsOn(tasks.withType()) 214 | } 215 | 216 | val sonatypeUsername: String by project 217 | val sonatypePassword: String by project 218 | 219 | centralPortalPlus { 220 | url = local 221 | username = sonatypeUsername 222 | password = sonatypePassword 223 | publishingType = BaseCentralPortalPlusExtension.PublishingType.AUTOMATIC 224 | } -------------------------------------------------------------------------------- /libsql/src/androidTest/java/tech/turso/libsql/LibsqlTest.java: -------------------------------------------------------------------------------- 1 | package tech.turso.libsql; 2 | 3 | import static org.junit.Assert.assertArrayEquals; 4 | import static org.junit.Assert.assertEquals; 5 | import static org.junit.Assert.assertNotNull; 6 | import static org.junit.Assert.fail; 7 | 8 | import androidx.test.ext.junit.runners.AndroidJUnit4; 9 | 10 | import java.util.List; 11 | import java.util.Map; 12 | import org.junit.Test; 13 | import org.junit.runner.RunWith; 14 | 15 | @RunWith(AndroidJUnit4.class) 16 | public class LibsqlTest { 17 | @Test 18 | public void failCloseTwoTimes() { 19 | try { 20 | var db = Libsql.open(":memory:"); 21 | db.close(); 22 | db.close(); 23 | fail("Successfully closed the same Database two times"); 24 | } catch (Throwable e) { 25 | assertNotNull(e); 26 | } 27 | } 28 | 29 | @Test 30 | public void failNestedTransaction() { 31 | try { 32 | try (var db = Libsql.open(":memory:"); 33 | var conn = db.connect()) { 34 | var tx1 = conn.transaction(); 35 | var tx2 = tx1.transaction(); 36 | } 37 | fail("Successfully made a nested transaction"); 38 | } catch (Throwable e) { 39 | assertNotNull(e); 40 | } 41 | } 42 | 43 | @Test 44 | public void queryEmptyParameters() { 45 | try (var db = Libsql.open(":memory:"); 46 | var conn = db.connect()) { 47 | conn.query("select 1"); 48 | } 49 | } 50 | 51 | @Test 52 | public void queryNamedParameters() { 53 | try (var db = Libsql.open(":memory:"); 54 | var conn = db.connect()) { 55 | conn.query("select :a", Map.of("a", 1)); 56 | } 57 | } 58 | 59 | @Test 60 | public void queryRows() { 61 | try (var db = Libsql.open(":memory:"); 62 | var conn = db.connect()) { 63 | try (var rows = conn.query("select 1", Map.of("a", 1))) { 64 | assertEquals(1L, rows.next().get(0)); 65 | } 66 | } 67 | } 68 | 69 | @Test 70 | public void queryMultiple() { 71 | try (var db = Libsql.open(":memory:"); 72 | var conn = db.connect()) { 73 | 74 | var end = 255; 75 | 76 | conn.execute("create table test (i integer, t text, r real, b blob)"); 77 | 78 | for (int i = 0; i < 255; i++) { 79 | conn.execute( 80 | "insert into test values (?, ?, ?, ?)", 81 | i, "" + i, Math.exp(i), new byte[]{ (byte) i } 82 | ); 83 | } 84 | 85 | try (var rows = conn.query("select * from test")) { 86 | var i = 0; 87 | for (var row : rows) { 88 | assertEquals((long) i, row.get(0)); 89 | assertEquals("" + i, row.get(1)); 90 | assertEquals(Math.exp(i), row.get(2)); 91 | assertArrayEquals(new byte[]{ (byte) i }, (byte[]) row.get(3)); 92 | i++; 93 | } 94 | } 95 | } 96 | } 97 | 98 | @Test 99 | public void queryPositionalParameters() { 100 | try (var db = Libsql.open(":memory:"); 101 | var conn = db.connect()) { 102 | conn.query("select ?", 1); 103 | } 104 | } 105 | 106 | @Test 107 | public void executeEmptyParameters() { 108 | try (var db = Libsql.open(":memory:"); 109 | var conn = db.connect()) { 110 | conn.execute("create table test(i integer)"); 111 | } 112 | } 113 | 114 | @Test 115 | public void executeNamedParameters() { 116 | try (var db = Libsql.open(":memory:"); 117 | var conn = db.connect()) { 118 | conn.execute("create table test(i integer)"); 119 | conn.execute("insert into test values(:a)", Map.of("a", 1)); 120 | } 121 | } 122 | 123 | @Test 124 | public void executeBatch() { 125 | try (var db = Libsql.open(":memory:"); 126 | var conn = db.connect()) { 127 | conn.executeBatch( 128 | "create table test(i integer);" 129 | + "insert into test values(1);" 130 | + "insert into test values(2);" 131 | + "insert into test values(3);"); 132 | } 133 | } 134 | 135 | @Test 136 | public void executeBatchList() { 137 | try (var db = Libsql.open(":memory:"); 138 | var conn = db.connect()) { 139 | conn.executeBatch( 140 | List.of( 141 | "create table test(i integer)", 142 | "insert into test values(1)", 143 | "insert into test values(2)", 144 | "insert into test values(3)")); 145 | } 146 | } 147 | 148 | @Test 149 | public void executePositionalParameters() { 150 | try (var db = Libsql.open(":memory:"); 151 | var conn = db.connect()) { 152 | conn.execute("create table test(i integer)"); 153 | conn.execute("insert into test values(?)", 1); 154 | } 155 | } 156 | 157 | @Test 158 | public void transactionQueryEmptyParameters() { 159 | try (var db = Libsql.open(":memory:"); 160 | var conn = db.connect()) { 161 | var tx = conn.transaction(); 162 | tx.query("select 1"); 163 | tx.commit(); 164 | } 165 | } 166 | 167 | @Test 168 | public void transactionQueryNamedParameters() { 169 | try (var db = Libsql.open(":memory:"); 170 | var conn = db.connect(); ) { 171 | var tx = conn.transaction(); 172 | tx.query("select :a", Map.of("a", 1)); 173 | tx.commit(); 174 | } 175 | } 176 | 177 | @Test 178 | public void transactionQueryRows() { 179 | try (var db = Libsql.open(":memory:"); 180 | var conn = db.connect()) { 181 | var tx = conn.transaction(); 182 | try (var rows = tx.query("select 1", Map.of("a", 1))) { 183 | assertEquals(1L, rows.next().get(0)); 184 | } 185 | tx.commit(); 186 | } 187 | } 188 | 189 | @Test 190 | public void transactionQueryPositionalParameters() { 191 | try (var db = Libsql.open(":memory:"); 192 | var conn = db.connect()) { 193 | var tx = conn.transaction(); 194 | conn.query("select ?", 1); 195 | tx.commit(); 196 | } 197 | } 198 | 199 | @Test 200 | public void transactionExecuteEmptyParameters() { 201 | try (var db = Libsql.open(":memory:"); 202 | var conn = db.connect()) { 203 | var tx = conn.transaction(); 204 | tx.execute("create table test(i integer)"); 205 | tx.commit(); 206 | } 207 | } 208 | 209 | @Test 210 | public void transactionExecuteNamedParameters() { 211 | try (var db = Libsql.open(":memory:"); 212 | var conn = db.connect()) { 213 | var tx = conn.transaction(); 214 | tx.execute("create table test(i integer)"); 215 | tx.execute("insert into test values(:a)", Map.of("a", 1)); 216 | tx.commit(); 217 | } 218 | } 219 | 220 | @Test 221 | public void transactionExecutePositionalParameters() { 222 | try (var db = Libsql.open(":memory:"); 223 | var conn = db.connect()) { 224 | var tx = conn.transaction(); 225 | tx.execute("create table test(i integer)"); 226 | tx.execute("insert into test values(?)", 1); 227 | tx.commit(); 228 | } 229 | } 230 | } 231 | -------------------------------------------------------------------------------- /examples/todo/src/main/kotlin/tech/turso/libsql/examples/todo/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package tech.turso.libsql.examples.todo 2 | 3 | import android.os.Bundle 4 | import android.util.Log 5 | import androidx.activity.ComponentActivity 6 | import androidx.activity.compose.setContent 7 | import androidx.activity.enableEdgeToEdge 8 | import androidx.compose.animation.core.animateFloatAsState 9 | import androidx.compose.animation.core.spring 10 | import androidx.compose.foundation.background 11 | import androidx.compose.foundation.border 12 | import androidx.compose.foundation.gestures.Orientation 13 | import androidx.compose.foundation.gestures.draggable 14 | import androidx.compose.foundation.gestures.rememberDraggableState 15 | import androidx.compose.foundation.layout.Box 16 | import androidx.compose.foundation.layout.Column 17 | import androidx.compose.foundation.layout.Row 18 | import androidx.compose.foundation.layout.Spacer 19 | import androidx.compose.foundation.layout.aspectRatio 20 | import androidx.compose.foundation.layout.fillMaxSize 21 | import androidx.compose.foundation.layout.offset 22 | import androidx.compose.foundation.layout.padding 23 | import androidx.compose.foundation.layout.size 24 | import androidx.compose.foundation.lazy.LazyColumn 25 | import androidx.compose.foundation.lazy.items 26 | import androidx.compose.foundation.shape.RoundedCornerShape 27 | import androidx.compose.material.icons.Icons 28 | import androidx.compose.material.icons.filled.Add 29 | import androidx.compose.material.icons.filled.CheckCircle 30 | import androidx.compose.material3.Icon 31 | import androidx.compose.material3.IconButton 32 | import androidx.compose.material3.IconButtonColors 33 | import androidx.compose.material3.MaterialTheme 34 | import androidx.compose.material3.Text 35 | import androidx.compose.material3.TextField 36 | import androidx.compose.runtime.Composable 37 | import androidx.compose.runtime.DisposableEffect 38 | import androidx.compose.runtime.getValue 39 | import androidx.compose.runtime.mutableFloatStateOf 40 | import androidx.compose.runtime.mutableStateOf 41 | import androidx.compose.runtime.remember 42 | import androidx.compose.runtime.rememberCoroutineScope 43 | import androidx.compose.runtime.setValue 44 | import androidx.compose.ui.Alignment 45 | import androidx.compose.ui.Modifier 46 | import androidx.compose.ui.draw.clip 47 | import androidx.compose.ui.graphics.Brush 48 | import androidx.compose.ui.graphics.Color 49 | import androidx.compose.ui.text.style.TextDecoration 50 | import androidx.compose.ui.unit.IntOffset 51 | import androidx.compose.ui.unit.dp 52 | import kotlinx.coroutines.Dispatchers 53 | import kotlinx.coroutines.delay 54 | import kotlinx.coroutines.launch 55 | import tech.turso.libsql.Database 56 | import tech.turso.libsql.EmbeddedReplicaDatabase 57 | import tech.turso.libsql.Libsql 58 | import tech.turso.libsql.examples.todo.ui.theme.TodoTheme 59 | import java.util.UUID 60 | import kotlin.concurrent.fixedRateTimer 61 | 62 | data class Item( 63 | val id: UUID = UUID.randomUUID(), var title: String, var isCompleted: Boolean = false 64 | ) 65 | 66 | class MainActivity : ComponentActivity() { 67 | private val db: Database by lazy { Libsql.open(this.filesDir.path + "/todo.db") } 68 | 69 | override fun onCreate(savedInstanceState: Bundle?) { 70 | super.onCreate(savedInstanceState) 71 | 72 | actionBar?.hide() 73 | 74 | val db = this.db 75 | db.connect().use { 76 | it.execute("create table if not exists todos(id text, title text, is_completed integer)") 77 | } 78 | 79 | enableEdgeToEdge() 80 | setContent { 81 | val padding = 24.dp 82 | var text by remember { mutableStateOf("") } 83 | var todos by remember { mutableStateOf(getAllTodos(db)) } 84 | 85 | val coroutineScope = rememberCoroutineScope() 86 | 87 | DisposableEffect(Unit) { 88 | val timer = fixedRateTimer(initialDelay = 0, period = 1000) { 89 | coroutineScope.launch(Dispatchers.Main) { 90 | Log.i("EmbeddedReplica", "Syncing!") 91 | if (db is EmbeddedReplicaDatabase) db.sync() 92 | todos = getAllTodos(db) 93 | } 94 | } 95 | 96 | onDispose { timer.cancel() } 97 | } 98 | 99 | TodoTheme { 100 | Box( 101 | Modifier.background( 102 | Brush.verticalGradient( 103 | listOf(Color(0xff15262b), Color(0xff2e5857)) 104 | ) 105 | ) 106 | ) { 107 | Column( 108 | modifier = Modifier.fillMaxSize() 109 | .padding(horizontal = padding, vertical = padding * Math.E.toFloat()), 110 | ) { 111 | Row(verticalAlignment = Alignment.CenterVertically) { 112 | TextField( 113 | singleLine = true, 114 | value = text, 115 | onValueChange = { text = it }, 116 | shape = RoundedCornerShape(10.dp), 117 | modifier = Modifier.weight(1f).clip(RoundedCornerShape(10.dp)), 118 | ) 119 | Spacer(modifier = Modifier.padding(10.dp)) 120 | IconButton(colors = IconButtonColors( 121 | containerColor = MaterialTheme.colorScheme.primaryContainer, 122 | contentColor = MaterialTheme.colorScheme.onPrimaryContainer, 123 | disabledContentColor = Color.Unspecified, 124 | disabledContainerColor = Color.Unspecified 125 | ), modifier = Modifier.size(42.dp).aspectRatio(1f), onClick = { 126 | if (text.isNotEmpty()) { 127 | val item = Item(title = text) 128 | db.connect().use { 129 | it.execute( 130 | "insert into todos values (?, ?, ?)", 131 | item.id.toString(), 132 | item.title, 133 | if (item.isCompleted) 1 else 0, 134 | ) 135 | } 136 | todos = buildList { 137 | addAll(todos) 138 | add(item) 139 | } 140 | text = "" 141 | } 142 | }) { 143 | Icon(Icons.Default.Add, contentDescription = null) 144 | } 145 | } 146 | Spacer(Modifier.size(padding)) 147 | LazyColumn { 148 | items(todos, key = { it.id }) { item -> 149 | TodoItem( 150 | item, 151 | onCheck = { checkedItem -> 152 | todos = todos.map { 153 | if (checkedItem.id == it.id) it.copy(isCompleted = !it.isCompleted) else it 154 | } 155 | 156 | coroutineScope.launch { 157 | db.connect().use { conn -> 158 | conn.execute( 159 | "update todos set is_completed = ? where id = ?", 160 | if (item.isCompleted) 0 else 1, 161 | item.id.toString(), 162 | ) 163 | } 164 | } 165 | }, 166 | onDelete = { deletedItem -> 167 | todos = todos.filterNot { deletedItem.id == it.id } 168 | 169 | coroutineScope.launch { 170 | db.connect().use { 171 | it.execute( 172 | "delete from todos where id = ?", 173 | item.id.toString(), 174 | ) 175 | } 176 | } 177 | }, 178 | ) 179 | Spacer(modifier = Modifier.padding(6.dp)) 180 | } 181 | } 182 | } 183 | } 184 | } 185 | } 186 | } 187 | 188 | override fun onDestroy() { 189 | super.onDestroy() 190 | db.close() 191 | } 192 | } 193 | 194 | @Composable 195 | fun TodoItem( 196 | item: Item, onCheck: (Item) -> Unit, onDelete: (Item) -> Unit 197 | ) { 198 | var offsetX by remember { mutableFloatStateOf(0f) } 199 | val animatedOffsetX by animateFloatAsState( 200 | targetValue = offsetX, 201 | animationSpec = spring(), 202 | ) 203 | 204 | Box(modifier = Modifier.offset { IntOffset(animatedOffsetX.toInt(), 0) }.border( 205 | width = 2.dp, 206 | color = MaterialTheme.colorScheme.onPrimaryContainer, 207 | shape = RoundedCornerShape(10.dp), 208 | )) { 209 | Row( 210 | modifier = Modifier.padding( 211 | horizontal = 12.dp, 212 | vertical = 14.dp, 213 | ).draggable(orientation = Orientation.Horizontal, 214 | state = rememberDraggableState { delta -> 215 | if (offsetX + delta < 0) { 216 | offsetX += delta 217 | } 218 | }, 219 | onDragStopped = { 220 | if (offsetX < -200) { 221 | offsetX = -1200f 222 | delay(300) 223 | onDelete(item) 224 | } else { 225 | offsetX = 0f 226 | } 227 | }), 228 | ) { 229 | Text( 230 | text = item.title, 231 | color = MaterialTheme.colorScheme.onBackground, 232 | modifier = Modifier.weight(10f), 233 | textDecoration = if (item.isCompleted) TextDecoration.LineThrough else null 234 | ) 235 | Spacer(Modifier.padding(2.dp)) 236 | if (item.isCompleted) { 237 | IconButton(colors = IconButtonColors( 238 | containerColor = MaterialTheme.colorScheme.primaryContainer, 239 | contentColor = MaterialTheme.colorScheme.onPrimaryContainer, 240 | disabledContentColor = Color.Unspecified, 241 | disabledContainerColor = Color.Unspecified 242 | ), 243 | modifier = Modifier.size(20.dp).aspectRatio(1f), 244 | onClick = { onCheck(item) }) { 245 | Icon( 246 | Icons.Default.CheckCircle, 247 | contentDescription = null, 248 | modifier = Modifier.weight(1f), 249 | ) 250 | } 251 | } else { 252 | IconButton(colors = IconButtonColors( 253 | containerColor = MaterialTheme.colorScheme.primaryContainer, 254 | contentColor = MaterialTheme.colorScheme.onPrimaryContainer, 255 | disabledContentColor = Color.Unspecified, 256 | disabledContainerColor = Color.Unspecified, 257 | ), 258 | modifier = Modifier.size(20.dp).aspectRatio(1f), 259 | onClick = { onCheck(item) }) {} 260 | } 261 | } 262 | } 263 | } 264 | 265 | fun getAllTodos(db: Database): List = db.connect().use { 266 | it.query("select * from todos").use { rows -> 267 | rows.map { row -> 268 | Item( 269 | id = UUID.fromString(row[0] as String), 270 | title = row[1] as String, 271 | isCompleted = row[2] as Long == 1L, 272 | ) 273 | } 274 | } 275 | } 276 | -------------------------------------------------------------------------------- /libsql/src/main/rust/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![allow(non_snake_case)] 2 | 3 | use jni::{ 4 | objects::{JByteArray, JClass, JString}, 5 | sys::{jboolean, jbyteArray, jlong}, 6 | JNIEnv, 7 | }; 8 | use jni_fn::jni_fn; 9 | use libsql::{Builder, Connection, Database, Rows, Transaction}; 10 | use std::{mem::ManuallyDrop, ptr, time::Duration}; 11 | 12 | use lazy_static::lazy_static; 13 | use prost::Message; 14 | use tokio::runtime::Runtime; 15 | 16 | pub mod proto { 17 | include!(concat!(env!("OUT_DIR"), "/proto.rs")); 18 | } 19 | 20 | impl From for libsql::Value { 21 | fn from(value: proto::Value) -> Self { 22 | use proto::value::Value as V; 23 | 24 | match value.value { 25 | Some(V::Integer(i)) => libsql::Value::Integer(i), 26 | Some(V::Real(r)) => libsql::Value::Real(r), 27 | Some(V::Text(s)) => libsql::Value::Text(s), 28 | Some(V::Blob(b)) => libsql::Value::Blob(b), 29 | Some(V::Null(_)) => libsql::Value::Null, 30 | None => libsql::Value::Null, 31 | } 32 | } 33 | } 34 | 35 | impl From for proto::Value { 36 | fn from(value: libsql::Value) -> Self { 37 | use proto::value::Value as V; 38 | 39 | match value { 40 | libsql::Value::Integer(i) => proto::Value { 41 | value: Some(V::Integer(i)), 42 | }, 43 | libsql::Value::Real(r) => proto::Value { 44 | value: Some(V::Real(r)), 45 | }, 46 | libsql::Value::Text(s) => proto::Value { 47 | value: Some(V::Text(s)), 48 | }, 49 | libsql::Value::Blob(b) => proto::Value { 50 | value: Some(V::Blob(b)), 51 | }, 52 | libsql::Value::Null => proto::Value { 53 | value: Some(V::Null(proto::value::Null {})), 54 | }, 55 | } 56 | } 57 | } 58 | 59 | lazy_static! { 60 | static ref RT: Runtime = Runtime::new().unwrap(); 61 | } 62 | 63 | fn execute(conn: &Connection, sql: impl AsRef, buf: impl AsRef<[u8]>) -> anyhow::Result { 64 | let proto::Parameters { parameters } = proto::Parameters::decode(buf.as_ref())?; 65 | 66 | use proto::{parameters::Parameters, NamedParameters, PositionalParameters}; 67 | 68 | Ok(match parameters { 69 | Some(Parameters::Named(NamedParameters { parameters })) => { 70 | let parameters: Vec<(String, libsql::Value)> = 71 | parameters.into_iter().map(|(k, v)| (k, v.into())).collect(); 72 | 73 | RT.block_on(conn.execute(sql.as_ref(), parameters))? 74 | } 75 | Some(Parameters::Positional(PositionalParameters { parameters })) => { 76 | let parameters: Vec = parameters.into_iter().map(|v| v.into()).collect(); 77 | 78 | RT.block_on(conn.execute(sql.as_ref(), parameters))? 79 | } 80 | None => RT.block_on(conn.execute(sql.as_ref(), ()))?, 81 | }) 82 | } 83 | 84 | fn query(conn: &Connection, sql: impl AsRef, buf: impl AsRef<[u8]>) -> anyhow::Result { 85 | let proto::Parameters { parameters } = proto::Parameters::decode(buf.as_ref())?; 86 | 87 | use proto::{parameters::Parameters, NamedParameters, PositionalParameters}; 88 | 89 | Ok(match parameters { 90 | Some(Parameters::Named(NamedParameters { parameters })) => { 91 | let parameters: Vec<(String, libsql::Value)> = 92 | parameters.into_iter().map(|(k, v)| (k, v.into())).collect(); 93 | 94 | RT.block_on(conn.query(sql.as_ref(), parameters))? 95 | } 96 | Some(Parameters::Positional(PositionalParameters { parameters })) => { 97 | let parameters: Vec = parameters.into_iter().map(|v| v.into()).collect(); 98 | 99 | RT.block_on(conn.query(sql.as_ref(), parameters))? 100 | } 101 | None => RT.block_on(conn.query(sql.as_ref(), ()))?, 102 | }) 103 | } 104 | 105 | #[jni_fn("tech.turso.libsql.Libsql")] 106 | pub fn nativeOpenLocal(mut env: JNIEnv, _: JClass, path: JString) -> jlong { 107 | match (|| -> anyhow::Result { 108 | let path = env.get_string(&path)?; 109 | Ok(RT.block_on(Builder::new_local(&*path.to_string_lossy()).build())?) 110 | })() { 111 | Ok(db) => Box::into_raw(Box::new(db)) as jlong, 112 | Err(err) => { 113 | env.throw(err.to_string()).unwrap(); 114 | ptr::null_mut::() as jlong 115 | } 116 | } 117 | } 118 | 119 | #[jni_fn("tech.turso.libsql.Libsql")] 120 | pub fn nativeOpenRemote(mut env: JNIEnv, _: JClass, url: JString, auth_token: JString) -> jlong { 121 | match (|| -> anyhow::Result { 122 | let url = env.get_string(&url)?; 123 | let auth_token = env.get_string(&auth_token)?; 124 | 125 | let connector = hyper_rustls::HttpsConnectorBuilder::new() 126 | .with_webpki_roots() 127 | .https_or_http() 128 | .enable_http1() 129 | .build(); 130 | 131 | Ok(RT.block_on( 132 | Builder::new_remote(url.into(), auth_token.into()) 133 | .connector(connector) 134 | .build(), 135 | )?) 136 | })() { 137 | Ok(db) => Box::into_raw(Box::new(db)) as jlong, 138 | Err(err) => { 139 | env.throw(err.to_string()).unwrap(); 140 | ptr::null_mut::() as jlong 141 | } 142 | } 143 | } 144 | 145 | #[jni_fn("tech.turso.libsql.Libsql")] 146 | pub fn nativeOpenEmbeddedReplica( 147 | mut env: JNIEnv, 148 | _: JClass, 149 | path: JString, 150 | url: JString, 151 | auth_token: JString, 152 | sync_interval: jlong, 153 | read_your_writes: jboolean, 154 | with_webpki: jboolean, 155 | ) -> jlong { 156 | match (|| -> anyhow::Result { 157 | let path = env.get_string(&path)?; 158 | let url = env.get_string(&url)?; 159 | let auth_token = env.get_string(&auth_token)?; 160 | 161 | let db = 162 | Builder::new_remote_replica(&*path.to_string_lossy(), url.into(), auth_token.into()) 163 | .read_your_writes(read_your_writes != 0); 164 | 165 | let db = if with_webpki != 0 { 166 | let connector = hyper_rustls::HttpsConnectorBuilder::new() 167 | .with_webpki_roots() 168 | .https_or_http() 169 | .enable_http1() 170 | .build(); 171 | db.connector(connector) 172 | } else { 173 | db 174 | }; 175 | 176 | let db = if sync_interval != 0 { 177 | db.sync_interval(Duration::from_millis(sync_interval.try_into()?)) 178 | } else { 179 | db 180 | }; 181 | 182 | let db = RT.block_on(db.build()); 183 | 184 | Ok(db?) 185 | })() { 186 | Ok(db) => Box::into_raw(Box::new(db)) as jlong, 187 | Err(err) => { 188 | env.throw(err.to_string()).unwrap(); 189 | ptr::null_mut::() as jlong 190 | } 191 | } 192 | } 193 | 194 | #[jni_fn("tech.turso.libsql.Database")] 195 | pub fn nativeConnect(mut env: JNIEnv, _: JClass, db: jlong) -> jlong { 196 | let db = ManuallyDrop::new(unsafe { Box::from_raw(db as *mut Database) }); 197 | match db.connect() { 198 | Ok(conn) => Box::into_raw(Box::new(conn)) as jlong, 199 | Err(err) => { 200 | env.throw(err.to_string()).unwrap(); 201 | ptr::null_mut::() as jlong 202 | } 203 | } 204 | } 205 | 206 | #[jni_fn("tech.turso.libsql.Database")] 207 | pub fn nativeClose(_: JNIEnv, _: JClass, db: jlong) { 208 | drop(unsafe { Box::from_raw(db as *mut Database) }); 209 | } 210 | 211 | #[jni_fn("tech.turso.libsql.EmbeddedReplicaDatabase")] 212 | pub fn nativeSync(mut env: JNIEnv, _: JClass, db: jlong) { 213 | let db = ManuallyDrop::new(unsafe { Box::from_raw(db as *mut Database) }); 214 | match RT.block_on(db.sync()) { 215 | Ok(_) => (), 216 | Err(err) => env.throw(err.to_string()).unwrap(), 217 | } 218 | } 219 | 220 | #[jni_fn("tech.turso.libsql.ConnectionImpl")] 221 | pub fn nativeExecute(mut env: JNIEnv, _: JClass, conn: jlong, sql: JString, buf: JByteArray) { 222 | match (|| -> anyhow::Result { 223 | let conn = ManuallyDrop::new(unsafe { Box::from_raw(conn as *mut Connection) }); 224 | let sql = env.get_string(&sql)?; 225 | let buf = env.convert_byte_array(buf)?; 226 | Ok(execute(&conn, &sql.to_string_lossy(), buf)?) 227 | })() { 228 | Ok(_) => (), 229 | Err(err) => env.throw(err.to_string()).unwrap(), 230 | } 231 | } 232 | 233 | #[jni_fn("tech.turso.libsql.ConnectionImpl")] 234 | pub fn nativeExecuteBatch(mut env: JNIEnv, _: JClass, tx: jlong, sql: JString) { 235 | // TODO: Support BatchRows 236 | match (|| -> anyhow::Result<_> { 237 | let tx = ManuallyDrop::new(unsafe { Box::from_raw(tx as *mut Connection) }); 238 | let sql = env.get_string(&sql)?; 239 | Ok(RT.block_on(tx.execute_batch(&sql.to_string_lossy()))?) 240 | })() { 241 | Ok(_) => (), 242 | Err(err) => env.throw(err.to_string()).unwrap(), 243 | } 244 | } 245 | 246 | #[jni_fn("tech.turso.libsql.ConnectionImpl")] 247 | pub fn nativeQuery( 248 | mut env: JNIEnv, 249 | _: JClass, 250 | conn: jlong, 251 | sql: JString, 252 | buf: JByteArray, 253 | ) -> jlong { 254 | match (|| -> anyhow::Result { 255 | let conn = ManuallyDrop::new(unsafe { Box::from_raw(conn as *mut Connection) }); 256 | let sql = env.get_string(&sql)?; 257 | let buf = env.convert_byte_array(buf)?; 258 | Ok(query(&conn, &sql.to_string_lossy(), buf)?) 259 | })() { 260 | Ok(row) => Box::into_raw(Box::new(row)) as jlong, 261 | Err(err) => { 262 | env.throw(err.to_string()).unwrap(); 263 | return ptr::null_mut::() as jlong; 264 | } 265 | } 266 | } 267 | 268 | #[jni_fn("tech.turso.libsql.ConnectionImpl")] 269 | pub fn nativeTransaction(mut env: JNIEnv, _: JClass, conn: jlong) -> jlong { 270 | let conn = ManuallyDrop::new(unsafe { Box::from_raw(conn as *mut Connection) }); 271 | 272 | match RT.block_on(conn.transaction()) { 273 | Ok(t) => Box::into_raw(Box::new(t)) as jlong, 274 | Err(err) => { 275 | env.throw(err.to_string()).unwrap(); 276 | return ptr::null_mut::() as jlong; 277 | } 278 | } 279 | } 280 | 281 | #[jni_fn("tech.turso.libsql.ConnectionImpl")] 282 | pub fn nativeClose(_: JNIEnv, _: JClass, conn: jlong) { 283 | drop(unsafe { Box::from_raw(conn as *mut Connection) }); 284 | } 285 | 286 | #[jni_fn("tech.turso.libsql.Rows")] 287 | pub fn nativeNext(mut env: JNIEnv, _: JClass, rows: jlong) -> jbyteArray { 288 | match (|| -> anyhow::Result { 289 | let mut rows = ManuallyDrop::new(unsafe { Box::from_raw(rows as *mut Rows) }); 290 | let mut values = Vec::::new(); 291 | 292 | if let Some(row) = RT.block_on(rows.next())? { 293 | for i in 0..rows.column_count() { 294 | let value = row.get_value(i)?; 295 | values.push(value.into()); 296 | } 297 | } 298 | 299 | Ok(env.byte_array_from_slice(proto::Row { values }.encode_to_vec().as_slice())?) 300 | })() { 301 | Ok(byte_array) => byte_array.into_raw(), 302 | Err(err) => { 303 | env.throw(err.to_string()).unwrap(); 304 | return JByteArray::default().into_raw(); 305 | } 306 | } 307 | } 308 | 309 | #[jni_fn("tech.turso.libsql.Rows")] 310 | pub fn nativeClose(_: JNIEnv, _: JClass, rows: jlong) { 311 | drop(unsafe { Box::from_raw(rows as *mut Rows) }); 312 | } 313 | 314 | #[jni_fn("tech.turso.libsql.Transaction")] 315 | pub fn nativeExecute(mut env: JNIEnv, _: JClass, tx: jlong, sql: JString, buf: JByteArray) { 316 | match (|| -> anyhow::Result { 317 | let tx = ManuallyDrop::new(unsafe { Box::from_raw(tx as *mut Transaction) }); 318 | let sql = env.get_string(&sql)?; 319 | let buf = env.convert_byte_array(buf)?; 320 | Ok(execute(&tx, &sql.to_string_lossy(), buf)?) 321 | })() { 322 | Ok(_) => (), 323 | Err(err) => env.throw(err.to_string()).unwrap(), 324 | } 325 | } 326 | 327 | #[jni_fn("tech.turso.libsql.Transaction")] 328 | pub fn nativeExecuteBatch(mut env: JNIEnv, _: JClass, tx: jlong, sql: JString) { 329 | // TODO: Support BatchRows 330 | match (|| -> anyhow::Result<_> { 331 | let tx = ManuallyDrop::new(unsafe { Box::from_raw(tx as *mut Transaction) }); 332 | let sql = env.get_string(&sql)?; 333 | Ok(RT.block_on(tx.execute_batch(&sql.to_string_lossy()))?) 334 | })() { 335 | Ok(_) => (), 336 | Err(err) => env.throw(err.to_string()).unwrap(), 337 | } 338 | } 339 | 340 | #[jni_fn("tech.turso.libsql.Transaction")] 341 | pub fn nativeQuery(mut env: JNIEnv, _: JClass, tx: jlong, sql: JString, buf: JByteArray) -> jlong { 342 | match (|| -> anyhow::Result { 343 | let tx = ManuallyDrop::new(unsafe { Box::from_raw(tx as *mut Transaction) }); 344 | let sql = env.get_string(&sql)?; 345 | let buf = env.convert_byte_array(buf)?; 346 | Ok(query(&tx, &sql.to_string_lossy(), buf)?) 347 | })() { 348 | Ok(row) => Box::into_raw(Box::new(row)) as jlong, 349 | Err(err) => { 350 | env.throw(err.to_string()).unwrap(); 351 | return ptr::null_mut::() as jlong; 352 | } 353 | } 354 | } 355 | 356 | #[jni_fn("tech.turso.libsql.Transaction")] 357 | pub fn nativeTransaction(mut env: JNIEnv, _: JClass, tx: jlong) -> jlong { 358 | let tx = ManuallyDrop::new(unsafe { Box::from_raw(tx as *mut Transaction) }); 359 | 360 | match RT.block_on(tx.transaction()) { 361 | Ok(t) => Box::into_raw(Box::new(t)) as jlong, 362 | Err(err) => { 363 | env.throw(err.to_string()).unwrap(); 364 | return ptr::null_mut::() as jlong; 365 | } 366 | } 367 | } 368 | 369 | #[jni_fn("tech.turso.libsql.Transaction")] 370 | pub fn nativeCommit(mut env: JNIEnv, _: JClass, tx: jlong) { 371 | let tx = unsafe { Box::from_raw(tx as *mut Transaction) }; 372 | 373 | match RT.block_on(tx.commit()) { 374 | Ok(_) => (), 375 | Err(err) => { 376 | env.throw(err.to_string()).unwrap(); 377 | } 378 | } 379 | } 380 | 381 | #[jni_fn("tech.turso.libsql.Transaction")] 382 | pub fn nativeRollback(mut env: JNIEnv, _: JClass, tx: jlong) { 383 | let tx = unsafe { Box::from_raw(tx as *mut Transaction) }; 384 | 385 | match RT.block_on(tx.rollback()) { 386 | Ok(_) => (), 387 | Err(err) => { 388 | env.throw(err.to_string()).unwrap(); 389 | } 390 | } 391 | } 392 | 393 | #[jni_fn("tech.turso.libsql.Transaction")] 394 | pub fn nativeClose(_: JNIEnv, _: JClass, tx: jlong) { 395 | drop(unsafe { Box::from_raw(tx as *mut Transaction) }); 396 | } 397 | -------------------------------------------------------------------------------- /libsql/src/main/rust/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.24.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler2" 16 | version = "2.0.1" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" 19 | 20 | [[package]] 21 | name = "aes" 22 | version = "0.8.4" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" 25 | dependencies = [ 26 | "cfg-if", 27 | "cipher", 28 | "cpufeatures", 29 | ] 30 | 31 | [[package]] 32 | name = "ahash" 33 | version = "0.8.12" 34 | source = "registry+https://github.com/rust-lang/crates.io-index" 35 | checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" 36 | dependencies = [ 37 | "cfg-if", 38 | "once_cell", 39 | "version_check", 40 | "zerocopy 0.8.26", 41 | ] 42 | 43 | [[package]] 44 | name = "aho-corasick" 45 | version = "1.1.3" 46 | source = "registry+https://github.com/rust-lang/crates.io-index" 47 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 48 | dependencies = [ 49 | "memchr", 50 | ] 51 | 52 | [[package]] 53 | name = "allocator-api2" 54 | version = "0.2.21" 55 | source = "registry+https://github.com/rust-lang/crates.io-index" 56 | checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" 57 | 58 | [[package]] 59 | name = "android-tzdata" 60 | version = "0.1.1" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" 63 | 64 | [[package]] 65 | name = "android_system_properties" 66 | version = "0.1.5" 67 | source = "registry+https://github.com/rust-lang/crates.io-index" 68 | checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" 69 | dependencies = [ 70 | "libc", 71 | ] 72 | 73 | [[package]] 74 | name = "anyhow" 75 | version = "1.0.98" 76 | source = "registry+https://github.com/rust-lang/crates.io-index" 77 | checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" 78 | 79 | [[package]] 80 | name = "async-stream" 81 | version = "0.3.6" 82 | source = "registry+https://github.com/rust-lang/crates.io-index" 83 | checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" 84 | dependencies = [ 85 | "async-stream-impl", 86 | "futures-core", 87 | "pin-project-lite", 88 | ] 89 | 90 | [[package]] 91 | name = "async-stream-impl" 92 | version = "0.3.6" 93 | source = "registry+https://github.com/rust-lang/crates.io-index" 94 | checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" 95 | dependencies = [ 96 | "proc-macro2", 97 | "quote", 98 | "syn 2.0.104", 99 | ] 100 | 101 | [[package]] 102 | name = "async-trait" 103 | version = "0.1.88" 104 | source = "registry+https://github.com/rust-lang/crates.io-index" 105 | checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" 106 | dependencies = [ 107 | "proc-macro2", 108 | "quote", 109 | "syn 2.0.104", 110 | ] 111 | 112 | [[package]] 113 | name = "autocfg" 114 | version = "1.5.0" 115 | source = "registry+https://github.com/rust-lang/crates.io-index" 116 | checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" 117 | 118 | [[package]] 119 | name = "axum" 120 | version = "0.6.20" 121 | source = "registry+https://github.com/rust-lang/crates.io-index" 122 | checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" 123 | dependencies = [ 124 | "async-trait", 125 | "axum-core", 126 | "bitflags 1.3.2", 127 | "bytes", 128 | "futures-util", 129 | "http", 130 | "http-body", 131 | "hyper", 132 | "itoa", 133 | "matchit", 134 | "memchr", 135 | "mime", 136 | "percent-encoding", 137 | "pin-project-lite", 138 | "rustversion", 139 | "serde", 140 | "sync_wrapper", 141 | "tower", 142 | "tower-layer", 143 | "tower-service", 144 | ] 145 | 146 | [[package]] 147 | name = "axum-core" 148 | version = "0.3.4" 149 | source = "registry+https://github.com/rust-lang/crates.io-index" 150 | checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" 151 | dependencies = [ 152 | "async-trait", 153 | "bytes", 154 | "futures-util", 155 | "http", 156 | "http-body", 157 | "mime", 158 | "rustversion", 159 | "tower-layer", 160 | "tower-service", 161 | ] 162 | 163 | [[package]] 164 | name = "backtrace" 165 | version = "0.3.75" 166 | source = "registry+https://github.com/rust-lang/crates.io-index" 167 | checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" 168 | dependencies = [ 169 | "addr2line", 170 | "cfg-if", 171 | "libc", 172 | "miniz_oxide", 173 | "object", 174 | "rustc-demangle", 175 | "windows-targets 0.52.6", 176 | ] 177 | 178 | [[package]] 179 | name = "base64" 180 | version = "0.21.7" 181 | source = "registry+https://github.com/rust-lang/crates.io-index" 182 | checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" 183 | 184 | [[package]] 185 | name = "bincode" 186 | version = "1.3.3" 187 | source = "registry+https://github.com/rust-lang/crates.io-index" 188 | checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" 189 | dependencies = [ 190 | "serde", 191 | ] 192 | 193 | [[package]] 194 | name = "bindgen" 195 | version = "0.66.1" 196 | source = "registry+https://github.com/rust-lang/crates.io-index" 197 | checksum = "f2b84e06fc203107bfbad243f4aba2af864eb7db3b1cf46ea0a023b0b433d2a7" 198 | dependencies = [ 199 | "bitflags 2.9.1", 200 | "cexpr", 201 | "clang-sys", 202 | "lazy_static", 203 | "lazycell", 204 | "log", 205 | "peeking_take_while", 206 | "prettyplease", 207 | "proc-macro2", 208 | "quote", 209 | "regex", 210 | "rustc-hash", 211 | "shlex", 212 | "syn 2.0.104", 213 | "which", 214 | ] 215 | 216 | [[package]] 217 | name = "bitflags" 218 | version = "1.3.2" 219 | source = "registry+https://github.com/rust-lang/crates.io-index" 220 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 221 | 222 | [[package]] 223 | name = "bitflags" 224 | version = "2.9.1" 225 | source = "registry+https://github.com/rust-lang/crates.io-index" 226 | checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" 227 | 228 | [[package]] 229 | name = "block-padding" 230 | version = "0.3.3" 231 | source = "registry+https://github.com/rust-lang/crates.io-index" 232 | checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" 233 | dependencies = [ 234 | "generic-array", 235 | ] 236 | 237 | [[package]] 238 | name = "bumpalo" 239 | version = "3.19.0" 240 | source = "registry+https://github.com/rust-lang/crates.io-index" 241 | checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" 242 | 243 | [[package]] 244 | name = "byteorder" 245 | version = "1.5.0" 246 | source = "registry+https://github.com/rust-lang/crates.io-index" 247 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 248 | 249 | [[package]] 250 | name = "bytes" 251 | version = "1.10.1" 252 | source = "registry+https://github.com/rust-lang/crates.io-index" 253 | checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" 254 | dependencies = [ 255 | "serde", 256 | ] 257 | 258 | [[package]] 259 | name = "catch_panic" 260 | version = "1.0.0" 261 | source = "git+https://github.com/sorz/catch_panic.git?branch=fix-jni-0.21#92d4158065e0b8de5169ba5fa6f05a6321d28a8d" 262 | dependencies = [ 263 | "catch_panic_macros", 264 | "jni", 265 | ] 266 | 267 | [[package]] 268 | name = "catch_panic_macros" 269 | version = "1.0.0" 270 | source = "git+https://github.com/sorz/catch_panic.git?branch=fix-jni-0.21#92d4158065e0b8de5169ba5fa6f05a6321d28a8d" 271 | dependencies = [ 272 | "proc-macro2", 273 | "quote", 274 | "syn 1.0.109", 275 | ] 276 | 277 | [[package]] 278 | name = "cbc" 279 | version = "0.1.2" 280 | source = "registry+https://github.com/rust-lang/crates.io-index" 281 | checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" 282 | dependencies = [ 283 | "cipher", 284 | ] 285 | 286 | [[package]] 287 | name = "cc" 288 | version = "1.2.29" 289 | source = "registry+https://github.com/rust-lang/crates.io-index" 290 | checksum = "5c1599538de2394445747c8cf7935946e3cc27e9625f889d979bfb2aaf569362" 291 | dependencies = [ 292 | "shlex", 293 | ] 294 | 295 | [[package]] 296 | name = "cesu8" 297 | version = "1.1.0" 298 | source = "registry+https://github.com/rust-lang/crates.io-index" 299 | checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" 300 | 301 | [[package]] 302 | name = "cexpr" 303 | version = "0.6.0" 304 | source = "registry+https://github.com/rust-lang/crates.io-index" 305 | checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" 306 | dependencies = [ 307 | "nom", 308 | ] 309 | 310 | [[package]] 311 | name = "cfg-if" 312 | version = "1.0.1" 313 | source = "registry+https://github.com/rust-lang/crates.io-index" 314 | checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" 315 | 316 | [[package]] 317 | name = "chrono" 318 | version = "0.4.41" 319 | source = "registry+https://github.com/rust-lang/crates.io-index" 320 | checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" 321 | dependencies = [ 322 | "android-tzdata", 323 | "iana-time-zone", 324 | "js-sys", 325 | "num-traits", 326 | "wasm-bindgen", 327 | "windows-link", 328 | ] 329 | 330 | [[package]] 331 | name = "cipher" 332 | version = "0.4.4" 333 | source = "registry+https://github.com/rust-lang/crates.io-index" 334 | checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" 335 | dependencies = [ 336 | "crypto-common", 337 | "inout", 338 | ] 339 | 340 | [[package]] 341 | name = "clang-sys" 342 | version = "1.8.1" 343 | source = "registry+https://github.com/rust-lang/crates.io-index" 344 | checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" 345 | dependencies = [ 346 | "glob", 347 | "libc", 348 | "libloading", 349 | ] 350 | 351 | [[package]] 352 | name = "cmake" 353 | version = "0.1.54" 354 | source = "registry+https://github.com/rust-lang/crates.io-index" 355 | checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" 356 | dependencies = [ 357 | "cc", 358 | ] 359 | 360 | [[package]] 361 | name = "combine" 362 | version = "4.6.7" 363 | source = "registry+https://github.com/rust-lang/crates.io-index" 364 | checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" 365 | dependencies = [ 366 | "bytes", 367 | "memchr", 368 | ] 369 | 370 | [[package]] 371 | name = "core-foundation" 372 | version = "0.9.4" 373 | source = "registry+https://github.com/rust-lang/crates.io-index" 374 | checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" 375 | dependencies = [ 376 | "core-foundation-sys", 377 | "libc", 378 | ] 379 | 380 | [[package]] 381 | name = "core-foundation-sys" 382 | version = "0.8.7" 383 | source = "registry+https://github.com/rust-lang/crates.io-index" 384 | checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" 385 | 386 | [[package]] 387 | name = "cpufeatures" 388 | version = "0.2.17" 389 | source = "registry+https://github.com/rust-lang/crates.io-index" 390 | checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" 391 | dependencies = [ 392 | "libc", 393 | ] 394 | 395 | [[package]] 396 | name = "crc32fast" 397 | version = "1.4.2" 398 | source = "registry+https://github.com/rust-lang/crates.io-index" 399 | checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" 400 | dependencies = [ 401 | "cfg-if", 402 | ] 403 | 404 | [[package]] 405 | name = "crypto-common" 406 | version = "0.1.6" 407 | source = "registry+https://github.com/rust-lang/crates.io-index" 408 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 409 | dependencies = [ 410 | "generic-array", 411 | "typenum", 412 | ] 413 | 414 | [[package]] 415 | name = "darling" 416 | version = "0.20.11" 417 | source = "registry+https://github.com/rust-lang/crates.io-index" 418 | checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" 419 | dependencies = [ 420 | "darling_core", 421 | "darling_macro", 422 | ] 423 | 424 | [[package]] 425 | name = "darling_core" 426 | version = "0.20.11" 427 | source = "registry+https://github.com/rust-lang/crates.io-index" 428 | checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" 429 | dependencies = [ 430 | "fnv", 431 | "ident_case", 432 | "proc-macro2", 433 | "quote", 434 | "strsim", 435 | "syn 2.0.104", 436 | ] 437 | 438 | [[package]] 439 | name = "darling_macro" 440 | version = "0.20.11" 441 | source = "registry+https://github.com/rust-lang/crates.io-index" 442 | checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" 443 | dependencies = [ 444 | "darling_core", 445 | "quote", 446 | "syn 2.0.104", 447 | ] 448 | 449 | [[package]] 450 | name = "either" 451 | version = "1.15.0" 452 | source = "registry+https://github.com/rust-lang/crates.io-index" 453 | checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" 454 | 455 | [[package]] 456 | name = "equivalent" 457 | version = "1.0.2" 458 | source = "registry+https://github.com/rust-lang/crates.io-index" 459 | checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" 460 | 461 | [[package]] 462 | name = "errno" 463 | version = "0.3.13" 464 | source = "registry+https://github.com/rust-lang/crates.io-index" 465 | checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" 466 | dependencies = [ 467 | "libc", 468 | "windows-sys 0.60.2", 469 | ] 470 | 471 | [[package]] 472 | name = "fallible-iterator" 473 | version = "0.2.0" 474 | source = "registry+https://github.com/rust-lang/crates.io-index" 475 | checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" 476 | 477 | [[package]] 478 | name = "fallible-iterator" 479 | version = "0.3.0" 480 | source = "registry+https://github.com/rust-lang/crates.io-index" 481 | checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" 482 | 483 | [[package]] 484 | name = "fallible-streaming-iterator" 485 | version = "0.1.9" 486 | source = "registry+https://github.com/rust-lang/crates.io-index" 487 | checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" 488 | 489 | [[package]] 490 | name = "fastrand" 491 | version = "2.3.0" 492 | source = "registry+https://github.com/rust-lang/crates.io-index" 493 | checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" 494 | 495 | [[package]] 496 | name = "fixedbitset" 497 | version = "0.5.7" 498 | source = "registry+https://github.com/rust-lang/crates.io-index" 499 | checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" 500 | 501 | [[package]] 502 | name = "fnv" 503 | version = "1.0.7" 504 | source = "registry+https://github.com/rust-lang/crates.io-index" 505 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 506 | 507 | [[package]] 508 | name = "futures" 509 | version = "0.3.31" 510 | source = "registry+https://github.com/rust-lang/crates.io-index" 511 | checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" 512 | dependencies = [ 513 | "futures-channel", 514 | "futures-core", 515 | "futures-executor", 516 | "futures-io", 517 | "futures-sink", 518 | "futures-task", 519 | "futures-util", 520 | ] 521 | 522 | [[package]] 523 | name = "futures-channel" 524 | version = "0.3.31" 525 | source = "registry+https://github.com/rust-lang/crates.io-index" 526 | checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" 527 | dependencies = [ 528 | "futures-core", 529 | "futures-sink", 530 | ] 531 | 532 | [[package]] 533 | name = "futures-core" 534 | version = "0.3.31" 535 | source = "registry+https://github.com/rust-lang/crates.io-index" 536 | checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" 537 | 538 | [[package]] 539 | name = "futures-executor" 540 | version = "0.3.31" 541 | source = "registry+https://github.com/rust-lang/crates.io-index" 542 | checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" 543 | dependencies = [ 544 | "futures-core", 545 | "futures-task", 546 | "futures-util", 547 | ] 548 | 549 | [[package]] 550 | name = "futures-io" 551 | version = "0.3.31" 552 | source = "registry+https://github.com/rust-lang/crates.io-index" 553 | checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" 554 | 555 | [[package]] 556 | name = "futures-macro" 557 | version = "0.3.31" 558 | source = "registry+https://github.com/rust-lang/crates.io-index" 559 | checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" 560 | dependencies = [ 561 | "proc-macro2", 562 | "quote", 563 | "syn 2.0.104", 564 | ] 565 | 566 | [[package]] 567 | name = "futures-sink" 568 | version = "0.3.31" 569 | source = "registry+https://github.com/rust-lang/crates.io-index" 570 | checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" 571 | 572 | [[package]] 573 | name = "futures-task" 574 | version = "0.3.31" 575 | source = "registry+https://github.com/rust-lang/crates.io-index" 576 | checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" 577 | 578 | [[package]] 579 | name = "futures-util" 580 | version = "0.3.31" 581 | source = "registry+https://github.com/rust-lang/crates.io-index" 582 | checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" 583 | dependencies = [ 584 | "futures-channel", 585 | "futures-core", 586 | "futures-io", 587 | "futures-macro", 588 | "futures-sink", 589 | "futures-task", 590 | "memchr", 591 | "pin-project-lite", 592 | "pin-utils", 593 | "slab", 594 | ] 595 | 596 | [[package]] 597 | name = "generic-array" 598 | version = "0.14.7" 599 | source = "registry+https://github.com/rust-lang/crates.io-index" 600 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 601 | dependencies = [ 602 | "typenum", 603 | "version_check", 604 | ] 605 | 606 | [[package]] 607 | name = "getrandom" 608 | version = "0.2.16" 609 | source = "registry+https://github.com/rust-lang/crates.io-index" 610 | checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" 611 | dependencies = [ 612 | "cfg-if", 613 | "libc", 614 | "wasi 0.11.1+wasi-snapshot-preview1", 615 | ] 616 | 617 | [[package]] 618 | name = "getrandom" 619 | version = "0.3.3" 620 | source = "registry+https://github.com/rust-lang/crates.io-index" 621 | checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" 622 | dependencies = [ 623 | "cfg-if", 624 | "libc", 625 | "r-efi", 626 | "wasi 0.14.2+wasi-0.2.4", 627 | ] 628 | 629 | [[package]] 630 | name = "gimli" 631 | version = "0.31.1" 632 | source = "registry+https://github.com/rust-lang/crates.io-index" 633 | checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" 634 | 635 | [[package]] 636 | name = "glob" 637 | version = "0.3.2" 638 | source = "registry+https://github.com/rust-lang/crates.io-index" 639 | checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" 640 | 641 | [[package]] 642 | name = "h2" 643 | version = "0.3.26" 644 | source = "registry+https://github.com/rust-lang/crates.io-index" 645 | checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" 646 | dependencies = [ 647 | "bytes", 648 | "fnv", 649 | "futures-core", 650 | "futures-sink", 651 | "futures-util", 652 | "http", 653 | "indexmap 2.10.0", 654 | "slab", 655 | "tokio", 656 | "tokio-util", 657 | "tracing", 658 | ] 659 | 660 | [[package]] 661 | name = "hashbrown" 662 | version = "0.12.3" 663 | source = "registry+https://github.com/rust-lang/crates.io-index" 664 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 665 | 666 | [[package]] 667 | name = "hashbrown" 668 | version = "0.14.5" 669 | source = "registry+https://github.com/rust-lang/crates.io-index" 670 | checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" 671 | dependencies = [ 672 | "ahash", 673 | "allocator-api2", 674 | ] 675 | 676 | [[package]] 677 | name = "hashbrown" 678 | version = "0.15.4" 679 | source = "registry+https://github.com/rust-lang/crates.io-index" 680 | checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" 681 | 682 | [[package]] 683 | name = "hashlink" 684 | version = "0.8.4" 685 | source = "registry+https://github.com/rust-lang/crates.io-index" 686 | checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" 687 | dependencies = [ 688 | "hashbrown 0.14.5", 689 | ] 690 | 691 | [[package]] 692 | name = "heck" 693 | version = "0.5.0" 694 | source = "registry+https://github.com/rust-lang/crates.io-index" 695 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 696 | 697 | [[package]] 698 | name = "home" 699 | version = "0.5.11" 700 | source = "registry+https://github.com/rust-lang/crates.io-index" 701 | checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" 702 | dependencies = [ 703 | "windows-sys 0.59.0", 704 | ] 705 | 706 | [[package]] 707 | name = "http" 708 | version = "0.2.12" 709 | source = "registry+https://github.com/rust-lang/crates.io-index" 710 | checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" 711 | dependencies = [ 712 | "bytes", 713 | "fnv", 714 | "itoa", 715 | ] 716 | 717 | [[package]] 718 | name = "http-body" 719 | version = "0.4.6" 720 | source = "registry+https://github.com/rust-lang/crates.io-index" 721 | checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" 722 | dependencies = [ 723 | "bytes", 724 | "http", 725 | "pin-project-lite", 726 | ] 727 | 728 | [[package]] 729 | name = "http-range-header" 730 | version = "0.3.1" 731 | source = "registry+https://github.com/rust-lang/crates.io-index" 732 | checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" 733 | 734 | [[package]] 735 | name = "httparse" 736 | version = "1.10.1" 737 | source = "registry+https://github.com/rust-lang/crates.io-index" 738 | checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" 739 | 740 | [[package]] 741 | name = "httpdate" 742 | version = "1.0.3" 743 | source = "registry+https://github.com/rust-lang/crates.io-index" 744 | checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" 745 | 746 | [[package]] 747 | name = "hyper" 748 | version = "0.14.32" 749 | source = "registry+https://github.com/rust-lang/crates.io-index" 750 | checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" 751 | dependencies = [ 752 | "bytes", 753 | "futures-channel", 754 | "futures-core", 755 | "futures-util", 756 | "h2", 757 | "http", 758 | "http-body", 759 | "httparse", 760 | "httpdate", 761 | "itoa", 762 | "pin-project-lite", 763 | "socket2", 764 | "tokio", 765 | "tower-service", 766 | "tracing", 767 | "want", 768 | ] 769 | 770 | [[package]] 771 | name = "hyper-rustls" 772 | version = "0.25.0" 773 | source = "registry+https://github.com/rust-lang/crates.io-index" 774 | checksum = "399c78f9338483cb7e630c8474b07268983c6bd5acee012e4211f9f7bb21b070" 775 | dependencies = [ 776 | "futures-util", 777 | "http", 778 | "hyper", 779 | "log", 780 | "rustls", 781 | "rustls-native-certs", 782 | "rustls-pki-types", 783 | "tokio", 784 | "tokio-rustls", 785 | "webpki-roots 0.26.11", 786 | ] 787 | 788 | [[package]] 789 | name = "hyper-timeout" 790 | version = "0.4.1" 791 | source = "registry+https://github.com/rust-lang/crates.io-index" 792 | checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" 793 | dependencies = [ 794 | "hyper", 795 | "pin-project-lite", 796 | "tokio", 797 | "tokio-io-timeout", 798 | ] 799 | 800 | [[package]] 801 | name = "iana-time-zone" 802 | version = "0.1.63" 803 | source = "registry+https://github.com/rust-lang/crates.io-index" 804 | checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" 805 | dependencies = [ 806 | "android_system_properties", 807 | "core-foundation-sys", 808 | "iana-time-zone-haiku", 809 | "js-sys", 810 | "log", 811 | "wasm-bindgen", 812 | "windows-core", 813 | ] 814 | 815 | [[package]] 816 | name = "iana-time-zone-haiku" 817 | version = "0.1.2" 818 | source = "registry+https://github.com/rust-lang/crates.io-index" 819 | checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" 820 | dependencies = [ 821 | "cc", 822 | ] 823 | 824 | [[package]] 825 | name = "ident_case" 826 | version = "1.0.1" 827 | source = "registry+https://github.com/rust-lang/crates.io-index" 828 | checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" 829 | 830 | [[package]] 831 | name = "indexmap" 832 | version = "1.9.3" 833 | source = "registry+https://github.com/rust-lang/crates.io-index" 834 | checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" 835 | dependencies = [ 836 | "autocfg", 837 | "hashbrown 0.12.3", 838 | ] 839 | 840 | [[package]] 841 | name = "indexmap" 842 | version = "2.10.0" 843 | source = "registry+https://github.com/rust-lang/crates.io-index" 844 | checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" 845 | dependencies = [ 846 | "equivalent", 847 | "hashbrown 0.15.4", 848 | ] 849 | 850 | [[package]] 851 | name = "inout" 852 | version = "0.1.4" 853 | source = "registry+https://github.com/rust-lang/crates.io-index" 854 | checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" 855 | dependencies = [ 856 | "block-padding", 857 | "generic-array", 858 | ] 859 | 860 | [[package]] 861 | name = "io-uring" 862 | version = "0.7.8" 863 | source = "registry+https://github.com/rust-lang/crates.io-index" 864 | checksum = "b86e202f00093dcba4275d4636b93ef9dd75d025ae560d2521b45ea28ab49013" 865 | dependencies = [ 866 | "bitflags 2.9.1", 867 | "cfg-if", 868 | "libc", 869 | ] 870 | 871 | [[package]] 872 | name = "itertools" 873 | version = "0.12.1" 874 | source = "registry+https://github.com/rust-lang/crates.io-index" 875 | checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" 876 | dependencies = [ 877 | "either", 878 | ] 879 | 880 | [[package]] 881 | name = "itertools" 882 | version = "0.14.0" 883 | source = "registry+https://github.com/rust-lang/crates.io-index" 884 | checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" 885 | dependencies = [ 886 | "either", 887 | ] 888 | 889 | [[package]] 890 | name = "itoa" 891 | version = "1.0.15" 892 | source = "registry+https://github.com/rust-lang/crates.io-index" 893 | checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" 894 | 895 | [[package]] 896 | name = "jni" 897 | version = "0.21.1" 898 | source = "registry+https://github.com/rust-lang/crates.io-index" 899 | checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" 900 | dependencies = [ 901 | "cesu8", 902 | "cfg-if", 903 | "combine", 904 | "jni-sys", 905 | "log", 906 | "thiserror", 907 | "walkdir", 908 | "windows-sys 0.45.0", 909 | ] 910 | 911 | [[package]] 912 | name = "jni-mangle" 913 | version = "0.1.2" 914 | source = "registry+https://github.com/rust-lang/crates.io-index" 915 | checksum = "4f44aabf2a96de508cd5582366347d8794a940b0802b93a71882993ea7c3c9c2" 916 | dependencies = [ 917 | "darling", 918 | "proc-macro2", 919 | "quote", 920 | "regex", 921 | "syn 2.0.104", 922 | ] 923 | 924 | [[package]] 925 | name = "jni-sys" 926 | version = "0.3.0" 927 | source = "registry+https://github.com/rust-lang/crates.io-index" 928 | checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" 929 | 930 | [[package]] 931 | name = "jni_fn" 932 | version = "0.1.2" 933 | source = "registry+https://github.com/rust-lang/crates.io-index" 934 | checksum = "9027f7e19a424f3d3b923ceac9a9ed5bbdd531d014c58ab37ee507793e8942f9" 935 | dependencies = [ 936 | "proc-macro2", 937 | "quote", 938 | "syn 2.0.104", 939 | ] 940 | 941 | [[package]] 942 | name = "js-sys" 943 | version = "0.3.77" 944 | source = "registry+https://github.com/rust-lang/crates.io-index" 945 | checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" 946 | dependencies = [ 947 | "once_cell", 948 | "wasm-bindgen", 949 | ] 950 | 951 | [[package]] 952 | name = "lazy_static" 953 | version = "1.5.0" 954 | source = "registry+https://github.com/rust-lang/crates.io-index" 955 | checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" 956 | 957 | [[package]] 958 | name = "lazycell" 959 | version = "1.3.0" 960 | source = "registry+https://github.com/rust-lang/crates.io-index" 961 | checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" 962 | 963 | [[package]] 964 | name = "libc" 965 | version = "0.2.174" 966 | source = "registry+https://github.com/rust-lang/crates.io-index" 967 | checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" 968 | 969 | [[package]] 970 | name = "libloading" 971 | version = "0.8.8" 972 | source = "registry+https://github.com/rust-lang/crates.io-index" 973 | checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" 974 | dependencies = [ 975 | "cfg-if", 976 | "windows-targets 0.53.2", 977 | ] 978 | 979 | [[package]] 980 | name = "libsql" 981 | version = "0.9.11" 982 | source = "registry+https://github.com/rust-lang/crates.io-index" 983 | checksum = "d41c1c2106d415b8bf929ca6e644e2bc9a44ce5aea9819350276e4d97e27f3b1" 984 | dependencies = [ 985 | "anyhow", 986 | "async-stream", 987 | "async-trait", 988 | "base64", 989 | "bincode", 990 | "bitflags 2.9.1", 991 | "bytes", 992 | "chrono", 993 | "crc32fast", 994 | "fallible-iterator 0.3.0", 995 | "futures", 996 | "http", 997 | "hyper", 998 | "hyper-rustls", 999 | "libsql-hrana", 1000 | "libsql-sqlite3-parser", 1001 | "libsql-sys", 1002 | "libsql_replication", 1003 | "parking_lot", 1004 | "serde", 1005 | "serde_json", 1006 | "thiserror", 1007 | "tokio", 1008 | "tokio-stream", 1009 | "tokio-util", 1010 | "tonic", 1011 | "tonic-web", 1012 | "tower", 1013 | "tower-http", 1014 | "tracing", 1015 | "uuid", 1016 | "zerocopy 0.7.35", 1017 | ] 1018 | 1019 | [[package]] 1020 | name = "libsql-ffi" 1021 | version = "0.9.11" 1022 | source = "registry+https://github.com/rust-lang/crates.io-index" 1023 | checksum = "e0df681b059a8672691e60232e78967ba821edd37e959f4e9fa8a3de36e9ca29" 1024 | dependencies = [ 1025 | "bindgen", 1026 | "cc", 1027 | "cmake", 1028 | "glob", 1029 | ] 1030 | 1031 | [[package]] 1032 | name = "libsql-hrana" 1033 | version = "0.9.11" 1034 | source = "registry+https://github.com/rust-lang/crates.io-index" 1035 | checksum = "09754f239a048aff667f0f2f492a4011d2bdafa8e662c138ab2c86badf73aaf5" 1036 | dependencies = [ 1037 | "base64", 1038 | "bytes", 1039 | "prost 0.12.6", 1040 | "serde", 1041 | ] 1042 | 1043 | [[package]] 1044 | name = "libsql-rusqlite" 1045 | version = "0.9.11" 1046 | source = "registry+https://github.com/rust-lang/crates.io-index" 1047 | checksum = "a33fde7ff52002bd1b8935a71ef0823472e19bb3a03c76862072467eb62c73eb" 1048 | dependencies = [ 1049 | "bitflags 2.9.1", 1050 | "fallible-iterator 0.2.0", 1051 | "fallible-streaming-iterator", 1052 | "hashlink", 1053 | "libsql-ffi", 1054 | "smallvec", 1055 | ] 1056 | 1057 | [[package]] 1058 | name = "libsql-sqlite3-parser" 1059 | version = "0.13.0" 1060 | source = "registry+https://github.com/rust-lang/crates.io-index" 1061 | checksum = "15a90128c708356af8f7d767c9ac2946692c9112b4f74f07b99a01a60680e413" 1062 | dependencies = [ 1063 | "bitflags 2.9.1", 1064 | "cc", 1065 | "fallible-iterator 0.3.0", 1066 | "indexmap 2.10.0", 1067 | "log", 1068 | "memchr", 1069 | "phf", 1070 | "phf_codegen", 1071 | "phf_shared", 1072 | "uncased", 1073 | ] 1074 | 1075 | [[package]] 1076 | name = "libsql-sys" 1077 | version = "0.9.11" 1078 | source = "registry+https://github.com/rust-lang/crates.io-index" 1079 | checksum = "62d1e07a691696cb18c2faba98313a194f0804aa6a1ce8aa9919b7ecd290d458" 1080 | dependencies = [ 1081 | "bytes", 1082 | "libsql-ffi", 1083 | "libsql-rusqlite", 1084 | "once_cell", 1085 | "tracing", 1086 | "zerocopy 0.7.35", 1087 | ] 1088 | 1089 | [[package]] 1090 | name = "libsql_android" 1091 | version = "0.1.0" 1092 | dependencies = [ 1093 | "anyhow", 1094 | "catch_panic", 1095 | "hyper-rustls", 1096 | "jni", 1097 | "jni-mangle", 1098 | "jni_fn", 1099 | "lazy_static", 1100 | "libsql", 1101 | "prost 0.13.5", 1102 | "prost-build", 1103 | "prost-types", 1104 | "tokio", 1105 | ] 1106 | 1107 | [[package]] 1108 | name = "libsql_replication" 1109 | version = "0.9.11" 1110 | source = "registry+https://github.com/rust-lang/crates.io-index" 1111 | checksum = "22587cf8791c63fac33f0ee19f225e4ff7922a2ee59dd97fa183869b9a57b32f" 1112 | dependencies = [ 1113 | "aes", 1114 | "async-stream", 1115 | "async-trait", 1116 | "bytes", 1117 | "cbc", 1118 | "libsql-rusqlite", 1119 | "libsql-sys", 1120 | "parking_lot", 1121 | "prost 0.12.6", 1122 | "serde", 1123 | "thiserror", 1124 | "tokio", 1125 | "tokio-stream", 1126 | "tokio-util", 1127 | "tonic", 1128 | "tracing", 1129 | "uuid", 1130 | "zerocopy 0.7.35", 1131 | ] 1132 | 1133 | [[package]] 1134 | name = "linux-raw-sys" 1135 | version = "0.4.15" 1136 | source = "registry+https://github.com/rust-lang/crates.io-index" 1137 | checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" 1138 | 1139 | [[package]] 1140 | name = "linux-raw-sys" 1141 | version = "0.9.4" 1142 | source = "registry+https://github.com/rust-lang/crates.io-index" 1143 | checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" 1144 | 1145 | [[package]] 1146 | name = "lock_api" 1147 | version = "0.4.13" 1148 | source = "registry+https://github.com/rust-lang/crates.io-index" 1149 | checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" 1150 | dependencies = [ 1151 | "autocfg", 1152 | "scopeguard", 1153 | ] 1154 | 1155 | [[package]] 1156 | name = "log" 1157 | version = "0.4.27" 1158 | source = "registry+https://github.com/rust-lang/crates.io-index" 1159 | checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" 1160 | 1161 | [[package]] 1162 | name = "matchit" 1163 | version = "0.7.3" 1164 | source = "registry+https://github.com/rust-lang/crates.io-index" 1165 | checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" 1166 | 1167 | [[package]] 1168 | name = "memchr" 1169 | version = "2.7.5" 1170 | source = "registry+https://github.com/rust-lang/crates.io-index" 1171 | checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" 1172 | 1173 | [[package]] 1174 | name = "mime" 1175 | version = "0.3.17" 1176 | source = "registry+https://github.com/rust-lang/crates.io-index" 1177 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 1178 | 1179 | [[package]] 1180 | name = "minimal-lexical" 1181 | version = "0.2.1" 1182 | source = "registry+https://github.com/rust-lang/crates.io-index" 1183 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" 1184 | 1185 | [[package]] 1186 | name = "miniz_oxide" 1187 | version = "0.8.9" 1188 | source = "registry+https://github.com/rust-lang/crates.io-index" 1189 | checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" 1190 | dependencies = [ 1191 | "adler2", 1192 | ] 1193 | 1194 | [[package]] 1195 | name = "mio" 1196 | version = "1.0.4" 1197 | source = "registry+https://github.com/rust-lang/crates.io-index" 1198 | checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" 1199 | dependencies = [ 1200 | "libc", 1201 | "wasi 0.11.1+wasi-snapshot-preview1", 1202 | "windows-sys 0.59.0", 1203 | ] 1204 | 1205 | [[package]] 1206 | name = "multimap" 1207 | version = "0.10.1" 1208 | source = "registry+https://github.com/rust-lang/crates.io-index" 1209 | checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" 1210 | 1211 | [[package]] 1212 | name = "nom" 1213 | version = "7.1.3" 1214 | source = "registry+https://github.com/rust-lang/crates.io-index" 1215 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" 1216 | dependencies = [ 1217 | "memchr", 1218 | "minimal-lexical", 1219 | ] 1220 | 1221 | [[package]] 1222 | name = "num-traits" 1223 | version = "0.2.19" 1224 | source = "registry+https://github.com/rust-lang/crates.io-index" 1225 | checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" 1226 | dependencies = [ 1227 | "autocfg", 1228 | ] 1229 | 1230 | [[package]] 1231 | name = "object" 1232 | version = "0.36.7" 1233 | source = "registry+https://github.com/rust-lang/crates.io-index" 1234 | checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" 1235 | dependencies = [ 1236 | "memchr", 1237 | ] 1238 | 1239 | [[package]] 1240 | name = "once_cell" 1241 | version = "1.21.3" 1242 | source = "registry+https://github.com/rust-lang/crates.io-index" 1243 | checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" 1244 | 1245 | [[package]] 1246 | name = "openssl-probe" 1247 | version = "0.1.6" 1248 | source = "registry+https://github.com/rust-lang/crates.io-index" 1249 | checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" 1250 | 1251 | [[package]] 1252 | name = "parking_lot" 1253 | version = "0.12.4" 1254 | source = "registry+https://github.com/rust-lang/crates.io-index" 1255 | checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" 1256 | dependencies = [ 1257 | "lock_api", 1258 | "parking_lot_core", 1259 | ] 1260 | 1261 | [[package]] 1262 | name = "parking_lot_core" 1263 | version = "0.9.11" 1264 | source = "registry+https://github.com/rust-lang/crates.io-index" 1265 | checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" 1266 | dependencies = [ 1267 | "cfg-if", 1268 | "libc", 1269 | "redox_syscall", 1270 | "smallvec", 1271 | "windows-targets 0.52.6", 1272 | ] 1273 | 1274 | [[package]] 1275 | name = "peeking_take_while" 1276 | version = "0.1.2" 1277 | source = "registry+https://github.com/rust-lang/crates.io-index" 1278 | checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" 1279 | 1280 | [[package]] 1281 | name = "percent-encoding" 1282 | version = "2.3.1" 1283 | source = "registry+https://github.com/rust-lang/crates.io-index" 1284 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 1285 | 1286 | [[package]] 1287 | name = "petgraph" 1288 | version = "0.7.1" 1289 | source = "registry+https://github.com/rust-lang/crates.io-index" 1290 | checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" 1291 | dependencies = [ 1292 | "fixedbitset", 1293 | "indexmap 2.10.0", 1294 | ] 1295 | 1296 | [[package]] 1297 | name = "phf" 1298 | version = "0.11.3" 1299 | source = "registry+https://github.com/rust-lang/crates.io-index" 1300 | checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" 1301 | dependencies = [ 1302 | "phf_shared", 1303 | ] 1304 | 1305 | [[package]] 1306 | name = "phf_codegen" 1307 | version = "0.11.3" 1308 | source = "registry+https://github.com/rust-lang/crates.io-index" 1309 | checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" 1310 | dependencies = [ 1311 | "phf_generator", 1312 | "phf_shared", 1313 | ] 1314 | 1315 | [[package]] 1316 | name = "phf_generator" 1317 | version = "0.11.3" 1318 | source = "registry+https://github.com/rust-lang/crates.io-index" 1319 | checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" 1320 | dependencies = [ 1321 | "phf_shared", 1322 | "rand", 1323 | ] 1324 | 1325 | [[package]] 1326 | name = "phf_shared" 1327 | version = "0.11.3" 1328 | source = "registry+https://github.com/rust-lang/crates.io-index" 1329 | checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" 1330 | dependencies = [ 1331 | "siphasher", 1332 | "uncased", 1333 | ] 1334 | 1335 | [[package]] 1336 | name = "pin-project" 1337 | version = "1.1.10" 1338 | source = "registry+https://github.com/rust-lang/crates.io-index" 1339 | checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" 1340 | dependencies = [ 1341 | "pin-project-internal", 1342 | ] 1343 | 1344 | [[package]] 1345 | name = "pin-project-internal" 1346 | version = "1.1.10" 1347 | source = "registry+https://github.com/rust-lang/crates.io-index" 1348 | checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" 1349 | dependencies = [ 1350 | "proc-macro2", 1351 | "quote", 1352 | "syn 2.0.104", 1353 | ] 1354 | 1355 | [[package]] 1356 | name = "pin-project-lite" 1357 | version = "0.2.16" 1358 | source = "registry+https://github.com/rust-lang/crates.io-index" 1359 | checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" 1360 | 1361 | [[package]] 1362 | name = "pin-utils" 1363 | version = "0.1.0" 1364 | source = "registry+https://github.com/rust-lang/crates.io-index" 1365 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1366 | 1367 | [[package]] 1368 | name = "ppv-lite86" 1369 | version = "0.2.21" 1370 | source = "registry+https://github.com/rust-lang/crates.io-index" 1371 | checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" 1372 | dependencies = [ 1373 | "zerocopy 0.8.26", 1374 | ] 1375 | 1376 | [[package]] 1377 | name = "prettyplease" 1378 | version = "0.2.35" 1379 | source = "registry+https://github.com/rust-lang/crates.io-index" 1380 | checksum = "061c1221631e079b26479d25bbf2275bfe5917ae8419cd7e34f13bfc2aa7539a" 1381 | dependencies = [ 1382 | "proc-macro2", 1383 | "syn 2.0.104", 1384 | ] 1385 | 1386 | [[package]] 1387 | name = "proc-macro2" 1388 | version = "1.0.95" 1389 | source = "registry+https://github.com/rust-lang/crates.io-index" 1390 | checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" 1391 | dependencies = [ 1392 | "unicode-ident", 1393 | ] 1394 | 1395 | [[package]] 1396 | name = "prost" 1397 | version = "0.12.6" 1398 | source = "registry+https://github.com/rust-lang/crates.io-index" 1399 | checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" 1400 | dependencies = [ 1401 | "bytes", 1402 | "prost-derive 0.12.6", 1403 | ] 1404 | 1405 | [[package]] 1406 | name = "prost" 1407 | version = "0.13.5" 1408 | source = "registry+https://github.com/rust-lang/crates.io-index" 1409 | checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5" 1410 | dependencies = [ 1411 | "bytes", 1412 | "prost-derive 0.13.5", 1413 | ] 1414 | 1415 | [[package]] 1416 | name = "prost-build" 1417 | version = "0.13.5" 1418 | source = "registry+https://github.com/rust-lang/crates.io-index" 1419 | checksum = "be769465445e8c1474e9c5dac2018218498557af32d9ed057325ec9a41ae81bf" 1420 | dependencies = [ 1421 | "heck", 1422 | "itertools 0.14.0", 1423 | "log", 1424 | "multimap", 1425 | "once_cell", 1426 | "petgraph", 1427 | "prettyplease", 1428 | "prost 0.13.5", 1429 | "prost-types", 1430 | "regex", 1431 | "syn 2.0.104", 1432 | "tempfile", 1433 | ] 1434 | 1435 | [[package]] 1436 | name = "prost-derive" 1437 | version = "0.12.6" 1438 | source = "registry+https://github.com/rust-lang/crates.io-index" 1439 | checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" 1440 | dependencies = [ 1441 | "anyhow", 1442 | "itertools 0.12.1", 1443 | "proc-macro2", 1444 | "quote", 1445 | "syn 2.0.104", 1446 | ] 1447 | 1448 | [[package]] 1449 | name = "prost-derive" 1450 | version = "0.13.5" 1451 | source = "registry+https://github.com/rust-lang/crates.io-index" 1452 | checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" 1453 | dependencies = [ 1454 | "anyhow", 1455 | "itertools 0.14.0", 1456 | "proc-macro2", 1457 | "quote", 1458 | "syn 2.0.104", 1459 | ] 1460 | 1461 | [[package]] 1462 | name = "prost-types" 1463 | version = "0.13.5" 1464 | source = "registry+https://github.com/rust-lang/crates.io-index" 1465 | checksum = "52c2c1bf36ddb1a1c396b3601a3cec27c2462e45f07c386894ec3ccf5332bd16" 1466 | dependencies = [ 1467 | "prost 0.13.5", 1468 | ] 1469 | 1470 | [[package]] 1471 | name = "quote" 1472 | version = "1.0.40" 1473 | source = "registry+https://github.com/rust-lang/crates.io-index" 1474 | checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" 1475 | dependencies = [ 1476 | "proc-macro2", 1477 | ] 1478 | 1479 | [[package]] 1480 | name = "r-efi" 1481 | version = "5.3.0" 1482 | source = "registry+https://github.com/rust-lang/crates.io-index" 1483 | checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" 1484 | 1485 | [[package]] 1486 | name = "rand" 1487 | version = "0.8.5" 1488 | source = "registry+https://github.com/rust-lang/crates.io-index" 1489 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 1490 | dependencies = [ 1491 | "libc", 1492 | "rand_chacha", 1493 | "rand_core", 1494 | ] 1495 | 1496 | [[package]] 1497 | name = "rand_chacha" 1498 | version = "0.3.1" 1499 | source = "registry+https://github.com/rust-lang/crates.io-index" 1500 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 1501 | dependencies = [ 1502 | "ppv-lite86", 1503 | "rand_core", 1504 | ] 1505 | 1506 | [[package]] 1507 | name = "rand_core" 1508 | version = "0.6.4" 1509 | source = "registry+https://github.com/rust-lang/crates.io-index" 1510 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 1511 | dependencies = [ 1512 | "getrandom 0.2.16", 1513 | ] 1514 | 1515 | [[package]] 1516 | name = "redox_syscall" 1517 | version = "0.5.13" 1518 | source = "registry+https://github.com/rust-lang/crates.io-index" 1519 | checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6" 1520 | dependencies = [ 1521 | "bitflags 2.9.1", 1522 | ] 1523 | 1524 | [[package]] 1525 | name = "regex" 1526 | version = "1.11.1" 1527 | source = "registry+https://github.com/rust-lang/crates.io-index" 1528 | checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" 1529 | dependencies = [ 1530 | "aho-corasick", 1531 | "memchr", 1532 | "regex-automata", 1533 | "regex-syntax", 1534 | ] 1535 | 1536 | [[package]] 1537 | name = "regex-automata" 1538 | version = "0.4.9" 1539 | source = "registry+https://github.com/rust-lang/crates.io-index" 1540 | checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" 1541 | dependencies = [ 1542 | "aho-corasick", 1543 | "memchr", 1544 | "regex-syntax", 1545 | ] 1546 | 1547 | [[package]] 1548 | name = "regex-syntax" 1549 | version = "0.8.5" 1550 | source = "registry+https://github.com/rust-lang/crates.io-index" 1551 | checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" 1552 | 1553 | [[package]] 1554 | name = "ring" 1555 | version = "0.17.14" 1556 | source = "registry+https://github.com/rust-lang/crates.io-index" 1557 | checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" 1558 | dependencies = [ 1559 | "cc", 1560 | "cfg-if", 1561 | "getrandom 0.2.16", 1562 | "libc", 1563 | "untrusted", 1564 | "windows-sys 0.52.0", 1565 | ] 1566 | 1567 | [[package]] 1568 | name = "rustc-demangle" 1569 | version = "0.1.25" 1570 | source = "registry+https://github.com/rust-lang/crates.io-index" 1571 | checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" 1572 | 1573 | [[package]] 1574 | name = "rustc-hash" 1575 | version = "1.1.0" 1576 | source = "registry+https://github.com/rust-lang/crates.io-index" 1577 | checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" 1578 | 1579 | [[package]] 1580 | name = "rustix" 1581 | version = "0.38.44" 1582 | source = "registry+https://github.com/rust-lang/crates.io-index" 1583 | checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" 1584 | dependencies = [ 1585 | "bitflags 2.9.1", 1586 | "errno", 1587 | "libc", 1588 | "linux-raw-sys 0.4.15", 1589 | "windows-sys 0.59.0", 1590 | ] 1591 | 1592 | [[package]] 1593 | name = "rustix" 1594 | version = "1.0.7" 1595 | source = "registry+https://github.com/rust-lang/crates.io-index" 1596 | checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" 1597 | dependencies = [ 1598 | "bitflags 2.9.1", 1599 | "errno", 1600 | "libc", 1601 | "linux-raw-sys 0.9.4", 1602 | "windows-sys 0.59.0", 1603 | ] 1604 | 1605 | [[package]] 1606 | name = "rustls" 1607 | version = "0.22.4" 1608 | source = "registry+https://github.com/rust-lang/crates.io-index" 1609 | checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" 1610 | dependencies = [ 1611 | "log", 1612 | "ring", 1613 | "rustls-pki-types", 1614 | "rustls-webpki", 1615 | "subtle", 1616 | "zeroize", 1617 | ] 1618 | 1619 | [[package]] 1620 | name = "rustls-native-certs" 1621 | version = "0.7.3" 1622 | source = "registry+https://github.com/rust-lang/crates.io-index" 1623 | checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5" 1624 | dependencies = [ 1625 | "openssl-probe", 1626 | "rustls-pemfile", 1627 | "rustls-pki-types", 1628 | "schannel", 1629 | "security-framework", 1630 | ] 1631 | 1632 | [[package]] 1633 | name = "rustls-pemfile" 1634 | version = "2.2.0" 1635 | source = "registry+https://github.com/rust-lang/crates.io-index" 1636 | checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" 1637 | dependencies = [ 1638 | "rustls-pki-types", 1639 | ] 1640 | 1641 | [[package]] 1642 | name = "rustls-pki-types" 1643 | version = "1.12.0" 1644 | source = "registry+https://github.com/rust-lang/crates.io-index" 1645 | checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" 1646 | dependencies = [ 1647 | "zeroize", 1648 | ] 1649 | 1650 | [[package]] 1651 | name = "rustls-webpki" 1652 | version = "0.102.8" 1653 | source = "registry+https://github.com/rust-lang/crates.io-index" 1654 | checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" 1655 | dependencies = [ 1656 | "ring", 1657 | "rustls-pki-types", 1658 | "untrusted", 1659 | ] 1660 | 1661 | [[package]] 1662 | name = "rustversion" 1663 | version = "1.0.21" 1664 | source = "registry+https://github.com/rust-lang/crates.io-index" 1665 | checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" 1666 | 1667 | [[package]] 1668 | name = "ryu" 1669 | version = "1.0.20" 1670 | source = "registry+https://github.com/rust-lang/crates.io-index" 1671 | checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" 1672 | 1673 | [[package]] 1674 | name = "same-file" 1675 | version = "1.0.6" 1676 | source = "registry+https://github.com/rust-lang/crates.io-index" 1677 | checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" 1678 | dependencies = [ 1679 | "winapi-util", 1680 | ] 1681 | 1682 | [[package]] 1683 | name = "schannel" 1684 | version = "0.1.27" 1685 | source = "registry+https://github.com/rust-lang/crates.io-index" 1686 | checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" 1687 | dependencies = [ 1688 | "windows-sys 0.59.0", 1689 | ] 1690 | 1691 | [[package]] 1692 | name = "scopeguard" 1693 | version = "1.2.0" 1694 | source = "registry+https://github.com/rust-lang/crates.io-index" 1695 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 1696 | 1697 | [[package]] 1698 | name = "security-framework" 1699 | version = "2.11.1" 1700 | source = "registry+https://github.com/rust-lang/crates.io-index" 1701 | checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" 1702 | dependencies = [ 1703 | "bitflags 2.9.1", 1704 | "core-foundation", 1705 | "core-foundation-sys", 1706 | "libc", 1707 | "security-framework-sys", 1708 | ] 1709 | 1710 | [[package]] 1711 | name = "security-framework-sys" 1712 | version = "2.14.0" 1713 | source = "registry+https://github.com/rust-lang/crates.io-index" 1714 | checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" 1715 | dependencies = [ 1716 | "core-foundation-sys", 1717 | "libc", 1718 | ] 1719 | 1720 | [[package]] 1721 | name = "serde" 1722 | version = "1.0.219" 1723 | source = "registry+https://github.com/rust-lang/crates.io-index" 1724 | checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" 1725 | dependencies = [ 1726 | "serde_derive", 1727 | ] 1728 | 1729 | [[package]] 1730 | name = "serde_derive" 1731 | version = "1.0.219" 1732 | source = "registry+https://github.com/rust-lang/crates.io-index" 1733 | checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" 1734 | dependencies = [ 1735 | "proc-macro2", 1736 | "quote", 1737 | "syn 2.0.104", 1738 | ] 1739 | 1740 | [[package]] 1741 | name = "serde_json" 1742 | version = "1.0.140" 1743 | source = "registry+https://github.com/rust-lang/crates.io-index" 1744 | checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" 1745 | dependencies = [ 1746 | "itoa", 1747 | "memchr", 1748 | "ryu", 1749 | "serde", 1750 | ] 1751 | 1752 | [[package]] 1753 | name = "shlex" 1754 | version = "1.3.0" 1755 | source = "registry+https://github.com/rust-lang/crates.io-index" 1756 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 1757 | 1758 | [[package]] 1759 | name = "signal-hook-registry" 1760 | version = "1.4.5" 1761 | source = "registry+https://github.com/rust-lang/crates.io-index" 1762 | checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" 1763 | dependencies = [ 1764 | "libc", 1765 | ] 1766 | 1767 | [[package]] 1768 | name = "siphasher" 1769 | version = "1.0.1" 1770 | source = "registry+https://github.com/rust-lang/crates.io-index" 1771 | checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" 1772 | 1773 | [[package]] 1774 | name = "slab" 1775 | version = "0.4.10" 1776 | source = "registry+https://github.com/rust-lang/crates.io-index" 1777 | checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" 1778 | 1779 | [[package]] 1780 | name = "smallvec" 1781 | version = "1.15.1" 1782 | source = "registry+https://github.com/rust-lang/crates.io-index" 1783 | checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" 1784 | 1785 | [[package]] 1786 | name = "socket2" 1787 | version = "0.5.10" 1788 | source = "registry+https://github.com/rust-lang/crates.io-index" 1789 | checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" 1790 | dependencies = [ 1791 | "libc", 1792 | "windows-sys 0.52.0", 1793 | ] 1794 | 1795 | [[package]] 1796 | name = "strsim" 1797 | version = "0.11.1" 1798 | source = "registry+https://github.com/rust-lang/crates.io-index" 1799 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 1800 | 1801 | [[package]] 1802 | name = "subtle" 1803 | version = "2.6.1" 1804 | source = "registry+https://github.com/rust-lang/crates.io-index" 1805 | checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" 1806 | 1807 | [[package]] 1808 | name = "syn" 1809 | version = "1.0.109" 1810 | source = "registry+https://github.com/rust-lang/crates.io-index" 1811 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 1812 | dependencies = [ 1813 | "proc-macro2", 1814 | "quote", 1815 | "unicode-ident", 1816 | ] 1817 | 1818 | [[package]] 1819 | name = "syn" 1820 | version = "2.0.104" 1821 | source = "registry+https://github.com/rust-lang/crates.io-index" 1822 | checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" 1823 | dependencies = [ 1824 | "proc-macro2", 1825 | "quote", 1826 | "unicode-ident", 1827 | ] 1828 | 1829 | [[package]] 1830 | name = "sync_wrapper" 1831 | version = "0.1.2" 1832 | source = "registry+https://github.com/rust-lang/crates.io-index" 1833 | checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" 1834 | 1835 | [[package]] 1836 | name = "tempfile" 1837 | version = "3.20.0" 1838 | source = "registry+https://github.com/rust-lang/crates.io-index" 1839 | checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" 1840 | dependencies = [ 1841 | "fastrand", 1842 | "getrandom 0.3.3", 1843 | "once_cell", 1844 | "rustix 1.0.7", 1845 | "windows-sys 0.59.0", 1846 | ] 1847 | 1848 | [[package]] 1849 | name = "thiserror" 1850 | version = "1.0.69" 1851 | source = "registry+https://github.com/rust-lang/crates.io-index" 1852 | checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" 1853 | dependencies = [ 1854 | "thiserror-impl", 1855 | ] 1856 | 1857 | [[package]] 1858 | name = "thiserror-impl" 1859 | version = "1.0.69" 1860 | source = "registry+https://github.com/rust-lang/crates.io-index" 1861 | checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" 1862 | dependencies = [ 1863 | "proc-macro2", 1864 | "quote", 1865 | "syn 2.0.104", 1866 | ] 1867 | 1868 | [[package]] 1869 | name = "tokio" 1870 | version = "1.46.1" 1871 | source = "registry+https://github.com/rust-lang/crates.io-index" 1872 | checksum = "0cc3a2344dafbe23a245241fe8b09735b521110d30fcefbbd5feb1797ca35d17" 1873 | dependencies = [ 1874 | "backtrace", 1875 | "bytes", 1876 | "io-uring", 1877 | "libc", 1878 | "mio", 1879 | "parking_lot", 1880 | "pin-project-lite", 1881 | "signal-hook-registry", 1882 | "slab", 1883 | "socket2", 1884 | "tokio-macros", 1885 | "windows-sys 0.52.0", 1886 | ] 1887 | 1888 | [[package]] 1889 | name = "tokio-io-timeout" 1890 | version = "1.2.0" 1891 | source = "registry+https://github.com/rust-lang/crates.io-index" 1892 | checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" 1893 | dependencies = [ 1894 | "pin-project-lite", 1895 | "tokio", 1896 | ] 1897 | 1898 | [[package]] 1899 | name = "tokio-macros" 1900 | version = "2.5.0" 1901 | source = "registry+https://github.com/rust-lang/crates.io-index" 1902 | checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" 1903 | dependencies = [ 1904 | "proc-macro2", 1905 | "quote", 1906 | "syn 2.0.104", 1907 | ] 1908 | 1909 | [[package]] 1910 | name = "tokio-rustls" 1911 | version = "0.25.0" 1912 | source = "registry+https://github.com/rust-lang/crates.io-index" 1913 | checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" 1914 | dependencies = [ 1915 | "rustls", 1916 | "rustls-pki-types", 1917 | "tokio", 1918 | ] 1919 | 1920 | [[package]] 1921 | name = "tokio-stream" 1922 | version = "0.1.17" 1923 | source = "registry+https://github.com/rust-lang/crates.io-index" 1924 | checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" 1925 | dependencies = [ 1926 | "futures-core", 1927 | "pin-project-lite", 1928 | "tokio", 1929 | ] 1930 | 1931 | [[package]] 1932 | name = "tokio-util" 1933 | version = "0.7.15" 1934 | source = "registry+https://github.com/rust-lang/crates.io-index" 1935 | checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df" 1936 | dependencies = [ 1937 | "bytes", 1938 | "futures-core", 1939 | "futures-sink", 1940 | "pin-project-lite", 1941 | "tokio", 1942 | ] 1943 | 1944 | [[package]] 1945 | name = "tonic" 1946 | version = "0.11.0" 1947 | source = "registry+https://github.com/rust-lang/crates.io-index" 1948 | checksum = "76c4eb7a4e9ef9d4763600161f12f5070b92a578e1b634db88a6887844c91a13" 1949 | dependencies = [ 1950 | "async-stream", 1951 | "async-trait", 1952 | "axum", 1953 | "base64", 1954 | "bytes", 1955 | "h2", 1956 | "http", 1957 | "http-body", 1958 | "hyper", 1959 | "hyper-timeout", 1960 | "percent-encoding", 1961 | "pin-project", 1962 | "prost 0.12.6", 1963 | "tokio", 1964 | "tokio-stream", 1965 | "tower", 1966 | "tower-layer", 1967 | "tower-service", 1968 | "tracing", 1969 | ] 1970 | 1971 | [[package]] 1972 | name = "tonic-web" 1973 | version = "0.11.0" 1974 | source = "registry+https://github.com/rust-lang/crates.io-index" 1975 | checksum = "dc3b0e1cedbf19fdfb78ef3d672cb9928e0a91a9cb4629cc0c916e8cff8aaaa1" 1976 | dependencies = [ 1977 | "base64", 1978 | "bytes", 1979 | "http", 1980 | "http-body", 1981 | "hyper", 1982 | "pin-project", 1983 | "tokio-stream", 1984 | "tonic", 1985 | "tower-http", 1986 | "tower-layer", 1987 | "tower-service", 1988 | "tracing", 1989 | ] 1990 | 1991 | [[package]] 1992 | name = "tower" 1993 | version = "0.4.13" 1994 | source = "registry+https://github.com/rust-lang/crates.io-index" 1995 | checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" 1996 | dependencies = [ 1997 | "futures-core", 1998 | "futures-util", 1999 | "indexmap 1.9.3", 2000 | "pin-project", 2001 | "pin-project-lite", 2002 | "rand", 2003 | "slab", 2004 | "tokio", 2005 | "tokio-util", 2006 | "tower-layer", 2007 | "tower-service", 2008 | "tracing", 2009 | ] 2010 | 2011 | [[package]] 2012 | name = "tower-http" 2013 | version = "0.4.4" 2014 | source = "registry+https://github.com/rust-lang/crates.io-index" 2015 | checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" 2016 | dependencies = [ 2017 | "bitflags 2.9.1", 2018 | "bytes", 2019 | "futures-core", 2020 | "futures-util", 2021 | "http", 2022 | "http-body", 2023 | "http-range-header", 2024 | "pin-project-lite", 2025 | "tower", 2026 | "tower-layer", 2027 | "tower-service", 2028 | "tracing", 2029 | ] 2030 | 2031 | [[package]] 2032 | name = "tower-layer" 2033 | version = "0.3.3" 2034 | source = "registry+https://github.com/rust-lang/crates.io-index" 2035 | checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" 2036 | 2037 | [[package]] 2038 | name = "tower-service" 2039 | version = "0.3.3" 2040 | source = "registry+https://github.com/rust-lang/crates.io-index" 2041 | checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" 2042 | 2043 | [[package]] 2044 | name = "tracing" 2045 | version = "0.1.41" 2046 | source = "registry+https://github.com/rust-lang/crates.io-index" 2047 | checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" 2048 | dependencies = [ 2049 | "log", 2050 | "pin-project-lite", 2051 | "tracing-attributes", 2052 | "tracing-core", 2053 | ] 2054 | 2055 | [[package]] 2056 | name = "tracing-attributes" 2057 | version = "0.1.30" 2058 | source = "registry+https://github.com/rust-lang/crates.io-index" 2059 | checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" 2060 | dependencies = [ 2061 | "proc-macro2", 2062 | "quote", 2063 | "syn 2.0.104", 2064 | ] 2065 | 2066 | [[package]] 2067 | name = "tracing-core" 2068 | version = "0.1.34" 2069 | source = "registry+https://github.com/rust-lang/crates.io-index" 2070 | checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" 2071 | dependencies = [ 2072 | "once_cell", 2073 | ] 2074 | 2075 | [[package]] 2076 | name = "try-lock" 2077 | version = "0.2.5" 2078 | source = "registry+https://github.com/rust-lang/crates.io-index" 2079 | checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" 2080 | 2081 | [[package]] 2082 | name = "typenum" 2083 | version = "1.18.0" 2084 | source = "registry+https://github.com/rust-lang/crates.io-index" 2085 | checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" 2086 | 2087 | [[package]] 2088 | name = "uncased" 2089 | version = "0.9.10" 2090 | source = "registry+https://github.com/rust-lang/crates.io-index" 2091 | checksum = "e1b88fcfe09e89d3866a5c11019378088af2d24c3fbd4f0543f96b479ec90697" 2092 | dependencies = [ 2093 | "version_check", 2094 | ] 2095 | 2096 | [[package]] 2097 | name = "unicode-ident" 2098 | version = "1.0.18" 2099 | source = "registry+https://github.com/rust-lang/crates.io-index" 2100 | checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" 2101 | 2102 | [[package]] 2103 | name = "untrusted" 2104 | version = "0.9.0" 2105 | source = "registry+https://github.com/rust-lang/crates.io-index" 2106 | checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" 2107 | 2108 | [[package]] 2109 | name = "uuid" 2110 | version = "1.17.0" 2111 | source = "registry+https://github.com/rust-lang/crates.io-index" 2112 | checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d" 2113 | dependencies = [ 2114 | "getrandom 0.3.3", 2115 | "js-sys", 2116 | "serde", 2117 | "wasm-bindgen", 2118 | ] 2119 | 2120 | [[package]] 2121 | name = "version_check" 2122 | version = "0.9.5" 2123 | source = "registry+https://github.com/rust-lang/crates.io-index" 2124 | checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" 2125 | 2126 | [[package]] 2127 | name = "walkdir" 2128 | version = "2.5.0" 2129 | source = "registry+https://github.com/rust-lang/crates.io-index" 2130 | checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" 2131 | dependencies = [ 2132 | "same-file", 2133 | "winapi-util", 2134 | ] 2135 | 2136 | [[package]] 2137 | name = "want" 2138 | version = "0.3.1" 2139 | source = "registry+https://github.com/rust-lang/crates.io-index" 2140 | checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" 2141 | dependencies = [ 2142 | "try-lock", 2143 | ] 2144 | 2145 | [[package]] 2146 | name = "wasi" 2147 | version = "0.11.1+wasi-snapshot-preview1" 2148 | source = "registry+https://github.com/rust-lang/crates.io-index" 2149 | checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" 2150 | 2151 | [[package]] 2152 | name = "wasi" 2153 | version = "0.14.2+wasi-0.2.4" 2154 | source = "registry+https://github.com/rust-lang/crates.io-index" 2155 | checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" 2156 | dependencies = [ 2157 | "wit-bindgen-rt", 2158 | ] 2159 | 2160 | [[package]] 2161 | name = "wasm-bindgen" 2162 | version = "0.2.100" 2163 | source = "registry+https://github.com/rust-lang/crates.io-index" 2164 | checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" 2165 | dependencies = [ 2166 | "cfg-if", 2167 | "once_cell", 2168 | "rustversion", 2169 | "wasm-bindgen-macro", 2170 | ] 2171 | 2172 | [[package]] 2173 | name = "wasm-bindgen-backend" 2174 | version = "0.2.100" 2175 | source = "registry+https://github.com/rust-lang/crates.io-index" 2176 | checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" 2177 | dependencies = [ 2178 | "bumpalo", 2179 | "log", 2180 | "proc-macro2", 2181 | "quote", 2182 | "syn 2.0.104", 2183 | "wasm-bindgen-shared", 2184 | ] 2185 | 2186 | [[package]] 2187 | name = "wasm-bindgen-macro" 2188 | version = "0.2.100" 2189 | source = "registry+https://github.com/rust-lang/crates.io-index" 2190 | checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" 2191 | dependencies = [ 2192 | "quote", 2193 | "wasm-bindgen-macro-support", 2194 | ] 2195 | 2196 | [[package]] 2197 | name = "wasm-bindgen-macro-support" 2198 | version = "0.2.100" 2199 | source = "registry+https://github.com/rust-lang/crates.io-index" 2200 | checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" 2201 | dependencies = [ 2202 | "proc-macro2", 2203 | "quote", 2204 | "syn 2.0.104", 2205 | "wasm-bindgen-backend", 2206 | "wasm-bindgen-shared", 2207 | ] 2208 | 2209 | [[package]] 2210 | name = "wasm-bindgen-shared" 2211 | version = "0.2.100" 2212 | source = "registry+https://github.com/rust-lang/crates.io-index" 2213 | checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" 2214 | dependencies = [ 2215 | "unicode-ident", 2216 | ] 2217 | 2218 | [[package]] 2219 | name = "webpki-roots" 2220 | version = "0.26.11" 2221 | source = "registry+https://github.com/rust-lang/crates.io-index" 2222 | checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" 2223 | dependencies = [ 2224 | "webpki-roots 1.0.1", 2225 | ] 2226 | 2227 | [[package]] 2228 | name = "webpki-roots" 2229 | version = "1.0.1" 2230 | source = "registry+https://github.com/rust-lang/crates.io-index" 2231 | checksum = "8782dd5a41a24eed3a4f40b606249b3e236ca61adf1f25ea4d45c73de122b502" 2232 | dependencies = [ 2233 | "rustls-pki-types", 2234 | ] 2235 | 2236 | [[package]] 2237 | name = "which" 2238 | version = "4.4.2" 2239 | source = "registry+https://github.com/rust-lang/crates.io-index" 2240 | checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" 2241 | dependencies = [ 2242 | "either", 2243 | "home", 2244 | "once_cell", 2245 | "rustix 0.38.44", 2246 | ] 2247 | 2248 | [[package]] 2249 | name = "winapi-util" 2250 | version = "0.1.9" 2251 | source = "registry+https://github.com/rust-lang/crates.io-index" 2252 | checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" 2253 | dependencies = [ 2254 | "windows-sys 0.59.0", 2255 | ] 2256 | 2257 | [[package]] 2258 | name = "windows-core" 2259 | version = "0.61.2" 2260 | source = "registry+https://github.com/rust-lang/crates.io-index" 2261 | checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" 2262 | dependencies = [ 2263 | "windows-implement", 2264 | "windows-interface", 2265 | "windows-link", 2266 | "windows-result", 2267 | "windows-strings", 2268 | ] 2269 | 2270 | [[package]] 2271 | name = "windows-implement" 2272 | version = "0.60.0" 2273 | source = "registry+https://github.com/rust-lang/crates.io-index" 2274 | checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" 2275 | dependencies = [ 2276 | "proc-macro2", 2277 | "quote", 2278 | "syn 2.0.104", 2279 | ] 2280 | 2281 | [[package]] 2282 | name = "windows-interface" 2283 | version = "0.59.1" 2284 | source = "registry+https://github.com/rust-lang/crates.io-index" 2285 | checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" 2286 | dependencies = [ 2287 | "proc-macro2", 2288 | "quote", 2289 | "syn 2.0.104", 2290 | ] 2291 | 2292 | [[package]] 2293 | name = "windows-link" 2294 | version = "0.1.3" 2295 | source = "registry+https://github.com/rust-lang/crates.io-index" 2296 | checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" 2297 | 2298 | [[package]] 2299 | name = "windows-result" 2300 | version = "0.3.4" 2301 | source = "registry+https://github.com/rust-lang/crates.io-index" 2302 | checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" 2303 | dependencies = [ 2304 | "windows-link", 2305 | ] 2306 | 2307 | [[package]] 2308 | name = "windows-strings" 2309 | version = "0.4.2" 2310 | source = "registry+https://github.com/rust-lang/crates.io-index" 2311 | checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" 2312 | dependencies = [ 2313 | "windows-link", 2314 | ] 2315 | 2316 | [[package]] 2317 | name = "windows-sys" 2318 | version = "0.45.0" 2319 | source = "registry+https://github.com/rust-lang/crates.io-index" 2320 | checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" 2321 | dependencies = [ 2322 | "windows-targets 0.42.2", 2323 | ] 2324 | 2325 | [[package]] 2326 | name = "windows-sys" 2327 | version = "0.52.0" 2328 | source = "registry+https://github.com/rust-lang/crates.io-index" 2329 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 2330 | dependencies = [ 2331 | "windows-targets 0.52.6", 2332 | ] 2333 | 2334 | [[package]] 2335 | name = "windows-sys" 2336 | version = "0.59.0" 2337 | source = "registry+https://github.com/rust-lang/crates.io-index" 2338 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 2339 | dependencies = [ 2340 | "windows-targets 0.52.6", 2341 | ] 2342 | 2343 | [[package]] 2344 | name = "windows-sys" 2345 | version = "0.60.2" 2346 | source = "registry+https://github.com/rust-lang/crates.io-index" 2347 | checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" 2348 | dependencies = [ 2349 | "windows-targets 0.53.2", 2350 | ] 2351 | 2352 | [[package]] 2353 | name = "windows-targets" 2354 | version = "0.42.2" 2355 | source = "registry+https://github.com/rust-lang/crates.io-index" 2356 | checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" 2357 | dependencies = [ 2358 | "windows_aarch64_gnullvm 0.42.2", 2359 | "windows_aarch64_msvc 0.42.2", 2360 | "windows_i686_gnu 0.42.2", 2361 | "windows_i686_msvc 0.42.2", 2362 | "windows_x86_64_gnu 0.42.2", 2363 | "windows_x86_64_gnullvm 0.42.2", 2364 | "windows_x86_64_msvc 0.42.2", 2365 | ] 2366 | 2367 | [[package]] 2368 | name = "windows-targets" 2369 | version = "0.52.6" 2370 | source = "registry+https://github.com/rust-lang/crates.io-index" 2371 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 2372 | dependencies = [ 2373 | "windows_aarch64_gnullvm 0.52.6", 2374 | "windows_aarch64_msvc 0.52.6", 2375 | "windows_i686_gnu 0.52.6", 2376 | "windows_i686_gnullvm 0.52.6", 2377 | "windows_i686_msvc 0.52.6", 2378 | "windows_x86_64_gnu 0.52.6", 2379 | "windows_x86_64_gnullvm 0.52.6", 2380 | "windows_x86_64_msvc 0.52.6", 2381 | ] 2382 | 2383 | [[package]] 2384 | name = "windows-targets" 2385 | version = "0.53.2" 2386 | source = "registry+https://github.com/rust-lang/crates.io-index" 2387 | checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef" 2388 | dependencies = [ 2389 | "windows_aarch64_gnullvm 0.53.0", 2390 | "windows_aarch64_msvc 0.53.0", 2391 | "windows_i686_gnu 0.53.0", 2392 | "windows_i686_gnullvm 0.53.0", 2393 | "windows_i686_msvc 0.53.0", 2394 | "windows_x86_64_gnu 0.53.0", 2395 | "windows_x86_64_gnullvm 0.53.0", 2396 | "windows_x86_64_msvc 0.53.0", 2397 | ] 2398 | 2399 | [[package]] 2400 | name = "windows_aarch64_gnullvm" 2401 | version = "0.42.2" 2402 | source = "registry+https://github.com/rust-lang/crates.io-index" 2403 | checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" 2404 | 2405 | [[package]] 2406 | name = "windows_aarch64_gnullvm" 2407 | version = "0.52.6" 2408 | source = "registry+https://github.com/rust-lang/crates.io-index" 2409 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 2410 | 2411 | [[package]] 2412 | name = "windows_aarch64_gnullvm" 2413 | version = "0.53.0" 2414 | source = "registry+https://github.com/rust-lang/crates.io-index" 2415 | checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" 2416 | 2417 | [[package]] 2418 | name = "windows_aarch64_msvc" 2419 | version = "0.42.2" 2420 | source = "registry+https://github.com/rust-lang/crates.io-index" 2421 | checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" 2422 | 2423 | [[package]] 2424 | name = "windows_aarch64_msvc" 2425 | version = "0.52.6" 2426 | source = "registry+https://github.com/rust-lang/crates.io-index" 2427 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 2428 | 2429 | [[package]] 2430 | name = "windows_aarch64_msvc" 2431 | version = "0.53.0" 2432 | source = "registry+https://github.com/rust-lang/crates.io-index" 2433 | checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" 2434 | 2435 | [[package]] 2436 | name = "windows_i686_gnu" 2437 | version = "0.42.2" 2438 | source = "registry+https://github.com/rust-lang/crates.io-index" 2439 | checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" 2440 | 2441 | [[package]] 2442 | name = "windows_i686_gnu" 2443 | version = "0.52.6" 2444 | source = "registry+https://github.com/rust-lang/crates.io-index" 2445 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 2446 | 2447 | [[package]] 2448 | name = "windows_i686_gnu" 2449 | version = "0.53.0" 2450 | source = "registry+https://github.com/rust-lang/crates.io-index" 2451 | checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" 2452 | 2453 | [[package]] 2454 | name = "windows_i686_gnullvm" 2455 | version = "0.52.6" 2456 | source = "registry+https://github.com/rust-lang/crates.io-index" 2457 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 2458 | 2459 | [[package]] 2460 | name = "windows_i686_gnullvm" 2461 | version = "0.53.0" 2462 | source = "registry+https://github.com/rust-lang/crates.io-index" 2463 | checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" 2464 | 2465 | [[package]] 2466 | name = "windows_i686_msvc" 2467 | version = "0.42.2" 2468 | source = "registry+https://github.com/rust-lang/crates.io-index" 2469 | checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" 2470 | 2471 | [[package]] 2472 | name = "windows_i686_msvc" 2473 | version = "0.52.6" 2474 | source = "registry+https://github.com/rust-lang/crates.io-index" 2475 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 2476 | 2477 | [[package]] 2478 | name = "windows_i686_msvc" 2479 | version = "0.53.0" 2480 | source = "registry+https://github.com/rust-lang/crates.io-index" 2481 | checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" 2482 | 2483 | [[package]] 2484 | name = "windows_x86_64_gnu" 2485 | version = "0.42.2" 2486 | source = "registry+https://github.com/rust-lang/crates.io-index" 2487 | checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" 2488 | 2489 | [[package]] 2490 | name = "windows_x86_64_gnu" 2491 | version = "0.52.6" 2492 | source = "registry+https://github.com/rust-lang/crates.io-index" 2493 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 2494 | 2495 | [[package]] 2496 | name = "windows_x86_64_gnu" 2497 | version = "0.53.0" 2498 | source = "registry+https://github.com/rust-lang/crates.io-index" 2499 | checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" 2500 | 2501 | [[package]] 2502 | name = "windows_x86_64_gnullvm" 2503 | version = "0.42.2" 2504 | source = "registry+https://github.com/rust-lang/crates.io-index" 2505 | checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" 2506 | 2507 | [[package]] 2508 | name = "windows_x86_64_gnullvm" 2509 | version = "0.52.6" 2510 | source = "registry+https://github.com/rust-lang/crates.io-index" 2511 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 2512 | 2513 | [[package]] 2514 | name = "windows_x86_64_gnullvm" 2515 | version = "0.53.0" 2516 | source = "registry+https://github.com/rust-lang/crates.io-index" 2517 | checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" 2518 | 2519 | [[package]] 2520 | name = "windows_x86_64_msvc" 2521 | version = "0.42.2" 2522 | source = "registry+https://github.com/rust-lang/crates.io-index" 2523 | checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" 2524 | 2525 | [[package]] 2526 | name = "windows_x86_64_msvc" 2527 | version = "0.52.6" 2528 | source = "registry+https://github.com/rust-lang/crates.io-index" 2529 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 2530 | 2531 | [[package]] 2532 | name = "windows_x86_64_msvc" 2533 | version = "0.53.0" 2534 | source = "registry+https://github.com/rust-lang/crates.io-index" 2535 | checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" 2536 | 2537 | [[package]] 2538 | name = "wit-bindgen-rt" 2539 | version = "0.39.0" 2540 | source = "registry+https://github.com/rust-lang/crates.io-index" 2541 | checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" 2542 | dependencies = [ 2543 | "bitflags 2.9.1", 2544 | ] 2545 | 2546 | [[package]] 2547 | name = "zerocopy" 2548 | version = "0.7.35" 2549 | source = "registry+https://github.com/rust-lang/crates.io-index" 2550 | checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" 2551 | dependencies = [ 2552 | "byteorder", 2553 | "zerocopy-derive 0.7.35", 2554 | ] 2555 | 2556 | [[package]] 2557 | name = "zerocopy" 2558 | version = "0.8.26" 2559 | source = "registry+https://github.com/rust-lang/crates.io-index" 2560 | checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" 2561 | dependencies = [ 2562 | "zerocopy-derive 0.8.26", 2563 | ] 2564 | 2565 | [[package]] 2566 | name = "zerocopy-derive" 2567 | version = "0.7.35" 2568 | source = "registry+https://github.com/rust-lang/crates.io-index" 2569 | checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" 2570 | dependencies = [ 2571 | "proc-macro2", 2572 | "quote", 2573 | "syn 2.0.104", 2574 | ] 2575 | 2576 | [[package]] 2577 | name = "zerocopy-derive" 2578 | version = "0.8.26" 2579 | source = "registry+https://github.com/rust-lang/crates.io-index" 2580 | checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" 2581 | dependencies = [ 2582 | "proc-macro2", 2583 | "quote", 2584 | "syn 2.0.104", 2585 | ] 2586 | 2587 | [[package]] 2588 | name = "zeroize" 2589 | version = "1.8.1" 2590 | source = "registry+https://github.com/rust-lang/crates.io-index" 2591 | checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" 2592 | --------------------------------------------------------------------------------