diff --git a/.flutter-plugins-dependencies b/.flutter-plugins-dependencies
new file mode 100644
index 00000000..dbd1c10d
--- /dev/null
+++ b/.flutter-plugins-dependencies
@@ -0,0 +1 @@
+{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"path_provider_foundation","path":"/home/icota/.pub-cache/hosted/pub.dev/path_provider_foundation-2.5.1/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"rust_lib_tor","path":"/home/icota/Code/tor/rust_builder/","native_build":true,"dependencies":[],"dev_dependency":false}],"android":[{"name":"path_provider_android","path":"/home/icota/.pub-cache/hosted/pub.dev/path_provider_android-2.2.22/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"rust_lib_tor","path":"/home/icota/Code/tor/rust_builder/","native_build":true,"dependencies":[],"dev_dependency":false}],"macos":[{"name":"path_provider_foundation","path":"/home/icota/.pub-cache/hosted/pub.dev/path_provider_foundation-2.5.1/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"rust_lib_tor","path":"/home/icota/Code/tor/rust_builder/","native_build":true,"dependencies":[],"dev_dependency":false}],"linux":[{"name":"path_provider_linux","path":"/home/icota/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"rust_lib_tor","path":"/home/icota/Code/tor/rust_builder/","native_build":true,"dependencies":[],"dev_dependency":false}],"windows":[{"name":"path_provider_windows","path":"/home/icota/.pub-cache/hosted/pub.dev/path_provider_windows-2.3.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"rust_lib_tor","path":"/home/icota/Code/tor/rust_builder/","native_build":true,"dependencies":[],"dev_dependency":false}],"web":[]},"dependencyGraph":[{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"rust_lib_tor","dependencies":[]}],"date_created":"2026-02-19 09:24:05.451601","version":"3.35.7","swift_package_manager_enabled":{"ios":false,"macos":false}}
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 7f1056d3..0a3097f0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,4 +34,7 @@ migrate_working_dir/
build/
rust/target/.rustc_info.json
-rust/target/debug
\ No newline at end of file
+rust/target/debug
+
+# direnv
+.direnv/
diff --git a/.reuse/dep5 b/.reuse/dep5
index e3101a54..86caaa07 100644
--- a/.reuse/dep5
+++ b/.reuse/dep5
@@ -11,6 +11,18 @@ Files: lib/generated*
Copyright: 2024 Foundation Devices Inc.
License: MIT
+Files: lib/src/rust/*
+Copyright: 2024 Foundation Devices Inc.
+License: MIT
+
+Files: rust/src/frb_generated.rs
+Copyright: 2024 Foundation Devices Inc.
+License: MIT
+
+Files: .flutter-plugins-dependencies
+Copyright: 2024 Foundation Devices Inc.
+License: MIT
+
Files: example/linux/flutter/generated*
Copyright: 2024 Foundation Devices Inc.
License: MIT
@@ -38,3 +50,7 @@ License: MIT
Files: flake.lock
Copyright: 2024 Foundation Devices Inc.
License: MIT
+
+Files: android/.gradle/*
+Copyright: 2024 Foundation Devices Inc.
+License: MIT
diff --git a/analysis_options.yaml b/analysis_options.yaml
index 193ecf6c..8db9afb3 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -8,4 +8,5 @@ include: package:flutter_lints/flutter.yaml
analyzer:
exclude:
- 'lib/generated*'
- - 'cargokit'
\ No newline at end of file
+ - 'lib/src/rust/**'
+ - 'cargokit/**'
\ No newline at end of file
diff --git a/android/.gitignore b/android/.gitignore
index a499193d..52d44cbf 100644
--- a/android/.gitignore
+++ b/android/.gitignore
@@ -1,4 +1,4 @@
-# SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
+# SPDX-FileCopyrightText: 2024 Foundation Devices Inc
#
# SPDX-License-Identifier: MIT
diff --git a/android/build.gradle b/android/build.gradle
index 0ca96f2c..c9274070 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -4,7 +4,7 @@
// The Android Gradle Plugin builds the native code with the Android NDK.
-group 'com.foundationdevices.tor'
+group 'com.flutter_rust_bridge.rust_lib_tor'
version '1.0'
buildscript {
@@ -15,7 +15,7 @@ buildscript {
dependencies {
// The Android Gradle Plugin knows how to build native code with the NDK.
- classpath 'com.android.tools.build:gradle:8.12.1'
+ classpath 'com.android.tools.build:gradle:7.3.0'
}
}
@@ -30,11 +30,18 @@ apply plugin: 'com.android.library'
android {
if (project.android.hasProperty("namespace")) {
- namespace 'com.foundationdevices.tor'
+ namespace 'com.flutter_rust_bridge.rust_lib_tor'
}
+
// Bumping the plugin compileSdkVersion requires all clients of this plugin
// to bump the version in their app.
- compileSdkVersion 36
+ compileSdkVersion 33
+
+ // Use the NDK version
+ // declared in /android/app/build.gradle file of the Flutter project.
+ // Replace it with a version number if this plugin requires a specfic NDK version.
+ // (e.g. ndkVersion "23.1.7779620")
+ ndkVersion android.ndkVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
@@ -42,13 +49,12 @@ android {
}
defaultConfig {
- minSdkVersion 16
+ minSdkVersion 19
}
}
apply from: "../cargokit/gradle/plugin.gradle"
-
cargokit {
manifestDir = "../rust"
- libname = "tor"
-}
\ No newline at end of file
+ libname = "rust_lib_tor"
+}
diff --git a/android/settings.gradle b/android/settings.gradle
index 44ad3e46..69e2430f 100644
--- a/android/settings.gradle
+++ b/android/settings.gradle
@@ -1,5 +1,5 @@
-// SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
+// SPDX-FileCopyrightText: 2024 Foundation Devices Inc
//
// SPDX-License-Identifier: MIT
-rootProject.name = 'tor'
+rootProject.name = 'rust_lib_backup'
diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml
index db722d2e..a04fa5ba 100644
--- a/android/src/main/AndroidManifest.xml
+++ b/android/src/main/AndroidManifest.xml
@@ -1,9 +1,9 @@
+ package="com.flutter_rust_bridge.rust_lib_backup">
diff --git a/cargokit/.github/workflows/check_and_lint.yml b/cargokit/.github/workflows/check_and_lint.yml
deleted file mode 100644
index 70ba64e3..00000000
--- a/cargokit/.github/workflows/check_and_lint.yml
+++ /dev/null
@@ -1,30 +0,0 @@
-# SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-#
-# SPDX-License-Identifier: MIT
-
-on:
- pull_request:
- push:
- branches:
- - main
-
-name: Check and Lint
-
-jobs:
- Flutter:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v2
- - uses: dart-lang/setup-dart@v1
- - name: Pub Get
- run: dart pub get --no-precompile
- working-directory: build_tool
- - name: Dart Format
- run: dart format . --output=none --set-exit-if-changed
- working-directory: build_tool
- - name: Analyze
- run: dart analyze
- working-directory: build_tool
- - name: Test
- run: dart test
- working-directory: build_tool
diff --git a/cargokit/.github/workflows/test_example_plugin_build.yml b/cargokit/.github/workflows/test_example_plugin_build.yml
deleted file mode 100644
index 9c7ad253..00000000
--- a/cargokit/.github/workflows/test_example_plugin_build.yml
+++ /dev/null
@@ -1,86 +0,0 @@
-# SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-#
-# SPDX-License-Identifier: MIT
-
-on:
- pull_request:
- push:
- branches:
- - main
-
-name: Test Example Plugin
-
-jobs:
- Build:
- runs-on: ${{ matrix.os }}
- strategy:
- fail-fast: false
- matrix:
- os:
- - ubuntu-latest
- - macOS-latest
- - windows-latest
- build_mode:
- - debug
- - profile
- - release
- env:
- EXAMPLE_DIR: "a b/hello_rust_ffi_plugin/example"
- CARGOKIT_VERBOSE: 1
- steps:
- - name: Extract branch name
- shell: bash
- run: echo "branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_OUTPUT
- id: extract_branch
- - name: Setup Repository
- shell: bash
- run: |
- mkdir "a b" # Space is intentional
- cd "a b"
- git config --global user.email "you@example.com"
- git config --global user.name "Your Name"
- # "advanced" branch has extra iOS flavor and uses rust nightly for release builds
- git clone -b advanced https://github.com/irondash/hello_rust_ffi_plugin
- cd hello_rust_ffi_plugin
- git subtree pull --prefix cargokit https://github.com/irondash/cargokit.git ${{ steps.extract_branch.outputs.branch }} --squash
- - uses: subosito/flutter-action@v1
- with:
- channel: "stable"
- - name: Install GTK
- if: (matrix.os == 'ubuntu-latest')
- run: sudo apt-get update && sudo apt-get install libgtk-3-dev
- - name: Install ninja-build
- if: (matrix.os == 'ubuntu-latest')
- run: sudo apt-get update && sudo apt-get install ninja-build
- - name: Build Linux (${{ matrix.build_mode }})
- if: matrix.os == 'ubuntu-latest'
- shell: bash
- working-directory: ${{ env.EXAMPLE_DIR }}
- run: flutter build linux --${{ matrix.build_mode }} -v
- - name: Build macOS (${{ matrix.build_mode }})
- if: matrix.os == 'macos-latest'
- shell: bash
- working-directory: ${{ env.EXAMPLE_DIR }}
- run: flutter build macos --${{ matrix.build_mode }} -v
- - name: Build iOS (${{ matrix.build_mode }})
- if: matrix.os == 'macos-latest'
- shell: bash
- working-directory: ${{ env.EXAMPLE_DIR }}
- run: flutter build ios --${{ matrix.build_mode }} --no-codesign -v
- - name: Build iOS (${{ matrix.build_mode }}) - flavor1
- if: matrix.os == 'macos-latest'
- shell: bash
- working-directory: ${{ env.EXAMPLE_DIR }}
- run: flutter build ios --flavor flavor1 --${{ matrix.build_mode }} --no-codesign -v
- - name: Build Windows (${{ matrix.build_mode }})
- if: matrix.os == 'windows-latest'
- shell: bash
- working-directory: ${{ env.EXAMPLE_DIR }}
- run: flutter build windows --${{ matrix.build_mode }} -v
- - name: Build Android (${{ matrix.build_mode }})
- shell: bash
- working-directory: ${{ env.EXAMPLE_DIR }}
- run: |
- export JAVA_HOME=$JAVA_HOME_11_X64
- flutter build apk --${{ matrix.build_mode }} -v
-
diff --git a/cargokit/.gitignore b/cargokit/.gitignore
index 7930d72e..cf7bb868 100644
--- a/cargokit/.gitignore
+++ b/cargokit/.gitignore
@@ -1,7 +1,3 @@
-# SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-#
-# SPDX-License-Identifier: MIT
-
target
.dart_tool
*.iml
diff --git a/cargokit/LICENSE b/cargokit/LICENSE
index 54a7d589..d33a5fea 100644
--- a/cargokit/LICENSE
+++ b/cargokit/LICENSE
@@ -1,3 +1,6 @@
+/// This is copied from Cargokit (which is the official way to use it currently)
+/// Details: https://fzyzcjy.github.io/flutter_rust_bridge/manual/integrate/builtin
+
Copyright 2022 Matej Knopp
================================================================================
diff --git a/cargokit/README b/cargokit/README
index 8ae4a073..398474db 100644
--- a/cargokit/README
+++ b/cargokit/README
@@ -1,3 +1,6 @@
+/// This is copied from Cargokit (which is the official way to use it currently)
+/// Details: https://fzyzcjy.github.io/flutter_rust_bridge/manual/integrate/builtin
+
Experimental repository to provide glue for seamlessly integrating cargo build
with flutter plugins and packages.
diff --git a/cargokit/README.license b/cargokit/README.license
deleted file mode 100644
index 7b44746f..00000000
--- a/cargokit/README.license
+++ /dev/null
@@ -1,3 +0,0 @@
-SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-
-SPDX-License-Identifier: MIT
diff --git a/cargokit/build_pod.sh b/cargokit/build_pod.sh
index b826ee9e..ed0e0d98 100755
--- a/cargokit/build_pod.sh
+++ b/cargokit/build_pod.sh
@@ -1,9 +1,4 @@
#!/bin/sh
-
-# SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-#
-# SPDX-License-Identifier: MIT
-
set -e
BASEDIR=$(dirname "$0")
@@ -54,10 +49,10 @@ do
fi
done
-"$BASEDIR/run_build_tool.sh" build-pod "$@"
+sh "$BASEDIR/run_build_tool.sh" build-pod "$@"
# Make a symlink from built framework to phony file, which will be used as input to
# build script. This should force rebuild (podspec currently doesn't support alwaysOutOfDate
# attribute on custom build phase)
-ln -Fs "$OBJROOT/XCBuildData/build.db" "${BUILT_PRODUCTS_DIR}/cargokit_phony"
-ln -Fs "${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}" "${BUILT_PRODUCTS_DIR}/cargokit_phony_out"
+ln -fs "$OBJROOT/XCBuildData/build.db" "${BUILT_PRODUCTS_DIR}/cargokit_phony"
+ln -fs "${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}" "${BUILT_PRODUCTS_DIR}/cargokit_phony_out"
diff --git a/cargokit/build_tool/README.md b/cargokit/build_tool/README.md
index b81c9700..a878c279 100644
--- a/cargokit/build_tool/README.md
+++ b/cargokit/build_tool/README.md
@@ -1,8 +1,5 @@
-
+/// This is copied from Cargokit (which is the official way to use it currently)
+/// Details: https://fzyzcjy.github.io/flutter_rust_bridge/manual/integrate/builtin
A sample command-line application with an entrypoint in `bin/`, library code
in `lib/`, and example unit test in `test/`.
diff --git a/cargokit/build_tool/analysis_options.yaml b/cargokit/build_tool/analysis_options.yaml
index d5ed3547..0e16a8b0 100644
--- a/cargokit/build_tool/analysis_options.yaml
+++ b/cargokit/build_tool/analysis_options.yaml
@@ -1,6 +1,5 @@
-# SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-#
-# SPDX-License-Identifier: MIT
+# This is copied from Cargokit (which is the official way to use it currently)
+# Details: https://fzyzcjy.github.io/flutter_rust_bridge/manual/integrate/builtin
# This file configures the static analysis results for your project (errors,
# warnings, and lints).
diff --git a/cargokit/build_tool/bin/build_tool.dart b/cargokit/build_tool/bin/build_tool.dart
index f2879eeb..268eb524 100644
--- a/cargokit/build_tool/bin/build_tool.dart
+++ b/cargokit/build_tool/bin/build_tool.dart
@@ -1,6 +1,5 @@
-// SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-//
-// SPDX-License-Identifier: MIT
+/// This is copied from Cargokit (which is the official way to use it currently)
+/// Details: https://fzyzcjy.github.io/flutter_rust_bridge/manual/integrate/builtin
import 'package:build_tool/build_tool.dart' as build_tool;
diff --git a/cargokit/build_tool/lib/build_tool.dart b/cargokit/build_tool/lib/build_tool.dart
index b0e25c9f..7c1bb750 100644
--- a/cargokit/build_tool/lib/build_tool.dart
+++ b/cargokit/build_tool/lib/build_tool.dart
@@ -1,6 +1,5 @@
-// SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-//
-// SPDX-License-Identifier: MIT
+/// This is copied from Cargokit (which is the official way to use it currently)
+/// Details: https://fzyzcjy.github.io/flutter_rust_bridge/manual/integrate/builtin
import 'src/build_tool.dart' as build_tool;
diff --git a/cargokit/build_tool/lib/src/android_environment.dart b/cargokit/build_tool/lib/src/android_environment.dart
index 32ae61a6..15fc9eed 100644
--- a/cargokit/build_tool/lib/src/android_environment.dart
+++ b/cargokit/build_tool/lib/src/android_environment.dart
@@ -1,6 +1,5 @@
-// SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-//
-// SPDX-License-Identifier: MIT
+/// This is copied from Cargokit (which is the official way to use it currently)
+/// Details: https://fzyzcjy.github.io/flutter_rust_bridge/manual/integrate/builtin
import 'dart:io';
import 'dart:isolate';
@@ -119,7 +118,7 @@ class AndroidEnvironment {
final cxxKey = 'CXX_${target.rust}';
final cxxValue = path.join(toolchainPath, 'clang++$exe');
- final cxxfFlagsKey = 'CXXFLAGS_${target.rust}';
+ final cxxFlagsKey = 'CXXFLAGS_${target.rust}';
final cxxFlagsValue = targetArg;
final linkerKey =
@@ -156,7 +155,7 @@ class AndroidEnvironment {
ccKey: ccValue,
cfFlagsKey: cFlagsValue,
cxxKey: cxxValue,
- cxxfFlagsKey: cxxFlagsValue,
+ cxxFlagsKey: cxxFlagsValue,
ranlibKey: ranlibValue,
rustFlagsKey: rustFlagsValue,
linkerKey: selfPath,
@@ -190,17 +189,7 @@ class AndroidEnvironment {
if (rustFlags.isNotEmpty) {
rustFlags = '$rustFlags\x1f';
}
- rustFlags = '$rustFlags-L\x1f$workaroundDir\x1f';
-
- const pageSizeArgs = [
- "-C",
- "link-arg=-Wl,--hash-style=both",
- "-C",
- "link-arg=-Wl,-z,max-page-size=16384"
- ];
- final pageSizeArgsString = pageSizeArgs.join("\x1f");
-
- rustFlags = '$rustFlags$pageSizeArgsString';
+ rustFlags = '$rustFlags-L\x1f$workaroundDir';
return rustFlags;
}
}
diff --git a/cargokit/build_tool/lib/src/artifacts_provider.dart b/cargokit/build_tool/lib/src/artifacts_provider.dart
index 6a24f209..e608cece 100644
--- a/cargokit/build_tool/lib/src/artifacts_provider.dart
+++ b/cargokit/build_tool/lib/src/artifacts_provider.dart
@@ -1,6 +1,5 @@
-// SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-//
-// SPDX-License-Identifier: MIT
+/// This is copied from Cargokit (which is the official way to use it currently)
+/// Details: https://fzyzcjy.github.io/flutter_rust_bridge/manual/integrate/builtin
import 'dart:io';
@@ -161,6 +160,27 @@ class ArtifactProvider {
return res;
}
+ static Future _get(Uri url, {Map? headers}) async {
+ int attempt = 0;
+ const maxAttempts = 10;
+ while (true) {
+ try {
+ return await get(url, headers: headers);
+ } on SocketException catch (e) {
+ // Try to detect reset by peer error and retry.
+ if (attempt++ < maxAttempts &&
+ (e.osError?.errorCode == 54 || e.osError?.errorCode == 10054)) {
+ _log.severe(
+ 'Failed to download $url: $e, attempt $attempt of $maxAttempts, will retry...');
+ await Future.delayed(Duration(seconds: 1));
+ continue;
+ } else {
+ rethrow;
+ }
+ }
+ }
+ }
+
Future _tryDownloadArtifacts({
required String crateHash,
required String fileName,
@@ -171,11 +191,11 @@ class ArtifactProvider {
final prefix = precompiledBinaries.uriPrefix;
final url = Uri.parse('$prefix$crateHash/$fileName');
final signatureUrl = Uri.parse('$prefix$crateHash/$signatureFileName');
- final signature = await get(signatureUrl);
_log.fine('Downloading signature from $signatureUrl');
+ final signature = await _get(signatureUrl);
if (signature.statusCode == 404) {
_log.warning(
- 'Precompiled binaries for available for crate hash $crateHash');
+ 'Precompiled binaries not available for crate hash $crateHash ($fileName)');
return;
}
if (signature.statusCode != 200) {
@@ -184,7 +204,7 @@ class ArtifactProvider {
return;
}
_log.fine('Downloading binary from $url');
- final res = await get(url);
+ final res = await _get(url);
if (res.statusCode != 200) {
_log.severe('Failed to download binary $url: status ${res.statusCode}');
return;
diff --git a/cargokit/build_tool/lib/src/build_cmake.dart b/cargokit/build_tool/lib/src/build_cmake.dart
index b9a96bc0..6f3b2a4e 100644
--- a/cargokit/build_tool/lib/src/build_cmake.dart
+++ b/cargokit/build_tool/lib/src/build_cmake.dart
@@ -1,6 +1,5 @@
-// SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-//
-// SPDX-License-Identifier: MIT
+/// This is copied from Cargokit (which is the official way to use it currently)
+/// Details: https://fzyzcjy.github.io/flutter_rust_bridge/manual/integrate/builtin
import 'dart:io';
diff --git a/cargokit/build_tool/lib/src/build_gradle.dart b/cargokit/build_tool/lib/src/build_gradle.dart
index 4a9419de..7e61fcbb 100644
--- a/cargokit/build_tool/lib/src/build_gradle.dart
+++ b/cargokit/build_tool/lib/src/build_gradle.dart
@@ -1,6 +1,5 @@
-// SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-//
-// SPDX-License-Identifier: MIT
+/// This is copied from Cargokit (which is the official way to use it currently)
+/// Details: https://fzyzcjy.github.io/flutter_rust_bridge/manual/integrate/builtin
import 'dart:io';
diff --git a/cargokit/build_tool/lib/src/build_pod.dart b/cargokit/build_tool/lib/src/build_pod.dart
index 7da04ab7..8a9c0db5 100644
--- a/cargokit/build_tool/lib/src/build_pod.dart
+++ b/cargokit/build_tool/lib/src/build_pod.dart
@@ -1,6 +1,5 @@
-// SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-//
-// SPDX-License-Identifier: MIT
+/// This is copied from Cargokit (which is the official way to use it currently)
+/// Details: https://fzyzcjy.github.io/flutter_rust_bridge/manual/integrate/builtin
import 'dart:io';
diff --git a/cargokit/build_tool/lib/src/build_tool.dart b/cargokit/build_tool/lib/src/build_tool.dart
index 79a7515c..c8f36981 100644
--- a/cargokit/build_tool/lib/src/build_tool.dart
+++ b/cargokit/build_tool/lib/src/build_tool.dart
@@ -1,6 +1,5 @@
-// SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-//
-// SPDX-License-Identifier: MIT
+/// This is copied from Cargokit (which is the official way to use it currently)
+/// Details: https://fzyzcjy.github.io/flutter_rust_bridge/manual/integrate/builtin
import 'dart:io';
diff --git a/cargokit/build_tool/lib/src/builder.dart b/cargokit/build_tool/lib/src/builder.dart
index 18b6663e..84c46e4f 100644
--- a/cargokit/build_tool/lib/src/builder.dart
+++ b/cargokit/build_tool/lib/src/builder.dart
@@ -1,6 +1,5 @@
-// SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-//
-// SPDX-License-Identifier: MIT
+/// This is copied from Cargokit (which is the official way to use it currently)
+/// Details: https://fzyzcjy.github.io/flutter_rust_bridge/manual/integrate/builtin
import 'package:collection/collection.dart';
import 'package:logging/logging.dart';
diff --git a/cargokit/build_tool/lib/src/cargo.dart b/cargokit/build_tool/lib/src/cargo.dart
index 8b882b20..0d8958ff 100644
--- a/cargokit/build_tool/lib/src/cargo.dart
+++ b/cargokit/build_tool/lib/src/cargo.dart
@@ -1,6 +1,5 @@
-// SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-//
-// SPDX-License-Identifier: MIT
+/// This is copied from Cargokit (which is the official way to use it currently)
+/// Details: https://fzyzcjy.github.io/flutter_rust_bridge/manual/integrate/builtin
import 'dart:io';
diff --git a/cargokit/build_tool/lib/src/crate_hash.dart b/cargokit/build_tool/lib/src/crate_hash.dart
index 088e2e95..0c4d88d1 100644
--- a/cargokit/build_tool/lib/src/crate_hash.dart
+++ b/cargokit/build_tool/lib/src/crate_hash.dart
@@ -1,6 +1,5 @@
-// SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-//
-// SPDX-License-Identifier: MIT
+/// This is copied from Cargokit (which is the official way to use it currently)
+/// Details: https://fzyzcjy.github.io/flutter_rust_bridge/manual/integrate/builtin
import 'dart:convert';
import 'dart:io';
diff --git a/cargokit/build_tool/lib/src/environment.dart b/cargokit/build_tool/lib/src/environment.dart
index 48867f93..996483a1 100644
--- a/cargokit/build_tool/lib/src/environment.dart
+++ b/cargokit/build_tool/lib/src/environment.dart
@@ -1,6 +1,5 @@
-// SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-//
-// SPDX-License-Identifier: MIT
+/// This is copied from Cargokit (which is the official way to use it currently)
+/// Details: https://fzyzcjy.github.io/flutter_rust_bridge/manual/integrate/builtin
import 'dart:io';
diff --git a/cargokit/build_tool/lib/src/logging.dart b/cargokit/build_tool/lib/src/logging.dart
index b7031f69..5edd4fd1 100644
--- a/cargokit/build_tool/lib/src/logging.dart
+++ b/cargokit/build_tool/lib/src/logging.dart
@@ -1,6 +1,5 @@
-// SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-//
-// SPDX-License-Identifier: MIT
+/// This is copied from Cargokit (which is the official way to use it currently)
+/// Details: https://fzyzcjy.github.io/flutter_rust_bridge/manual/integrate/builtin
import 'dart:io';
diff --git a/cargokit/build_tool/lib/src/options.dart b/cargokit/build_tool/lib/src/options.dart
index f152a115..22aef1d3 100644
--- a/cargokit/build_tool/lib/src/options.dart
+++ b/cargokit/build_tool/lib/src/options.dart
@@ -1,6 +1,5 @@
-// SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-//
-// SPDX-License-Identifier: MIT
+/// This is copied from Cargokit (which is the official way to use it currently)
+/// Details: https://fzyzcjy.github.io/flutter_rust_bridge/manual/integrate/builtin
import 'dart:io';
diff --git a/cargokit/build_tool/lib/src/precompile_binaries.dart b/cargokit/build_tool/lib/src/precompile_binaries.dart
index 9ca5b9cd..c27f4195 100644
--- a/cargokit/build_tool/lib/src/precompile_binaries.dart
+++ b/cargokit/build_tool/lib/src/precompile_binaries.dart
@@ -1,6 +1,5 @@
-// SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-//
-// SPDX-License-Identifier: MIT
+/// This is copied from Cargokit (which is the official way to use it currently)
+/// Details: https://fzyzcjy.github.io/flutter_rust_bridge/manual/integrate/builtin
import 'dart:io';
diff --git a/cargokit/build_tool/lib/src/rustup.dart b/cargokit/build_tool/lib/src/rustup.dart
index 955d1d33..0ac8d086 100644
--- a/cargokit/build_tool/lib/src/rustup.dart
+++ b/cargokit/build_tool/lib/src/rustup.dart
@@ -1,6 +1,5 @@
-// SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-//
-// SPDX-License-Identifier: MIT
+/// This is copied from Cargokit (which is the official way to use it currently)
+/// Details: https://fzyzcjy.github.io/flutter_rust_bridge/manual/integrate/builtin
import 'dart:io';
@@ -64,10 +63,14 @@ class Rustup {
}
final res = runCommand("rustup", ['toolchain', 'list']);
+
+ // To list all non-custom toolchains, we need to filter out lines that
+ // don't start with "stable", "beta", or "nightly".
+ Pattern nonCustom = RegExp(r"^(stable|beta|nightly)");
final lines = res.stdout
.toString()
.split('\n')
- .where((e) => e.isNotEmpty)
+ .where((e) => e.isNotEmpty && e.startsWith(nonCustom))
.map(extractToolchainName)
.toList(growable: true);
diff --git a/cargokit/build_tool/lib/src/target.dart b/cargokit/build_tool/lib/src/target.dart
index 4dda2dc1..6fbc58b6 100644
--- a/cargokit/build_tool/lib/src/target.dart
+++ b/cargokit/build_tool/lib/src/target.dart
@@ -1,6 +1,5 @@
-// SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-//
-// SPDX-License-Identifier: MIT
+/// This is copied from Cargokit (which is the official way to use it currently)
+/// Details: https://fzyzcjy.github.io/flutter_rust_bridge/manual/integrate/builtin
import 'dart:io';
diff --git a/cargokit/build_tool/lib/src/util.dart b/cargokit/build_tool/lib/src/util.dart
index db42adf6..8bb6a872 100644
--- a/cargokit/build_tool/lib/src/util.dart
+++ b/cargokit/build_tool/lib/src/util.dart
@@ -1,6 +1,5 @@
-// SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-//
-// SPDX-License-Identifier: MIT
+/// This is copied from Cargokit (which is the official way to use it currently)
+/// Details: https://fzyzcjy.github.io/flutter_rust_bridge/manual/integrate/builtin
import 'dart:convert';
import 'dart:io';
@@ -41,6 +40,44 @@ class CommandFailedException implements Exception {
}
}
+class TestRunCommandArgs {
+ final String executable;
+ final List arguments;
+ final String? workingDirectory;
+ final Map? environment;
+ final bool includeParentEnvironment;
+ final bool runInShell;
+ final Encoding? stdoutEncoding;
+ final Encoding? stderrEncoding;
+
+ TestRunCommandArgs({
+ required this.executable,
+ required this.arguments,
+ this.workingDirectory,
+ this.environment,
+ this.includeParentEnvironment = true,
+ this.runInShell = false,
+ this.stdoutEncoding,
+ this.stderrEncoding,
+ });
+}
+
+class TestRunCommandResult {
+ TestRunCommandResult({
+ this.pid = 1,
+ this.exitCode = 0,
+ this.stdout = '',
+ this.stderr = '',
+ });
+
+ final int pid;
+ final int exitCode;
+ final String stdout;
+ final String stderr;
+}
+
+TestRunCommandResult Function(TestRunCommandArgs args)? testRunCommandOverride;
+
ProcessResult runCommand(
String executable,
List arguments, {
@@ -51,6 +88,24 @@ ProcessResult runCommand(
Encoding? stdoutEncoding = systemEncoding,
Encoding? stderrEncoding = systemEncoding,
}) {
+ if (testRunCommandOverride != null) {
+ final result = testRunCommandOverride!(TestRunCommandArgs(
+ executable: executable,
+ arguments: arguments,
+ workingDirectory: workingDirectory,
+ environment: environment,
+ includeParentEnvironment: includeParentEnvironment,
+ runInShell: runInShell,
+ stdoutEncoding: stdoutEncoding,
+ stderrEncoding: stderrEncoding,
+ ));
+ return ProcessResult(
+ result.pid,
+ result.exitCode,
+ result.stdout,
+ result.stderr,
+ );
+ }
log.finer('Running command $executable ${arguments.join(' ')}');
final res = Process.runSync(
_resolveExecutable(executable),
diff --git a/cargokit/build_tool/lib/src/verify_binaries.dart b/cargokit/build_tool/lib/src/verify_binaries.dart
index 7bb71a07..2366b57b 100644
--- a/cargokit/build_tool/lib/src/verify_binaries.dart
+++ b/cargokit/build_tool/lib/src/verify_binaries.dart
@@ -1,6 +1,5 @@
-// SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-//
-// SPDX-License-Identifier: MIT
+/// This is copied from Cargokit (which is the official way to use it currently)
+/// Details: https://fzyzcjy.github.io/flutter_rust_bridge/manual/integrate/builtin
import 'dart:io';
diff --git a/cargokit/build_tool/pubspec.lock.license b/cargokit/build_tool/pubspec.lock.license
deleted file mode 100644
index 7b44746f..00000000
--- a/cargokit/build_tool/pubspec.lock.license
+++ /dev/null
@@ -1,3 +0,0 @@
-SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-
-SPDX-License-Identifier: MIT
diff --git a/cargokit/build_tool/pubspec.yaml b/cargokit/build_tool/pubspec.yaml
index 973154a4..18c61e33 100644
--- a/cargokit/build_tool/pubspec.yaml
+++ b/cargokit/build_tool/pubspec.yaml
@@ -1,6 +1,5 @@
-# SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-#
-# SPDX-License-Identifier: MIT
+# This is copied from Cargokit (which is the official way to use it currently)
+# Details: https://fzyzcjy.github.io/flutter_rust_bridge/manual/integrate/builtin
name: build_tool
description: Cargokit build_tool. Facilitates the build of Rust crate during Flutter application build.
diff --git a/cargokit/build_tool/test/builder_test.dart b/cargokit/build_tool/test/builder_test.dart
deleted file mode 100644
index b10b8e30..00000000
--- a/cargokit/build_tool/test/builder_test.dart
+++ /dev/null
@@ -1,32 +0,0 @@
-// SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-//
-// SPDX-License-Identifier: MIT
-
-import 'package:build_tool/src/builder.dart';
-import 'package:test/test.dart';
-
-void main() {
- test('parseBuildConfiguration', () {
- var b = BuildEnvironment.parseBuildConfiguration('debug');
- expect(b, BuildConfiguration.debug);
-
- b = BuildEnvironment.parseBuildConfiguration('profile');
- expect(b, BuildConfiguration.profile);
-
- b = BuildEnvironment.parseBuildConfiguration('release');
- expect(b, BuildConfiguration.release);
-
- b = BuildEnvironment.parseBuildConfiguration('debug-dev');
- expect(b, BuildConfiguration.debug);
-
- b = BuildEnvironment.parseBuildConfiguration('profile');
- expect(b, BuildConfiguration.profile);
-
- b = BuildEnvironment.parseBuildConfiguration('profile-prod');
- expect(b, BuildConfiguration.profile);
-
- // fallback to release
- b = BuildEnvironment.parseBuildConfiguration('unknown');
- expect(b, BuildConfiguration.release);
- });
-}
diff --git a/cargokit/build_tool/test/cargo_test.dart b/cargokit/build_tool/test/cargo_test.dart
deleted file mode 100644
index 623fb4b8..00000000
--- a/cargokit/build_tool/test/cargo_test.dart
+++ /dev/null
@@ -1,32 +0,0 @@
-// SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-//
-// SPDX-License-Identifier: MIT
-
-import 'package:build_tool/src/cargo.dart';
-import 'package:test/test.dart';
-
-final _cargoToml = """
-[workspace]
-
-[profile.release]
-lto = true
-panic = "abort"
-opt-level = "z"
-# strip = "symbols"
-
-[package]
-name = "super_native_extensions"
-version = "0.1.0"
-edition = "2021"
-resolver = "2"
-
-[lib]
-crate-type = ["cdylib", "staticlib"]
-""";
-
-void main() {
- test('parseCargoToml', () {
- final info = CrateInfo.parseManifest(_cargoToml);
- expect(info.packageName, 'super_native_extensions');
- });
-}
diff --git a/cargokit/build_tool/test/options_test.dart b/cargokit/build_tool/test/options_test.dart
deleted file mode 100644
index c91db771..00000000
--- a/cargokit/build_tool/test/options_test.dart
+++ /dev/null
@@ -1,79 +0,0 @@
-// SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-//
-// SPDX-License-Identifier: MIT
-
-import 'package:build_tool/src/builder.dart';
-import 'package:build_tool/src/options.dart';
-import 'package:hex/hex.dart';
-import 'package:test/test.dart';
-import 'package:yaml/yaml.dart';
-
-void main() {
- test('parseCargoBuildOptions', () {
- final yaml = """
-toolchain: nightly
-extra_flags:
- - -Z
- # Comment here
- - build-std=panic_abort,std
-""";
- final node = loadYamlNode(yaml);
- final options = CargoBuildOptions.parse(node);
- expect(options.toolchain, Toolchain.nightly);
- expect(options.flags, ['-Z', 'build-std=panic_abort,std']);
- });
-
- test('parsePrecompiledBinaries', () {
- final yaml = """
-url_prefix: https://url-prefix
-public_key: a4c3433798eb2c36edf2b94dbb4dd899d57496ca373a8982d8a792410b7f6445
-""";
- final precompiledBinaries = PrecompiledBinaries.parse(loadYamlNode(yaml));
- final key = HEX.decode(
- 'a4c3433798eb2c36edf2b94dbb4dd899d57496ca373a8982d8a792410b7f6445');
- expect(precompiledBinaries.uriPrefix, 'https://url-prefix');
- expect(precompiledBinaries.publicKey.bytes, key);
- });
-
- test('parseCargokitOptions', () {
- const yaml = '''
-cargo:
- # For smalles binaries rebuilt the standard library with panic=abort
- debug:
- toolchain: nightly
- extra_flags:
- - -Z
- # Comment here
- - build-std=panic_abort,std
- release:
- toolchain: beta
-
-precompiled_binaries:
- url_prefix: https://url-prefix
- public_key: a4c3433798eb2c36edf2b94dbb4dd899d57496ca373a8982d8a792410b7f6445
-''';
- final options = CargokitCrateOptions.parse(loadYamlNode(yaml));
- expect(options.precompiledBinaries?.uriPrefix, 'https://url-prefix');
- final key = HEX.decode(
- 'a4c3433798eb2c36edf2b94dbb4dd899d57496ca373a8982d8a792410b7f6445');
- expect(options.precompiledBinaries?.publicKey.bytes, key);
-
- final debugOptions = options.cargo[BuildConfiguration.debug]!;
- expect(debugOptions.toolchain, Toolchain.nightly);
- expect(debugOptions.flags, ['-Z', 'build-std=panic_abort,std']);
-
- final releaseOptions = options.cargo[BuildConfiguration.release]!;
- expect(releaseOptions.toolchain, Toolchain.beta);
- expect(releaseOptions.flags, []);
- });
-
- test('parseCargokitUserOptions', () {
- const yaml = '''
-use_precompiled_binaries: false
-verbose_logging: true
-''';
- final options = CargokitUserOptions.parse(loadYamlNode(yaml));
- expect(options.usePrecompiledBinaries, false);
- expect(options.verboseLogging, true);
- });
-}
diff --git a/cargokit/cmake/cargokit.cmake b/cargokit/cmake/cargokit.cmake
index 54340e72..ddd05df9 100644
--- a/cargokit/cmake/cargokit.cmake
+++ b/cargokit/cmake/cargokit.cmake
@@ -1,7 +1,3 @@
-# SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-#
-# SPDX-License-Identifier: MIT
-
SET(cargokit_cmake_root "${CMAKE_CURRENT_LIST_DIR}/..")
# Workaround for https://github.com/dart-lang/pub/issues/4010
@@ -9,7 +5,7 @@ get_filename_component(cargokit_cmake_root "${cargokit_cmake_root}" REALPATH)
if(WIN32)
# REALPATH does not properly resolve symlinks on windows :-/
- execute_process(COMMAND powershell -File "${CMAKE_CURRENT_LIST_DIR}/resolve_symlinks.ps1" "${cargokit_cmake_root}" OUTPUT_VARIABLE cargokit_cmake_root OUTPUT_STRIP_TRAILING_WHITESPACE)
+ execute_process(COMMAND powershell -ExecutionPolicy Bypass -File "${CMAKE_CURRENT_LIST_DIR}/resolve_symlinks.ps1" "${cargokit_cmake_root}" OUTPUT_VARIABLE cargokit_cmake_root OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()
# Arguments
@@ -54,6 +50,7 @@ function(apply_cargokit target manifest_dir lib_name any_symbol_name)
else()
set(SCRIPT_EXTENSION ".sh")
set(IMPORT_LIB_EXTENSION "")
+ execute_process(COMMAND chmod +x "${cargokit_cmake_root}/run_build_tool${SCRIPT_EXTENSION}")
endif()
# Using generators in custom command is only supported in CMake 3.20+
@@ -79,6 +76,7 @@ function(apply_cargokit target manifest_dir lib_name any_symbol_name)
)
endif()
+
set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/_phony_" PROPERTIES SYMBOLIC TRUE)
if (TARGET ${target})
@@ -98,4 +96,4 @@ function(apply_cargokit target manifest_dir lib_name any_symbol_name)
# Allow adding the output library to plugin bundled libraries
set("${target}_cargokit_lib" ${OUTPUT_LIB} PARENT_SCOPE)
-endfunction()
\ No newline at end of file
+endfunction()
diff --git a/cargokit/cmake/resolve_symlinks.ps1 b/cargokit/cmake/resolve_symlinks.ps1
index 69cb97d6..2ac593a1 100644
--- a/cargokit/cmake/resolve_symlinks.ps1
+++ b/cargokit/cmake/resolve_symlinks.ps1
@@ -1,7 +1,3 @@
-# SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-#
-# SPDX-License-Identifier: MIT
-
function Resolve-Symlinks {
[CmdletBinding()]
[OutputType([string])]
@@ -18,14 +14,21 @@ function Resolve-Symlinks {
if ($realPath -and !$realPath.EndsWith($separator)) {
$realPath += $separator
}
- $realPath += $part
+
+ $realPath += $part.Replace('\', '/')
+
+ # The slash is important when using Get-Item on Drive letters in pwsh.
+ if (-not($realPath.Contains($separator)) -and $realPath.EndsWith(':')) {
+ $realPath += '/'
+ }
+
$item = Get-Item $realPath
- if ($item.Target) {
- $realPath = $item.Target.Replace('\', '/')
+ if ($item.LinkTarget) {
+ $realPath = $item.LinkTarget.Replace('\', '/')
}
}
$realPath
}
-$path=Resolve-Symlinks -Path $args[0]
+$path = Resolve-Symlinks -Path $args[0]
Write-Host $path
diff --git a/cargokit/docs/architecture.md b/cargokit/docs/architecture.md
deleted file mode 100644
index 6a380211..00000000
--- a/cargokit/docs/architecture.md
+++ /dev/null
@@ -1,110 +0,0 @@
-
-
-# Cargokit Architecture
-
-Note: This is mostly relevant for plugins authors that want to see a bit under the hood rather then just following a tutorial.
-
-In ideal conditions the end-developer using the plugin should not even be aware of Cargokit existence.
-
-## Integration
-
-Cargokit is meant to be included in Flutter plugin (or application) that contains the Rust crate to be built during the Flutter build process.
-
-Cargokit can be either incuded as git submodule or git subtree (required for plugins - as pub does not support submodules for git dependencies).
-
-For a step by step tutorial on integrating Cargokit with a Flutter plugin see https://matejknopp.com/post/flutter_plugin_in_rust_with_no_prebuilt_binaries/.
-
-## build_tool
-
-Build tool is the core of cargokit. It is a Dart command line package that facilitates the build of Rust crate. It is invoked during the Flutter build process to build (or download) Rust artifacts, but it can be also used as a standalone tool.
-
-It handles the following commands:
-
-### build-cmake
-
-This is invoked from `cargokit.cmake` and it is used to build the Rust crate into a dynamic library on Linux and Windows (which use CMake as build system).
-
-The command takes no additional arguments, everything is controlled during environment variables set by `cargokit.cmake`.
-
-### build-gradle
-
-This is invoked from `plugin.gradle` and it is used to build the Rust crate into a dynamic library on Android. The command takes no additional arguments, everything is controlled during environment variables set by `plugin.gradle`.
-
-The build_tool installs NDK if needed, configures the Rust environment for cross compilation and then invokes `cargo build` with appropriate arguments and environment variables.
-
-The build-tool also acts a linker driver.
-
-### build-pod
-
-This is invoked from plugin's podspec `script_phase` through `build_pod.sh`. Bundle tool will build the Rust crate into a static library that gets linked into the plugin Framework. In this case must have `:execution_position` set to `:before_compile`.
-
-Cargokit will build binaries for all active architectures from XCode build and lipo them togherer.
-
-When using Cargokit to integrate Rust code with an application (not a plugin) you can also configure the `Cargo.toml` to just build a dynamic library. When Cargokit finds that the crate only built a dylib and no static lib, it will attempt to replace the Cocoapod framework binary with the dylib. In this case the script `:execution_position` must be set to `:after_compile`. This is *not* recommended for plugins and it's quite experimental.
-
-### gen-key, precompile-binaries, verify-binaries
-
-These are used as when providing precompiled binaries for Plugin. See [precompiled_binaries.md](precompiled_binaries.md) for more information.
-
-## Launching the build_tool during build.
-
-During Flutter build, the build tool can not be launched directly using `dart run`. Rather it is launched through `run_build_tool.sh` and `run_build_tool.cmd`. Because the `build_tool` is shipped as part of plugin, we generally don't want to write into the plugin directory during build, which would happen if the `build_tool` was simply invoked through `dart run` (For example the `.dart_tool/package_config.json` file would get written inside the `build_tool` directory).
-
-Instead the `run_build_tool` script creates a minimal Dart command line package in the build directory and references the `build_tool` as package. That way the `.dart_tool/package_config.json` file is created in the temporary build folder and not in the plugin itself. The script also precompiles the Dart code to speed up subsequent invocations.
-
-## Configuring Cargokit
-
-### Configuration for the Rust crate
-
-Cargokit can be configured through a `cargokit.yaml` file, which can be used to control the build of the Rust package and is placed into the Rust crate next to `Cargo.toml`.
-
-Here is an example `cargokit.yaml` with comments:
-```yaml
-cargo:
- debug: # Configuration of cargo execution during debug builds
- toolchain: stable # default
- release: # Configuration of cargo execution for release builds
- toolchain: nightly # rustup will be invoked with nightly toolchain
- extra_flags: # extra arguments passed to cargo build
- - -Z
- - build-std=panic_abort,std
-
-# If crate ships with precompiled binaries, they can be configured here.
-precompiled_binaries:
- # Uri prefix used when downloading precompiled binaries.
- url_prefix: https://github.com/superlistapp/super_native_extensions/releases/download/precompiled_
-
- # Public key for verifying downloaded precompiled binaries.
- public_key: 3a257ef1c7d72d84225ac4658d24812ada50a7a7a8a2138c2a91353389fdc514
-```
-
-### Configuration for the application consuming the plugin
-
-A `cargokit_options.yaml` file can also be placed by developer using plugin to the root of the application package. In which case the file can be used to specify following options:
-
-```yaml
-# Enables verbose logging of Cargokit during build
-verbose_logging: true
-
-# Opts out of using precompiled binaries. If crate has configured
-# and deployed precompiled binaries, these will be by default used whenever Rustup
-# is not installed. With `use_precompiled_binaries` set to false, the build will
-# instead be aborted prompting user to install Rustup.
-use_precompiled_binaries: false
-```
-
-## Detecting Rustup
-
-When the plugin doesn't come with precompiled libraries (or user opt-out), `build_tool` will need to invoke Rustup during build to ensure that required Rust targets and toolchain are installed for current build and to build the Rust crate.
-
-Cargokit will attempt to detect Rustup in the default Rustup installation location (`~/.cargo/rustup`) as well as in PATH. This is done so that if user install Rustup but doesn't properly configure PATH, Cargokit will still work.
-
-If `build_tool` doesn't find Rustup, it will about the build with a message showing instructions to install Rustup specific to current platform.
-
-On macOS it will also detect a homebrew Rust installation in PATH and will prompt user to call `brew unlink rust` first to remove homebrew Rust installation from PATH, because it may interfere with Rustup.
-
-Homebrew Rust installation can not be used by Cargokit, because it can only build for host platform. Cargokit needs to be able to cross compile the Rust crate for iOS and Android and thus needs full Rustup installation.
diff --git a/cargokit/docs/precompiled_binaries.md b/cargokit/docs/precompiled_binaries.md
deleted file mode 100644
index 9b85b7e5..00000000
--- a/cargokit/docs/precompiled_binaries.md
+++ /dev/null
@@ -1,101 +0,0 @@
-
-
-# Precompiled Binaries
-
-Because Cargokit builds the Rust crate during Flutter build, it is inherently
-dependend on the Rust toolchain being installed on the developer's machine.
-
-To decrease the friction, it is possible for Cargokit to use precompiled binaries instead.
-
-This is how the process of using precompiled binaries looks from the perspective of the build on developer machine:
-
-1. Cargokit checks if there is `cargokit_options.yaml` file in the root folder of target application. If there is one, it will be checked for `use_precompiled_binaries` options to see if user opted out of using precompiled binaries. In which case Cargokit will insist on building from source. Cargokit will also build from source if the configuration file is absent, but user has Rustup installed.
-
-2. Cargokit checks if there is `cargokit.yaml` file placed in the Rust crate. If there is one, it will be checked for `precompiled_binaries` section to see if crate supports precompiled binaries. The configuration section must contain a public key and URL prefix.
-
-3. Cargokit computes a `crate-hash`. This is a SHA256 hash value computed from all Rust files inside crate, `Cargo.toml`, `Cargo.lock` and `cargokit.yaml`. This uniquely identifies the crate and it is used to find the correct precompiled binaries.
-
-4. Cargokit will attempt to download the precompiled binaries for target platform and `crate_hash` combination and a signature file for each downloaded binary. If download succeeds, the binary content will be verified against the signature and public key included in `cargokit.yaml` (which is part of Rust crate and thus part of published Flutter package).
-
-5. If the verification succeeds, the precompiled binaries will be used. Otherwise the binary will be discarded and Cargokit will insist on building from source.
-
-## Providing precompiled binaries
-
-Note that this assumes that precompiled binaries will be generated during github actions and deployed as github releases.
-
-### Use `build_tool` to generate a key-pair:
-
-```
-dart run build_tool gen-key
-```
-
-This will print the private key and public key. Store the private key securely. It needs to be provided as a secret to github action.
-
-The public key should be included in `cargokit.yaml` file in the Rust crate.
-
-### Provide a `cargokit.yaml` file in the Rust crate
-
-The file must be placed alongside Cargo.toml.
-
-```yaml
-precompiled_binaries:
- # Uri prefix used when downloading precompiled binaries.
- url_prefix: https://github.com///releases/download/precompiled_
-
- # Public key for verifying downloaded precompiled binaries.
- public_key:
-```
-
-### Configure a github action to build and upload precompiled binaries.
-
-The github action should be run at every commit to main branch (and possibly other branches).
-
-The action needs two secrets - private key for signing binaries and GitHub token for uploading binaries as releases. Here is example action that precompiles and uploads binaries for all supported targets.
-
-```yaml
-on:
- push:
- branches: [ main ]
-
-name: Precompile Binaries
-
-jobs:
- Precompile:
- runs-on: ${{ matrix.os }}
- strategy:
- fail-fast: false
- matrix:
- os:
- - ubuntu-latest
- - macOS-latest
- - windows-latest
- steps:
- - uses: actions/checkout@v2
- - uses: dart-lang/setup-dart@v1
- - name: Install GTK
- if: (matrix.os == 'ubuntu-latest')
- run: sudo apt-get update && sudo apt-get install libgtk-3-dev
- - name: Precompile
- if: (matrix.os == 'macOS-latest') || (matrix.os == 'windows-latest')
- run: dart run build_tool precompile-binaries -v --manifest-dir=../../rust --repository=superlistapp/super_native_extensions
- working-directory: super_native_extensions/cargokit/build_tool
- env:
- GITHUB_TOKEN: ${{ secrets.RELEASE_GITHUB_TOKEN }}
- PRIVATE_KEY: ${{ secrets.RELEASE_PRIVATE_KEY }}
- - name: Precompile (with Android)
- if: (matrix.os == 'ubuntu-latest')
- run: dart run build_tool precompile-binaries -v --manifest-dir=../../rust --repository=superlistapp/super_native_extensions --android-sdk-location=/usr/local/lib/android/sdk --android-ndk-version=24.0.8215888 --android-min-sdk-version=23
- working-directory: super_native_extensions/cargokit/build_tool
- env:
- GITHUB_TOKEN: ${{ secrets.RELEASE_GITHUB_TOKEN }}
- PRIVATE_KEY: ${{ secrets.RELEASE_PRIVATE_KEY }}
-```
-
-By default the `built_tool precompile-binaries` commands build and uploads the binaries for all targets buildable from current host. This can be overriden using the `--target ` argument.
-
-Android binaries will be built when `--android-sdk-location` and `--android-ndk-version` arguments are provided.
-
diff --git a/cargokit/gradle/plugin.gradle b/cargokit/gradle/plugin.gradle
index b6d9ff00..4af35ee0 100644
--- a/cargokit/gradle/plugin.gradle
+++ b/cargokit/gradle/plugin.gradle
@@ -1,3 +1,6 @@
+/// This is copied from Cargokit (which is the official way to use it currently)
+/// Details: https://fzyzcjy.github.io/flutter_rust_bridge/manual/integrate/builtin
+
import java.nio.file.Paths
import org.apache.tools.ant.taskdefs.condition.Os
@@ -56,6 +59,12 @@ abstract class CargoKitBuildTask extends DefaultTask {
def rootProjectDir = project.rootProject.projectDir
+ if (!Os.isFamily(Os.FAMILY_WINDOWS)) {
+ project.exec {
+ commandLine 'chmod', '+x', path
+ }
+ }
+
project.exec {
executable path
args "build-gradle"
@@ -83,7 +92,7 @@ class CargoKitPlugin implements Plugin {
_findFlutterPlugin(rootProject.childProjects)
}
- private Plugin _findFlutterPlugin(Map projects) {
+ private Plugin _findFlutterPlugin(Map projects) {
for (project in projects) {
for (plugin in project.value.getPlugins()) {
if (plugin.class.name == "com.flutter.gradle.FlutterPlugin") {
@@ -111,7 +120,11 @@ class CargoKitPlugin implements Plugin {
def cargoBuildDir = "${project.buildDir}/build"
- plugin.project.android.applicationVariants.all { variant ->
+ // Determine if the project is an application or library
+ def isApplication = plugin.project.plugins.hasPlugin('com.android.application')
+ def variants = isApplication ? plugin.project.android.applicationVariants : plugin.project.android.libraryVariants
+
+ variants.all { variant ->
final buildType = variant.buildType.name
@@ -163,4 +176,4 @@ class CargoKitPlugin implements Plugin {
}
}
}
-}
\ No newline at end of file
+}
diff --git a/cargokit/run_build_tool.cmd b/cargokit/run_build_tool.cmd
old mode 100644
new mode 100755
index 29556103..c45d0aa8
--- a/cargokit/run_build_tool.cmd
+++ b/cargokit/run_build_tool.cmd
@@ -8,7 +8,7 @@ SET BASEDIR=%~dp0
if not exist "%CARGOKIT_TOOL_TEMP_DIR%" (
mkdir "%CARGOKIT_TOOL_TEMP_DIR%"
)
-cd "%CARGOKIT_TOOL_TEMP_DIR%"
+cd /D "%CARGOKIT_TOOL_TEMP_DIR%"
SET BUILD_TOOL_PKG_DIR=%BASEDIR%build_tool
SET DART=%FLUTTER_ROOT%\bin\cache\dart-sdk\bin\dart
@@ -76,8 +76,16 @@ If %ERRORLEVEL% neq 0 (
REM There is no CUR_PACKAGE_INFO it was renamed in previous step to %PREV_PACKAGE_INFO%
REM which means we need to do pub get and precompile
if not exist "%PRECOMPILED%" (
+ echo Running pub get in "%cd%"
"%DART%" pub get --no-precompile
"%DART%" compile kernel bin/build_tool_runner.dart
)
"%DART%" "%PRECOMPILED%" %*
+
+REM 253 means invalid snapshot version.
+If %ERRORLEVEL% equ 253 (
+ "%DART%" pub get --no-precompile
+ "%DART%" compile kernel bin/build_tool_runner.dart
+ "%DART%" "%PRECOMPILED%" %*
+)
diff --git a/cargokit/run_build_tool.cmd.license b/cargokit/run_build_tool.cmd.license
deleted file mode 100644
index 7b44746f..00000000
--- a/cargokit/run_build_tool.cmd.license
+++ /dev/null
@@ -1,3 +0,0 @@
-SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-
-SPDX-License-Identifier: MIT
diff --git a/cargokit/run_build_tool.sh b/cargokit/run_build_tool.sh
index eada363e..24b0ed89 100755
--- a/cargokit/run_build_tool.sh
+++ b/cargokit/run_build_tool.sh
@@ -1,8 +1,4 @@
-#!/bin/bash
-
-# SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-#
-# SPDX-License-Identifier: MIT
+#!/usr/bin/env bash
set -e
@@ -46,6 +42,12 @@ void main(List args) {
}
EOF
+# Create alias for `shasum` if it does not exist and `sha1sum` exists
+if ! [ -x "$(command -v shasum)" ] && [ -x "$(command -v sha1sum)" ]; then
+ shopt -s expand_aliases
+ alias shasum="sha1sum"
+fi
+
# Dart run will not cache any package that has a path dependency, which
# is the case for our build_tool_runner. So instead we precompile the package
# ourselves.
@@ -68,7 +70,6 @@ if [ -f "$PACKAGE_HASH_FILE" ]; then
fi
fi
-
# Run pub get if needed.
if [ ! -f "$PACKAGE_HASH_FILE" ]; then
"$DART" pub get --no-precompile
@@ -76,4 +77,23 @@ if [ ! -f "$PACKAGE_HASH_FILE" ]; then
echo "$PACKAGE_HASH" > "$PACKAGE_HASH_FILE"
fi
+# Rebuild the tool if it was deleted by Android Studio
+if [ ! -f "bin/build_tool_runner.dill" ]; then
+ "$DART" compile kernel bin/build_tool_runner.dart
+fi
+
+set +e
+
"$DART" bin/build_tool_runner.dill "$@"
+
+exit_code=$?
+
+# 253 means invalid snapshot version.
+if [ $exit_code == 253 ]; then
+ "$DART" pub get --no-precompile
+ "$DART" compile kernel bin/build_tool_runner.dart
+ "$DART" bin/build_tool_runner.dill "$@"
+ exit_code=$?
+fi
+
+exit $exit_code
diff --git a/example/pubspec.lock b/example/pubspec.lock
index 5fbe5ae2..9756d644 100644
--- a/example/pubspec.lock
+++ b/example/pubspec.lock
@@ -1,6 +1,14 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
+ args:
+ dependency: transitive
+ description:
+ name: args
+ sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.7.0"
async:
dependency: transitive
description:
@@ -17,6 +25,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.2"
+ build_cli_annotations:
+ dependency: transitive
+ description:
+ name: build_cli_annotations
+ sha256: e563c2e01de8974566a1998410d3f6f03521788160a02503b0b1f1a46c7b3d95
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.1"
characters:
dependency: transitive
description:
@@ -78,11 +94,35 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.3"
+ flutter_rust_bridge:
+ dependency: transitive
+ description:
+ name: flutter_rust_bridge
+ sha256: "37ef40bc6f863652e865f0b2563ea07f0d3c58d8efad803cc01933a4b2ee067e"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.11.1"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
+ freezed_annotation:
+ dependency: transitive
+ description:
+ name: freezed_annotation
+ sha256: c2e2d632dd9b8a2b7751117abcfc2b4888ecfe181bd9fca7170d9ef02e595fe2
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.4.4"
+ json_annotation:
+ dependency: transitive
+ description:
+ name: json_annotation
+ sha256: "805fa86df56383000f640384b282ce0cb8431f1a7a2396de92fb66186d8c57df"
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.10.0"
leak_tracker:
dependency: transitive
description:
@@ -135,10 +175,10 @@ packages:
dependency: transitive
description:
name: meta
- sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
+ sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394"
url: "https://pub.dev"
source: hosted
- version: "1.16.0"
+ version: "1.17.0"
path:
dependency: transitive
description:
@@ -268,17 +308,17 @@ packages:
dependency: transitive
description:
name: test_api
- sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00"
+ sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55
url: "https://pub.dev"
source: hosted
- version: "0.7.6"
+ version: "0.7.7"
tor:
dependency: "direct main"
description:
path: ".."
relative: true
source: path
- version: "0.1.0"
+ version: "0.2.0"
vector_math:
dependency: transitive
description:
@@ -295,6 +335,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "15.0.2"
+ web:
+ dependency: transitive
+ description:
+ name: web
+ sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.1"
xdg_directories:
dependency: transitive
description:
@@ -304,5 +352,5 @@ packages:
source: hosted
version: "1.1.0"
sdks:
- dart: ">=3.8.0-0 <4.0.0"
+ dart: ">=3.9.0 <4.0.0"
flutter: ">=3.29.0"
diff --git a/ffigen.yaml b/ffigen.yaml
deleted file mode 100644
index 62108b01..00000000
--- a/ffigen.yaml
+++ /dev/null
@@ -1,23 +0,0 @@
-# SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-#
-# SPDX-License-Identifier: MIT
-
-# Run with `flutter pub run ffigen --config ffigen.yaml`.
-name: NativeLibrary
-description: |
- Bindings for `tor.h`.
-
- Regenerate bindings with `flutter pub run ffigen --config ffigen.yaml`.
-output: 'lib/tor_bindings_generated.dart'
-headers:
- entry-points:
- - 'rust/target/tor.h'
- include-directives:
- - 'rust/target/tor.h'
-preamble: |
- // ignore_for_file: always_specify_types
- // ignore_for_file: camel_case_types
- // ignore_for_file: non_constant_identifier_names
-comments:
- style: any
- length: full
diff --git a/flake.nix b/flake.nix
index 59fd5df4..36ba1cf6 100644
--- a/flake.nix
+++ b/flake.nix
@@ -56,6 +56,10 @@
cargo-ndk
]
++ pkgs.lib.optionals pkgs.stdenv.isLinux [
+ # C++ toolchain for Flutter Linux builds
+ gcc
+ glibc
+
# Linux desktop build deps (GTK runner)
gtk3
pcre2
@@ -75,6 +79,12 @@
shellHook = ''
export LIBCLANG_PATH="${pkgs.llvmPackages.libclang.lib}/lib"
+ # Use GCC for compiling C/C++ code (Flutter/CMake)
+ export CC="${pkgs.gcc}/bin/gcc"
+ export CXX="${pkgs.gcc}/bin/g++"
+ # Ensure linker can find C runtime and C++ libraries
+ export LIBRARY_PATH="${pkgs.glibc}/lib:${pkgs.gcc.cc.lib}/lib:$LIBRARY_PATH"
+ export LD_LIBRARY_PATH="${pkgs.gcc.cc.lib}/lib:$LD_LIBRARY_PATH"
'';
};
}
diff --git a/flutter_rust_bridge.yaml b/flutter_rust_bridge.yaml
new file mode 100644
index 00000000..27ddd366
--- /dev/null
+++ b/flutter_rust_bridge.yaml
@@ -0,0 +1,8 @@
+# SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
+#
+# SPDX-License-Identifier: MIT
+
+rust_input: crate::api
+rust_root: rust/
+dart_output: lib/src/rust
+dart_entrypoint_class_name: RustLib
diff --git a/ios/Classes/dummy_file.c b/ios/Classes/dummy_file.c
new file mode 100644
index 00000000..a092da28
--- /dev/null
+++ b/ios/Classes/dummy_file.c
@@ -0,0 +1,7 @@
+/*
+ * SPDX-FileCopyrightText: 2024 Foundation Devices Inc
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+// This is an empty file to force CocoaPods to create a framework.
diff --git a/ios/Classes/tor_ffi_plugin.c b/ios/Classes/tor_ffi_plugin.c
deleted file mode 100644
index bc3f15a2..00000000
--- a/ios/Classes/tor_ffi_plugin.c
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
- *
- * SPDX-License-Identifier: MIT
- */
-
-// SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-//
-// SPDX-License-Identifier: MIT
-
-// Relative import to be able to reuse the C sources.
-// See the comment in ../{projectName}}.podspec for more information.
diff --git a/ios/rust_lib_tor.podspec b/ios/rust_lib_tor.podspec
new file mode 100644
index 00000000..c74e0aaa
--- /dev/null
+++ b/ios/rust_lib_tor.podspec
@@ -0,0 +1,48 @@
+#
+# SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
+# SPDX-License-Identifier: MIT
+#
+# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
+# Run `pod lib lint rust_lib_tor.podspec` to validate before publishing.
+#
+Pod::Spec.new do |s|
+ s.name = 'rust_lib_tor'
+ s.version = '0.0.1'
+ s.summary = 'Rust library for Tor proxy'
+ s.description = <<-DESC
+Rust library providing Tor proxy functionality via arti.
+ DESC
+ s.homepage = 'https://github.com/Foundation-Devices/tor'
+ s.license = { :file => '../LICENSE' }
+ s.author = { 'Foundation Devices' => 'hello@foundation.xyz' }
+
+ # This will ensure the source files in Classes/ are included in the native
+ # builds of apps using this FFI plugin. Podspec does not support relative
+ # paths, so Classes contains a forwarder C file that relatively imports
+ # `../src/*` so that the C sources can be shared among all target platforms.
+ s.source = { :path => '.' }
+ s.source_files = 'Classes/**/*'
+ s.dependency 'Flutter'
+ s.platform = :ios, '11.0'
+
+ # Flutter.framework does not contain a i386 slice.
+ s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
+ s.swift_version = '5.0'
+
+ s.script_phase = {
+ :name => 'Build Rust library',
+ # First argument is relative path to the `rust` folder, second is name of rust library
+ :script => 'sh "$PODS_TARGET_SRCROOT/../cargokit/build_pod.sh" ../rust rust_lib_tor',
+ :execution_position => :before_compile,
+ :input_files => ['${BUILT_PRODUCTS_DIR}/cargokit_phony'],
+ # Let XCode know that the static library referenced in -force_load below is
+ # created by this build step.
+ :output_files => ["${BUILT_PRODUCTS_DIR}/librust_lib_tor.a"],
+ }
+ s.pod_target_xcconfig = {
+ 'DEFINES_MODULE' => 'YES',
+ # Flutter.framework does not contain a i386 slice.
+ 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386',
+ 'OTHER_LDFLAGS' => '-force_load ${BUILT_PRODUCTS_DIR}/librust_lib_tor.a',
+ }
+end
diff --git a/ios/tor.podspec b/ios/tor.podspec
deleted file mode 100644
index df75e302..00000000
--- a/ios/tor.podspec
+++ /dev/null
@@ -1,37 +0,0 @@
-#
-# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
-# Run `pod lib lint tor.podspec` to validate before publishing.
-#
-Pod::Spec.new do |s|
- s.name = 'tor'
- s.version = '0.0.1'
- s.summary = 'A new Flutter FFI plugin project.'
- s.description = <<-DESC
-A new Flutter FFI plugin project.
- DESC
- s.homepage = 'http://example.com'
- s.license = { :file => '../LICENSE' }
- s.author = { 'Your Company' => 'email@example.com' }
-
- s.source = { :path => '.' }
- s.source_files = 'Classes/**/*'
- s.dependency 'Flutter'
- s.platform = :ios, '9.0'
-
- s.script_phase = {
- :name => 'Build Rust library',
- # First argument is relative path to the `rust` folder, second is name of rust library
- :script => 'sh "$PODS_TARGET_SRCROOT/../cargokit/build_pod.sh" ../rust tor',
- :execution_position => :before_compile,
- :input_files => ['${BUILT_PRODUCTS_DIR}/cargokit_phony'],
- # Let XCode know that the static library referenced in -force_load below is
- # created by this build step.
- :output_files => ["${BUILT_PRODUCTS_DIR}/libtor.a"],
- }
- s.pod_target_xcconfig = {
- 'DEFINES_MODULE' => 'YES',
- # Flutter.framework does not contain a i386 slice.
- 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386',
- 'OTHER_LDFLAGS' => '-force_load ${BUILT_PRODUCTS_DIR}/libtor.a',
- }
-end
diff --git a/ios/tor.podspec.license b/ios/tor.podspec.license
deleted file mode 100644
index 7b44746f..00000000
--- a/ios/tor.podspec.license
+++ /dev/null
@@ -1,3 +0,0 @@
-SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-
-SPDX-License-Identifier: MIT
diff --git a/lib/generated_bindings.dart b/lib/generated_bindings.dart
deleted file mode 100644
index b5b15a54..00000000
--- a/lib/generated_bindings.dart
+++ /dev/null
@@ -1,275 +0,0 @@
-// SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-//
-// SPDX-License-Identifier: MIT
-
-// AUTO GENERATED FILE, DO NOT EDIT.
-//
-// Generated by `package:ffigen`.
-// ignore_for_file: type=lint
-import 'dart:ffi' as ffi;
-
-class NativeLibrary {
- /// Holds the symbol lookup function.
- final ffi.Pointer Function(String symbolName)
- _lookup;
-
- /// The symbols are looked up in [dynamicLibrary].
- NativeLibrary(ffi.DynamicLibrary dynamicLibrary)
- : _lookup = dynamicLibrary.lookup;
-
- /// The symbols are looked up with [lookup].
- NativeLibrary.fromLookup(
- ffi.Pointer Function(String symbolName)
- lookup)
- : _lookup = lookup;
-
- Tor tor_start(
- int socks_port,
- ffi.Pointer state_dir,
- ffi.Pointer cache_dir,
- ) {
- return _tor_start(
- socks_port,
- state_dir,
- cache_dir,
- );
- }
-
- late final _tor_startPtr = _lookup<
- ffi.NativeFunction<
- Tor Function(ffi.Uint16, ffi.Pointer,
- ffi.Pointer)>>('tor_start');
- late final _tor_start = _tor_startPtr.asFunction<
- Tor Function(int, ffi.Pointer, ffi.Pointer)>();
-
- bool tor_client_bootstrap(
- ffi.Pointer client,
- ) {
- return _tor_client_bootstrap(
- client,
- );
- }
-
- late final _tor_client_bootstrapPtr =
- _lookup)>>(
- 'tor_client_bootstrap');
- late final _tor_client_bootstrap = _tor_client_bootstrapPtr
- .asFunction)>();
-
- void tor_client_set_dormant(
- ffi.Pointer client,
- bool soft_mode,
- ) {
- return _tor_client_set_dormant(
- client,
- soft_mode,
- );
- }
-
- late final _tor_client_set_dormantPtr = _lookup<
- ffi
- .NativeFunction, ffi.Bool)>>(
- 'tor_client_set_dormant');
- late final _tor_client_set_dormant = _tor_client_set_dormantPtr
- .asFunction, bool)>();
-
- void tor_proxy_stop(
- ffi.Pointer proxy,
- ) {
- return _tor_proxy_stop(
- proxy,
- );
- }
-
- late final _tor_proxy_stopPtr =
- _lookup)>>(
- 'tor_proxy_stop');
- late final _tor_proxy_stop =
- _tor_proxy_stopPtr.asFunction)>();
-
- void tor_hello() {
- return _tor_hello();
- }
-
- late final _tor_helloPtr =
- _lookup>('tor_hello');
- late final _tor_hello = _tor_helloPtr.asFunction();
-
- ffi.Pointer tor_last_error_message() {
- return _tor_last_error_message();
- }
-
- late final _tor_last_error_messagePtr =
- _lookup Function()>>(
- 'tor_last_error_message');
- late final _tor_last_error_message =
- _tor_last_error_messagePtr.asFunction Function()>();
-
- int tor_get_nofile_limit() {
- return _tor_get_nofile_limit();
- }
-
- late final _tor_get_nofile_limitPtr =
- _lookup>(
- 'tor_get_nofile_limit');
- late final _tor_get_nofile_limit =
- _tor_get_nofile_limitPtr.asFunction();
-
- int tor_set_nofile_limit(
- int limit,
- ) {
- return _tor_set_nofile_limit(
- limit,
- );
- }
-
- late final _tor_set_nofile_limitPtr =
- _lookup>(
- 'tor_set_nofile_limit');
- late final _tor_set_nofile_limit =
- _tor_set_nofile_limitPtr.asFunction();
-}
-
-final class Tor extends ffi.Struct {
- external ffi.Pointer client;
-
- external ffi.Pointer proxy;
-}
-
-const int true1 = 1;
-
-const int false1 = 0;
-
-const int INT8_MIN = -128;
-
-const int INT16_MIN = -32768;
-
-const int INT32_MIN = -2147483648;
-
-const int INT64_MIN = -9223372036854775808;
-
-const int INT8_MAX = 127;
-
-const int INT16_MAX = 32767;
-
-const int INT32_MAX = 2147483647;
-
-const int INT64_MAX = 9223372036854775807;
-
-const int UINT8_MAX = 255;
-
-const int UINT16_MAX = 65535;
-
-const int UINT32_MAX = 4294967295;
-
-const int UINT64_MAX = -1;
-
-const int INT_LEAST8_MIN = -128;
-
-const int INT_LEAST16_MIN = -32768;
-
-const int INT_LEAST32_MIN = -2147483648;
-
-const int INT_LEAST64_MIN = -9223372036854775808;
-
-const int INT_LEAST8_MAX = 127;
-
-const int INT_LEAST16_MAX = 32767;
-
-const int INT_LEAST32_MAX = 2147483647;
-
-const int INT_LEAST64_MAX = 9223372036854775807;
-
-const int UINT_LEAST8_MAX = 255;
-
-const int UINT_LEAST16_MAX = 65535;
-
-const int UINT_LEAST32_MAX = 4294967295;
-
-const int UINT_LEAST64_MAX = -1;
-
-const int INT_FAST8_MIN = -128;
-
-const int INT_FAST16_MIN = -9223372036854775808;
-
-const int INT_FAST32_MIN = -9223372036854775808;
-
-const int INT_FAST64_MIN = -9223372036854775808;
-
-const int INT_FAST8_MAX = 127;
-
-const int INT_FAST16_MAX = 9223372036854775807;
-
-const int INT_FAST32_MAX = 9223372036854775807;
-
-const int INT_FAST64_MAX = 9223372036854775807;
-
-const int UINT_FAST8_MAX = 255;
-
-const int UINT_FAST16_MAX = -1;
-
-const int UINT_FAST32_MAX = -1;
-
-const int UINT_FAST64_MAX = -1;
-
-const int INTPTR_MIN = -9223372036854775808;
-
-const int INTPTR_MAX = 9223372036854775807;
-
-const int UINTPTR_MAX = -1;
-
-const int INTMAX_MIN = -9223372036854775808;
-
-const int INTMAX_MAX = 9223372036854775807;
-
-const int UINTMAX_MAX = -1;
-
-const int PTRDIFF_MIN = -9223372036854775808;
-
-const int PTRDIFF_MAX = 9223372036854775807;
-
-const int SIG_ATOMIC_MIN = -2147483648;
-
-const int SIG_ATOMIC_MAX = 2147483647;
-
-const int SIZE_MAX = -1;
-
-const int WCHAR_MIN = -2147483648;
-
-const int WCHAR_MAX = 2147483647;
-
-const int WINT_MIN = 0;
-
-const int WINT_MAX = 4294967295;
-
-const int NULL = 0;
-
-const int WNOHANG = 1;
-
-const int WUNTRACED = 2;
-
-const int WSTOPPED = 2;
-
-const int WEXITED = 4;
-
-const int WCONTINUED = 8;
-
-const int WNOWAIT = 16777216;
-
-const int RAND_MAX = 2147483647;
-
-const int EXIT_FAILURE = 1;
-
-const int EXIT_SUCCESS = 0;
-
-const int LITTLE_ENDIAN = 1234;
-
-const int BIG_ENDIAN = 4321;
-
-const int PDP_ENDIAN = 3412;
-
-const int BYTE_ORDER = 1234;
-
-const int FD_SETSIZE = 1024;
-
-const int NFDBITS = 64;
diff --git a/lib/src/rust/api/tor.dart b/lib/src/rust/api/tor.dart
new file mode 100644
index 00000000..b170eb74
--- /dev/null
+++ b/lib/src/rust/api/tor.dart
@@ -0,0 +1,98 @@
+// This file is automatically generated, so please do not edit it.
+// @generated by `flutter_rust_bridge`@ 2.11.1.
+
+// ignore_for_file: invalid_use_of_internal_member, unused_import, unnecessary_import
+
+import '../frb_generated.dart';
+import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
+import 'package:freezed_annotation/freezed_annotation.dart' hide protected;
+part 'tor.freezed.dart';
+
+// These functions are ignored because they are not marked as `pub`: `start_proxy_internal`
+// These types are ignored because they are neither used by any `pub` functions nor (for structs and enums) marked `#[frb(unignore)]`: `RUNTIME`
+// These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `clone`, `clone`, `deref`, `fmt`, `fmt`, `initialize`
+
+/// Start Tor client and proxy
+///
+/// This is a blocking operation that may take several seconds.
+/// It bootstraps the Tor network connection and starts a SOCKS proxy.
+Future startTor(
+ {required int socksPort,
+ required String stateDir,
+ required String cacheDir}) =>
+ RustLib.instance.api.crateApiTorStartTor(
+ socksPort: socksPort, stateDir: stateDir, cacheDir: cacheDir);
+
+/// Re-bootstrap the Tor client
+///
+/// Call this after network changes or to refresh the connection.
+Future bootstrap({required TorClientWrapper client}) =>
+ RustLib.instance.api.crateApiTorBootstrap(client: client);
+
+/// Set the client dormant mode
+///
+/// * `soft_mode` - If true, uses Soft dormant mode (keeps some circuits warm)
+/// If false, uses Normal mode (full operation)
+Future setDormant(
+ {required TorClientWrapper client, required bool softMode}) =>
+ RustLib.instance.api
+ .crateApiTorSetDormant(client: client, softMode: softMode);
+
+/// Stop the Tor proxy
+///
+/// This safely aborts the proxy task. Previously this could panic
+/// and crash the app - with FRB, any panic becomes a catchable exception.
+Future stopProxy({required TorProxyHandle proxy}) =>
+ RustLib.instance.api.crateApiTorStopProxy(proxy: proxy);
+
+/// Test function to verify library linking
+Future hello() => RustLib.instance.api.crateApiTorHello();
+
+Future getNofileLimit() =>
+ RustLib.instance.api.crateApiTorGetNofileLimit();
+
+Future setNofileLimit({required BigInt limit}) =>
+ RustLib.instance.api.crateApiTorSetNofileLimit(limit: limit);
+
+// Rust type: RustOpaqueMoi>
+abstract class TorClientWrapper implements RustOpaqueInterface {}
+
+// Rust type: RustOpaqueMoi>
+abstract class TorInstance implements RustOpaqueInterface {
+ TorClientWrapper get client;
+
+ TorProxyHandle get proxy;
+
+ int get socksPort;
+
+ set client(TorClientWrapper client);
+
+ set proxy(TorProxyHandle proxy);
+
+ set socksPort(int socksPort);
+}
+
+// Rust type: RustOpaqueMoi>
+abstract class TorProxyHandle implements RustOpaqueInterface {}
+
+@freezed
+sealed class TorError with _$TorError implements FrbException {
+ const TorError._();
+
+ const factory TorError.bootstrapError(
+ String field0,
+ ) = TorError_BootstrapError;
+ const factory TorError.proxyStartError(
+ String field0,
+ ) = TorError_ProxyStartError;
+ const factory TorError.proxyStopError(
+ String field0,
+ ) = TorError_ProxyStopError;
+ const factory TorError.clientNotInitialized() = TorError_ClientNotInitialized;
+ const factory TorError.runtimeError(
+ String field0,
+ ) = TorError_RuntimeError;
+ const factory TorError.configError(
+ String field0,
+ ) = TorError_ConfigError;
+}
diff --git a/lib/src/rust/api/tor.freezed.dart b/lib/src/rust/api/tor.freezed.dart
new file mode 100644
index 00000000..e36f2488
--- /dev/null
+++ b/lib/src/rust/api/tor.freezed.dart
@@ -0,0 +1,1093 @@
+// coverage:ignore-file
+// GENERATED CODE - DO NOT MODIFY BY HAND
+// ignore_for_file: type=lint
+// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
+
+part of 'tor.dart';
+
+// **************************************************************************
+// FreezedGenerator
+// **************************************************************************
+
+T _$identity(T value) => value;
+
+final _privateConstructorUsedError = UnsupportedError(
+ 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
+
+/// @nodoc
+mixin _$TorError {
+ @optionalTypeArgs
+ TResult when({
+ required TResult Function(String field0) bootstrapError,
+ required TResult Function(String field0) proxyStartError,
+ required TResult Function(String field0) proxyStopError,
+ required TResult Function() clientNotInitialized,
+ required TResult Function(String field0) runtimeError,
+ required TResult Function(String field0) configError,
+ }) =>
+ throw _privateConstructorUsedError;
+ @optionalTypeArgs
+ TResult? whenOrNull({
+ TResult? Function(String field0)? bootstrapError,
+ TResult? Function(String field0)? proxyStartError,
+ TResult? Function(String field0)? proxyStopError,
+ TResult? Function()? clientNotInitialized,
+ TResult? Function(String field0)? runtimeError,
+ TResult? Function(String field0)? configError,
+ }) =>
+ throw _privateConstructorUsedError;
+ @optionalTypeArgs
+ TResult maybeWhen({
+ TResult Function(String field0)? bootstrapError,
+ TResult Function(String field0)? proxyStartError,
+ TResult Function(String field0)? proxyStopError,
+ TResult Function()? clientNotInitialized,
+ TResult Function(String field0)? runtimeError,
+ TResult Function(String field0)? configError,
+ required TResult orElse(),
+ }) =>
+ throw _privateConstructorUsedError;
+ @optionalTypeArgs
+ TResult map({
+ required TResult Function(TorError_BootstrapError value) bootstrapError,
+ required TResult Function(TorError_ProxyStartError value) proxyStartError,
+ required TResult Function(TorError_ProxyStopError value) proxyStopError,
+ required TResult Function(TorError_ClientNotInitialized value)
+ clientNotInitialized,
+ required TResult Function(TorError_RuntimeError value) runtimeError,
+ required TResult Function(TorError_ConfigError value) configError,
+ }) =>
+ throw _privateConstructorUsedError;
+ @optionalTypeArgs
+ TResult? mapOrNull({
+ TResult? Function(TorError_BootstrapError value)? bootstrapError,
+ TResult? Function(TorError_ProxyStartError value)? proxyStartError,
+ TResult? Function(TorError_ProxyStopError value)? proxyStopError,
+ TResult? Function(TorError_ClientNotInitialized value)?
+ clientNotInitialized,
+ TResult? Function(TorError_RuntimeError value)? runtimeError,
+ TResult? Function(TorError_ConfigError value)? configError,
+ }) =>
+ throw _privateConstructorUsedError;
+ @optionalTypeArgs
+ TResult maybeMap({
+ TResult Function(TorError_BootstrapError value)? bootstrapError,
+ TResult Function(TorError_ProxyStartError value)? proxyStartError,
+ TResult Function(TorError_ProxyStopError value)? proxyStopError,
+ TResult Function(TorError_ClientNotInitialized value)? clientNotInitialized,
+ TResult Function(TorError_RuntimeError value)? runtimeError,
+ TResult Function(TorError_ConfigError value)? configError,
+ required TResult orElse(),
+ }) =>
+ throw _privateConstructorUsedError;
+}
+
+/// @nodoc
+abstract class $TorErrorCopyWith<$Res> {
+ factory $TorErrorCopyWith(TorError value, $Res Function(TorError) then) =
+ _$TorErrorCopyWithImpl<$Res, TorError>;
+}
+
+/// @nodoc
+class _$TorErrorCopyWithImpl<$Res, $Val extends TorError>
+ implements $TorErrorCopyWith<$Res> {
+ _$TorErrorCopyWithImpl(this._value, this._then);
+
+ // ignore: unused_field
+ final $Val _value;
+ // ignore: unused_field
+ final $Res Function($Val) _then;
+
+ /// Create a copy of TorError
+ /// with the given fields replaced by the non-null parameter values.
+}
+
+/// @nodoc
+abstract class _$$TorError_BootstrapErrorImplCopyWith<$Res> {
+ factory _$$TorError_BootstrapErrorImplCopyWith(
+ _$TorError_BootstrapErrorImpl value,
+ $Res Function(_$TorError_BootstrapErrorImpl) then) =
+ __$$TorError_BootstrapErrorImplCopyWithImpl<$Res>;
+ @useResult
+ $Res call({String field0});
+}
+
+/// @nodoc
+class __$$TorError_BootstrapErrorImplCopyWithImpl<$Res>
+ extends _$TorErrorCopyWithImpl<$Res, _$TorError_BootstrapErrorImpl>
+ implements _$$TorError_BootstrapErrorImplCopyWith<$Res> {
+ __$$TorError_BootstrapErrorImplCopyWithImpl(
+ _$TorError_BootstrapErrorImpl _value,
+ $Res Function(_$TorError_BootstrapErrorImpl) _then)
+ : super(_value, _then);
+
+ /// Create a copy of TorError
+ /// with the given fields replaced by the non-null parameter values.
+ @pragma('vm:prefer-inline')
+ @override
+ $Res call({
+ Object? field0 = null,
+ }) {
+ return _then(_$TorError_BootstrapErrorImpl(
+ null == field0
+ ? _value.field0
+ : field0 // ignore: cast_nullable_to_non_nullable
+ as String,
+ ));
+ }
+}
+
+/// @nodoc
+
+class _$TorError_BootstrapErrorImpl extends TorError_BootstrapError {
+ const _$TorError_BootstrapErrorImpl(this.field0) : super._();
+
+ @override
+ final String field0;
+
+ @override
+ String toString() {
+ return 'TorError.bootstrapError(field0: $field0)';
+ }
+
+ @override
+ bool operator ==(Object other) {
+ return identical(this, other) ||
+ (other.runtimeType == runtimeType &&
+ other is _$TorError_BootstrapErrorImpl &&
+ (identical(other.field0, field0) || other.field0 == field0));
+ }
+
+ @override
+ int get hashCode => Object.hash(runtimeType, field0);
+
+ /// Create a copy of TorError
+ /// with the given fields replaced by the non-null parameter values.
+ @JsonKey(includeFromJson: false, includeToJson: false)
+ @override
+ @pragma('vm:prefer-inline')
+ _$$TorError_BootstrapErrorImplCopyWith<_$TorError_BootstrapErrorImpl>
+ get copyWith => __$$TorError_BootstrapErrorImplCopyWithImpl<
+ _$TorError_BootstrapErrorImpl>(this, _$identity);
+
+ @override
+ @optionalTypeArgs
+ TResult when({
+ required TResult Function(String field0) bootstrapError,
+ required TResult Function(String field0) proxyStartError,
+ required TResult Function(String field0) proxyStopError,
+ required TResult Function() clientNotInitialized,
+ required TResult Function(String field0) runtimeError,
+ required TResult Function(String field0) configError,
+ }) {
+ return bootstrapError(field0);
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult? whenOrNull({
+ TResult? Function(String field0)? bootstrapError,
+ TResult? Function(String field0)? proxyStartError,
+ TResult? Function(String field0)? proxyStopError,
+ TResult? Function()? clientNotInitialized,
+ TResult? Function(String field0)? runtimeError,
+ TResult? Function(String field0)? configError,
+ }) {
+ return bootstrapError?.call(field0);
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult maybeWhen({
+ TResult Function(String field0)? bootstrapError,
+ TResult Function(String field0)? proxyStartError,
+ TResult Function(String field0)? proxyStopError,
+ TResult Function()? clientNotInitialized,
+ TResult Function(String field0)? runtimeError,
+ TResult Function(String field0)? configError,
+ required TResult orElse(),
+ }) {
+ if (bootstrapError != null) {
+ return bootstrapError(field0);
+ }
+ return orElse();
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult map({
+ required TResult Function(TorError_BootstrapError value) bootstrapError,
+ required TResult Function(TorError_ProxyStartError value) proxyStartError,
+ required TResult Function(TorError_ProxyStopError value) proxyStopError,
+ required TResult Function(TorError_ClientNotInitialized value)
+ clientNotInitialized,
+ required TResult Function(TorError_RuntimeError value) runtimeError,
+ required TResult Function(TorError_ConfigError value) configError,
+ }) {
+ return bootstrapError(this);
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult? mapOrNull({
+ TResult? Function(TorError_BootstrapError value)? bootstrapError,
+ TResult? Function(TorError_ProxyStartError value)? proxyStartError,
+ TResult? Function(TorError_ProxyStopError value)? proxyStopError,
+ TResult? Function(TorError_ClientNotInitialized value)?
+ clientNotInitialized,
+ TResult? Function(TorError_RuntimeError value)? runtimeError,
+ TResult? Function(TorError_ConfigError value)? configError,
+ }) {
+ return bootstrapError?.call(this);
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult maybeMap({
+ TResult Function(TorError_BootstrapError value)? bootstrapError,
+ TResult Function(TorError_ProxyStartError value)? proxyStartError,
+ TResult Function(TorError_ProxyStopError value)? proxyStopError,
+ TResult Function(TorError_ClientNotInitialized value)? clientNotInitialized,
+ TResult Function(TorError_RuntimeError value)? runtimeError,
+ TResult Function(TorError_ConfigError value)? configError,
+ required TResult orElse(),
+ }) {
+ if (bootstrapError != null) {
+ return bootstrapError(this);
+ }
+ return orElse();
+ }
+}
+
+abstract class TorError_BootstrapError extends TorError {
+ const factory TorError_BootstrapError(final String field0) =
+ _$TorError_BootstrapErrorImpl;
+ const TorError_BootstrapError._() : super._();
+
+ String get field0;
+
+ /// Create a copy of TorError
+ /// with the given fields replaced by the non-null parameter values.
+ @JsonKey(includeFromJson: false, includeToJson: false)
+ _$$TorError_BootstrapErrorImplCopyWith<_$TorError_BootstrapErrorImpl>
+ get copyWith => throw _privateConstructorUsedError;
+}
+
+/// @nodoc
+abstract class _$$TorError_ProxyStartErrorImplCopyWith<$Res> {
+ factory _$$TorError_ProxyStartErrorImplCopyWith(
+ _$TorError_ProxyStartErrorImpl value,
+ $Res Function(_$TorError_ProxyStartErrorImpl) then) =
+ __$$TorError_ProxyStartErrorImplCopyWithImpl<$Res>;
+ @useResult
+ $Res call({String field0});
+}
+
+/// @nodoc
+class __$$TorError_ProxyStartErrorImplCopyWithImpl<$Res>
+ extends _$TorErrorCopyWithImpl<$Res, _$TorError_ProxyStartErrorImpl>
+ implements _$$TorError_ProxyStartErrorImplCopyWith<$Res> {
+ __$$TorError_ProxyStartErrorImplCopyWithImpl(
+ _$TorError_ProxyStartErrorImpl _value,
+ $Res Function(_$TorError_ProxyStartErrorImpl) _then)
+ : super(_value, _then);
+
+ /// Create a copy of TorError
+ /// with the given fields replaced by the non-null parameter values.
+ @pragma('vm:prefer-inline')
+ @override
+ $Res call({
+ Object? field0 = null,
+ }) {
+ return _then(_$TorError_ProxyStartErrorImpl(
+ null == field0
+ ? _value.field0
+ : field0 // ignore: cast_nullable_to_non_nullable
+ as String,
+ ));
+ }
+}
+
+/// @nodoc
+
+class _$TorError_ProxyStartErrorImpl extends TorError_ProxyStartError {
+ const _$TorError_ProxyStartErrorImpl(this.field0) : super._();
+
+ @override
+ final String field0;
+
+ @override
+ String toString() {
+ return 'TorError.proxyStartError(field0: $field0)';
+ }
+
+ @override
+ bool operator ==(Object other) {
+ return identical(this, other) ||
+ (other.runtimeType == runtimeType &&
+ other is _$TorError_ProxyStartErrorImpl &&
+ (identical(other.field0, field0) || other.field0 == field0));
+ }
+
+ @override
+ int get hashCode => Object.hash(runtimeType, field0);
+
+ /// Create a copy of TorError
+ /// with the given fields replaced by the non-null parameter values.
+ @JsonKey(includeFromJson: false, includeToJson: false)
+ @override
+ @pragma('vm:prefer-inline')
+ _$$TorError_ProxyStartErrorImplCopyWith<_$TorError_ProxyStartErrorImpl>
+ get copyWith => __$$TorError_ProxyStartErrorImplCopyWithImpl<
+ _$TorError_ProxyStartErrorImpl>(this, _$identity);
+
+ @override
+ @optionalTypeArgs
+ TResult when({
+ required TResult Function(String field0) bootstrapError,
+ required TResult Function(String field0) proxyStartError,
+ required TResult Function(String field0) proxyStopError,
+ required TResult Function() clientNotInitialized,
+ required TResult Function(String field0) runtimeError,
+ required TResult Function(String field0) configError,
+ }) {
+ return proxyStartError(field0);
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult? whenOrNull({
+ TResult? Function(String field0)? bootstrapError,
+ TResult? Function(String field0)? proxyStartError,
+ TResult? Function(String field0)? proxyStopError,
+ TResult? Function()? clientNotInitialized,
+ TResult? Function(String field0)? runtimeError,
+ TResult? Function(String field0)? configError,
+ }) {
+ return proxyStartError?.call(field0);
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult maybeWhen({
+ TResult Function(String field0)? bootstrapError,
+ TResult Function(String field0)? proxyStartError,
+ TResult Function(String field0)? proxyStopError,
+ TResult Function()? clientNotInitialized,
+ TResult Function(String field0)? runtimeError,
+ TResult Function(String field0)? configError,
+ required TResult orElse(),
+ }) {
+ if (proxyStartError != null) {
+ return proxyStartError(field0);
+ }
+ return orElse();
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult map({
+ required TResult Function(TorError_BootstrapError value) bootstrapError,
+ required TResult Function(TorError_ProxyStartError value) proxyStartError,
+ required TResult Function(TorError_ProxyStopError value) proxyStopError,
+ required TResult Function(TorError_ClientNotInitialized value)
+ clientNotInitialized,
+ required TResult Function(TorError_RuntimeError value) runtimeError,
+ required TResult Function(TorError_ConfigError value) configError,
+ }) {
+ return proxyStartError(this);
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult? mapOrNull({
+ TResult? Function(TorError_BootstrapError value)? bootstrapError,
+ TResult? Function(TorError_ProxyStartError value)? proxyStartError,
+ TResult? Function(TorError_ProxyStopError value)? proxyStopError,
+ TResult? Function(TorError_ClientNotInitialized value)?
+ clientNotInitialized,
+ TResult? Function(TorError_RuntimeError value)? runtimeError,
+ TResult? Function(TorError_ConfigError value)? configError,
+ }) {
+ return proxyStartError?.call(this);
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult maybeMap({
+ TResult Function(TorError_BootstrapError value)? bootstrapError,
+ TResult Function(TorError_ProxyStartError value)? proxyStartError,
+ TResult Function(TorError_ProxyStopError value)? proxyStopError,
+ TResult Function(TorError_ClientNotInitialized value)? clientNotInitialized,
+ TResult Function(TorError_RuntimeError value)? runtimeError,
+ TResult Function(TorError_ConfigError value)? configError,
+ required TResult orElse(),
+ }) {
+ if (proxyStartError != null) {
+ return proxyStartError(this);
+ }
+ return orElse();
+ }
+}
+
+abstract class TorError_ProxyStartError extends TorError {
+ const factory TorError_ProxyStartError(final String field0) =
+ _$TorError_ProxyStartErrorImpl;
+ const TorError_ProxyStartError._() : super._();
+
+ String get field0;
+
+ /// Create a copy of TorError
+ /// with the given fields replaced by the non-null parameter values.
+ @JsonKey(includeFromJson: false, includeToJson: false)
+ _$$TorError_ProxyStartErrorImplCopyWith<_$TorError_ProxyStartErrorImpl>
+ get copyWith => throw _privateConstructorUsedError;
+}
+
+/// @nodoc
+abstract class _$$TorError_ProxyStopErrorImplCopyWith<$Res> {
+ factory _$$TorError_ProxyStopErrorImplCopyWith(
+ _$TorError_ProxyStopErrorImpl value,
+ $Res Function(_$TorError_ProxyStopErrorImpl) then) =
+ __$$TorError_ProxyStopErrorImplCopyWithImpl<$Res>;
+ @useResult
+ $Res call({String field0});
+}
+
+/// @nodoc
+class __$$TorError_ProxyStopErrorImplCopyWithImpl<$Res>
+ extends _$TorErrorCopyWithImpl<$Res, _$TorError_ProxyStopErrorImpl>
+ implements _$$TorError_ProxyStopErrorImplCopyWith<$Res> {
+ __$$TorError_ProxyStopErrorImplCopyWithImpl(
+ _$TorError_ProxyStopErrorImpl _value,
+ $Res Function(_$TorError_ProxyStopErrorImpl) _then)
+ : super(_value, _then);
+
+ /// Create a copy of TorError
+ /// with the given fields replaced by the non-null parameter values.
+ @pragma('vm:prefer-inline')
+ @override
+ $Res call({
+ Object? field0 = null,
+ }) {
+ return _then(_$TorError_ProxyStopErrorImpl(
+ null == field0
+ ? _value.field0
+ : field0 // ignore: cast_nullable_to_non_nullable
+ as String,
+ ));
+ }
+}
+
+/// @nodoc
+
+class _$TorError_ProxyStopErrorImpl extends TorError_ProxyStopError {
+ const _$TorError_ProxyStopErrorImpl(this.field0) : super._();
+
+ @override
+ final String field0;
+
+ @override
+ String toString() {
+ return 'TorError.proxyStopError(field0: $field0)';
+ }
+
+ @override
+ bool operator ==(Object other) {
+ return identical(this, other) ||
+ (other.runtimeType == runtimeType &&
+ other is _$TorError_ProxyStopErrorImpl &&
+ (identical(other.field0, field0) || other.field0 == field0));
+ }
+
+ @override
+ int get hashCode => Object.hash(runtimeType, field0);
+
+ /// Create a copy of TorError
+ /// with the given fields replaced by the non-null parameter values.
+ @JsonKey(includeFromJson: false, includeToJson: false)
+ @override
+ @pragma('vm:prefer-inline')
+ _$$TorError_ProxyStopErrorImplCopyWith<_$TorError_ProxyStopErrorImpl>
+ get copyWith => __$$TorError_ProxyStopErrorImplCopyWithImpl<
+ _$TorError_ProxyStopErrorImpl>(this, _$identity);
+
+ @override
+ @optionalTypeArgs
+ TResult when({
+ required TResult Function(String field0) bootstrapError,
+ required TResult Function(String field0) proxyStartError,
+ required TResult Function(String field0) proxyStopError,
+ required TResult Function() clientNotInitialized,
+ required TResult Function(String field0) runtimeError,
+ required TResult Function(String field0) configError,
+ }) {
+ return proxyStopError(field0);
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult? whenOrNull({
+ TResult? Function(String field0)? bootstrapError,
+ TResult? Function(String field0)? proxyStartError,
+ TResult? Function(String field0)? proxyStopError,
+ TResult? Function()? clientNotInitialized,
+ TResult? Function(String field0)? runtimeError,
+ TResult? Function(String field0)? configError,
+ }) {
+ return proxyStopError?.call(field0);
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult maybeWhen({
+ TResult Function(String field0)? bootstrapError,
+ TResult Function(String field0)? proxyStartError,
+ TResult Function(String field0)? proxyStopError,
+ TResult Function()? clientNotInitialized,
+ TResult Function(String field0)? runtimeError,
+ TResult Function(String field0)? configError,
+ required TResult orElse(),
+ }) {
+ if (proxyStopError != null) {
+ return proxyStopError(field0);
+ }
+ return orElse();
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult map({
+ required TResult Function(TorError_BootstrapError value) bootstrapError,
+ required TResult Function(TorError_ProxyStartError value) proxyStartError,
+ required TResult Function(TorError_ProxyStopError value) proxyStopError,
+ required TResult Function(TorError_ClientNotInitialized value)
+ clientNotInitialized,
+ required TResult Function(TorError_RuntimeError value) runtimeError,
+ required TResult Function(TorError_ConfigError value) configError,
+ }) {
+ return proxyStopError(this);
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult? mapOrNull({
+ TResult? Function(TorError_BootstrapError value)? bootstrapError,
+ TResult? Function(TorError_ProxyStartError value)? proxyStartError,
+ TResult? Function(TorError_ProxyStopError value)? proxyStopError,
+ TResult? Function(TorError_ClientNotInitialized value)?
+ clientNotInitialized,
+ TResult? Function(TorError_RuntimeError value)? runtimeError,
+ TResult? Function(TorError_ConfigError value)? configError,
+ }) {
+ return proxyStopError?.call(this);
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult maybeMap({
+ TResult Function(TorError_BootstrapError value)? bootstrapError,
+ TResult Function(TorError_ProxyStartError value)? proxyStartError,
+ TResult Function(TorError_ProxyStopError value)? proxyStopError,
+ TResult Function(TorError_ClientNotInitialized value)? clientNotInitialized,
+ TResult Function(TorError_RuntimeError value)? runtimeError,
+ TResult Function(TorError_ConfigError value)? configError,
+ required TResult orElse(),
+ }) {
+ if (proxyStopError != null) {
+ return proxyStopError(this);
+ }
+ return orElse();
+ }
+}
+
+abstract class TorError_ProxyStopError extends TorError {
+ const factory TorError_ProxyStopError(final String field0) =
+ _$TorError_ProxyStopErrorImpl;
+ const TorError_ProxyStopError._() : super._();
+
+ String get field0;
+
+ /// Create a copy of TorError
+ /// with the given fields replaced by the non-null parameter values.
+ @JsonKey(includeFromJson: false, includeToJson: false)
+ _$$TorError_ProxyStopErrorImplCopyWith<_$TorError_ProxyStopErrorImpl>
+ get copyWith => throw _privateConstructorUsedError;
+}
+
+/// @nodoc
+abstract class _$$TorError_ClientNotInitializedImplCopyWith<$Res> {
+ factory _$$TorError_ClientNotInitializedImplCopyWith(
+ _$TorError_ClientNotInitializedImpl value,
+ $Res Function(_$TorError_ClientNotInitializedImpl) then) =
+ __$$TorError_ClientNotInitializedImplCopyWithImpl<$Res>;
+}
+
+/// @nodoc
+class __$$TorError_ClientNotInitializedImplCopyWithImpl<$Res>
+ extends _$TorErrorCopyWithImpl<$Res, _$TorError_ClientNotInitializedImpl>
+ implements _$$TorError_ClientNotInitializedImplCopyWith<$Res> {
+ __$$TorError_ClientNotInitializedImplCopyWithImpl(
+ _$TorError_ClientNotInitializedImpl _value,
+ $Res Function(_$TorError_ClientNotInitializedImpl) _then)
+ : super(_value, _then);
+
+ /// Create a copy of TorError
+ /// with the given fields replaced by the non-null parameter values.
+}
+
+/// @nodoc
+
+class _$TorError_ClientNotInitializedImpl
+ extends TorError_ClientNotInitialized {
+ const _$TorError_ClientNotInitializedImpl() : super._();
+
+ @override
+ String toString() {
+ return 'TorError.clientNotInitialized()';
+ }
+
+ @override
+ bool operator ==(Object other) {
+ return identical(this, other) ||
+ (other.runtimeType == runtimeType &&
+ other is _$TorError_ClientNotInitializedImpl);
+ }
+
+ @override
+ int get hashCode => runtimeType.hashCode;
+
+ @override
+ @optionalTypeArgs
+ TResult when({
+ required TResult Function(String field0) bootstrapError,
+ required TResult Function(String field0) proxyStartError,
+ required TResult Function(String field0) proxyStopError,
+ required TResult Function() clientNotInitialized,
+ required TResult Function(String field0) runtimeError,
+ required TResult Function(String field0) configError,
+ }) {
+ return clientNotInitialized();
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult? whenOrNull({
+ TResult? Function(String field0)? bootstrapError,
+ TResult? Function(String field0)? proxyStartError,
+ TResult? Function(String field0)? proxyStopError,
+ TResult? Function()? clientNotInitialized,
+ TResult? Function(String field0)? runtimeError,
+ TResult? Function(String field0)? configError,
+ }) {
+ return clientNotInitialized?.call();
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult maybeWhen({
+ TResult Function(String field0)? bootstrapError,
+ TResult Function(String field0)? proxyStartError,
+ TResult Function(String field0)? proxyStopError,
+ TResult Function()? clientNotInitialized,
+ TResult Function(String field0)? runtimeError,
+ TResult Function(String field0)? configError,
+ required TResult orElse(),
+ }) {
+ if (clientNotInitialized != null) {
+ return clientNotInitialized();
+ }
+ return orElse();
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult map({
+ required TResult Function(TorError_BootstrapError value) bootstrapError,
+ required TResult Function(TorError_ProxyStartError value) proxyStartError,
+ required TResult Function(TorError_ProxyStopError value) proxyStopError,
+ required TResult Function(TorError_ClientNotInitialized value)
+ clientNotInitialized,
+ required TResult Function(TorError_RuntimeError value) runtimeError,
+ required TResult Function(TorError_ConfigError value) configError,
+ }) {
+ return clientNotInitialized(this);
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult? mapOrNull({
+ TResult? Function(TorError_BootstrapError value)? bootstrapError,
+ TResult? Function(TorError_ProxyStartError value)? proxyStartError,
+ TResult? Function(TorError_ProxyStopError value)? proxyStopError,
+ TResult? Function(TorError_ClientNotInitialized value)?
+ clientNotInitialized,
+ TResult? Function(TorError_RuntimeError value)? runtimeError,
+ TResult? Function(TorError_ConfigError value)? configError,
+ }) {
+ return clientNotInitialized?.call(this);
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult maybeMap({
+ TResult Function(TorError_BootstrapError value)? bootstrapError,
+ TResult Function(TorError_ProxyStartError value)? proxyStartError,
+ TResult Function(TorError_ProxyStopError value)? proxyStopError,
+ TResult Function(TorError_ClientNotInitialized value)? clientNotInitialized,
+ TResult Function(TorError_RuntimeError value)? runtimeError,
+ TResult Function(TorError_ConfigError value)? configError,
+ required TResult orElse(),
+ }) {
+ if (clientNotInitialized != null) {
+ return clientNotInitialized(this);
+ }
+ return orElse();
+ }
+}
+
+abstract class TorError_ClientNotInitialized extends TorError {
+ const factory TorError_ClientNotInitialized() =
+ _$TorError_ClientNotInitializedImpl;
+ const TorError_ClientNotInitialized._() : super._();
+}
+
+/// @nodoc
+abstract class _$$TorError_RuntimeErrorImplCopyWith<$Res> {
+ factory _$$TorError_RuntimeErrorImplCopyWith(
+ _$TorError_RuntimeErrorImpl value,
+ $Res Function(_$TorError_RuntimeErrorImpl) then) =
+ __$$TorError_RuntimeErrorImplCopyWithImpl<$Res>;
+ @useResult
+ $Res call({String field0});
+}
+
+/// @nodoc
+class __$$TorError_RuntimeErrorImplCopyWithImpl<$Res>
+ extends _$TorErrorCopyWithImpl<$Res, _$TorError_RuntimeErrorImpl>
+ implements _$$TorError_RuntimeErrorImplCopyWith<$Res> {
+ __$$TorError_RuntimeErrorImplCopyWithImpl(_$TorError_RuntimeErrorImpl _value,
+ $Res Function(_$TorError_RuntimeErrorImpl) _then)
+ : super(_value, _then);
+
+ /// Create a copy of TorError
+ /// with the given fields replaced by the non-null parameter values.
+ @pragma('vm:prefer-inline')
+ @override
+ $Res call({
+ Object? field0 = null,
+ }) {
+ return _then(_$TorError_RuntimeErrorImpl(
+ null == field0
+ ? _value.field0
+ : field0 // ignore: cast_nullable_to_non_nullable
+ as String,
+ ));
+ }
+}
+
+/// @nodoc
+
+class _$TorError_RuntimeErrorImpl extends TorError_RuntimeError {
+ const _$TorError_RuntimeErrorImpl(this.field0) : super._();
+
+ @override
+ final String field0;
+
+ @override
+ String toString() {
+ return 'TorError.runtimeError(field0: $field0)';
+ }
+
+ @override
+ bool operator ==(Object other) {
+ return identical(this, other) ||
+ (other.runtimeType == runtimeType &&
+ other is _$TorError_RuntimeErrorImpl &&
+ (identical(other.field0, field0) || other.field0 == field0));
+ }
+
+ @override
+ int get hashCode => Object.hash(runtimeType, field0);
+
+ /// Create a copy of TorError
+ /// with the given fields replaced by the non-null parameter values.
+ @JsonKey(includeFromJson: false, includeToJson: false)
+ @override
+ @pragma('vm:prefer-inline')
+ _$$TorError_RuntimeErrorImplCopyWith<_$TorError_RuntimeErrorImpl>
+ get copyWith => __$$TorError_RuntimeErrorImplCopyWithImpl<
+ _$TorError_RuntimeErrorImpl>(this, _$identity);
+
+ @override
+ @optionalTypeArgs
+ TResult when({
+ required TResult Function(String field0) bootstrapError,
+ required TResult Function(String field0) proxyStartError,
+ required TResult Function(String field0) proxyStopError,
+ required TResult Function() clientNotInitialized,
+ required TResult Function(String field0) runtimeError,
+ required TResult Function(String field0) configError,
+ }) {
+ return runtimeError(field0);
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult? whenOrNull({
+ TResult? Function(String field0)? bootstrapError,
+ TResult? Function(String field0)? proxyStartError,
+ TResult? Function(String field0)? proxyStopError,
+ TResult? Function()? clientNotInitialized,
+ TResult? Function(String field0)? runtimeError,
+ TResult? Function(String field0)? configError,
+ }) {
+ return runtimeError?.call(field0);
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult maybeWhen({
+ TResult Function(String field0)? bootstrapError,
+ TResult Function(String field0)? proxyStartError,
+ TResult Function(String field0)? proxyStopError,
+ TResult Function()? clientNotInitialized,
+ TResult Function(String field0)? runtimeError,
+ TResult Function(String field0)? configError,
+ required TResult orElse(),
+ }) {
+ if (runtimeError != null) {
+ return runtimeError(field0);
+ }
+ return orElse();
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult map({
+ required TResult Function(TorError_BootstrapError value) bootstrapError,
+ required TResult Function(TorError_ProxyStartError value) proxyStartError,
+ required TResult Function(TorError_ProxyStopError value) proxyStopError,
+ required TResult Function(TorError_ClientNotInitialized value)
+ clientNotInitialized,
+ required TResult Function(TorError_RuntimeError value) runtimeError,
+ required TResult Function(TorError_ConfigError value) configError,
+ }) {
+ return runtimeError(this);
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult? mapOrNull({
+ TResult? Function(TorError_BootstrapError value)? bootstrapError,
+ TResult? Function(TorError_ProxyStartError value)? proxyStartError,
+ TResult? Function(TorError_ProxyStopError value)? proxyStopError,
+ TResult? Function(TorError_ClientNotInitialized value)?
+ clientNotInitialized,
+ TResult? Function(TorError_RuntimeError value)? runtimeError,
+ TResult? Function(TorError_ConfigError value)? configError,
+ }) {
+ return runtimeError?.call(this);
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult maybeMap({
+ TResult Function(TorError_BootstrapError value)? bootstrapError,
+ TResult Function(TorError_ProxyStartError value)? proxyStartError,
+ TResult Function(TorError_ProxyStopError value)? proxyStopError,
+ TResult Function(TorError_ClientNotInitialized value)? clientNotInitialized,
+ TResult Function(TorError_RuntimeError value)? runtimeError,
+ TResult Function(TorError_ConfigError value)? configError,
+ required TResult orElse(),
+ }) {
+ if (runtimeError != null) {
+ return runtimeError(this);
+ }
+ return orElse();
+ }
+}
+
+abstract class TorError_RuntimeError extends TorError {
+ const factory TorError_RuntimeError(final String field0) =
+ _$TorError_RuntimeErrorImpl;
+ const TorError_RuntimeError._() : super._();
+
+ String get field0;
+
+ /// Create a copy of TorError
+ /// with the given fields replaced by the non-null parameter values.
+ @JsonKey(includeFromJson: false, includeToJson: false)
+ _$$TorError_RuntimeErrorImplCopyWith<_$TorError_RuntimeErrorImpl>
+ get copyWith => throw _privateConstructorUsedError;
+}
+
+/// @nodoc
+abstract class _$$TorError_ConfigErrorImplCopyWith<$Res> {
+ factory _$$TorError_ConfigErrorImplCopyWith(_$TorError_ConfigErrorImpl value,
+ $Res Function(_$TorError_ConfigErrorImpl) then) =
+ __$$TorError_ConfigErrorImplCopyWithImpl<$Res>;
+ @useResult
+ $Res call({String field0});
+}
+
+/// @nodoc
+class __$$TorError_ConfigErrorImplCopyWithImpl<$Res>
+ extends _$TorErrorCopyWithImpl<$Res, _$TorError_ConfigErrorImpl>
+ implements _$$TorError_ConfigErrorImplCopyWith<$Res> {
+ __$$TorError_ConfigErrorImplCopyWithImpl(_$TorError_ConfigErrorImpl _value,
+ $Res Function(_$TorError_ConfigErrorImpl) _then)
+ : super(_value, _then);
+
+ /// Create a copy of TorError
+ /// with the given fields replaced by the non-null parameter values.
+ @pragma('vm:prefer-inline')
+ @override
+ $Res call({
+ Object? field0 = null,
+ }) {
+ return _then(_$TorError_ConfigErrorImpl(
+ null == field0
+ ? _value.field0
+ : field0 // ignore: cast_nullable_to_non_nullable
+ as String,
+ ));
+ }
+}
+
+/// @nodoc
+
+class _$TorError_ConfigErrorImpl extends TorError_ConfigError {
+ const _$TorError_ConfigErrorImpl(this.field0) : super._();
+
+ @override
+ final String field0;
+
+ @override
+ String toString() {
+ return 'TorError.configError(field0: $field0)';
+ }
+
+ @override
+ bool operator ==(Object other) {
+ return identical(this, other) ||
+ (other.runtimeType == runtimeType &&
+ other is _$TorError_ConfigErrorImpl &&
+ (identical(other.field0, field0) || other.field0 == field0));
+ }
+
+ @override
+ int get hashCode => Object.hash(runtimeType, field0);
+
+ /// Create a copy of TorError
+ /// with the given fields replaced by the non-null parameter values.
+ @JsonKey(includeFromJson: false, includeToJson: false)
+ @override
+ @pragma('vm:prefer-inline')
+ _$$TorError_ConfigErrorImplCopyWith<_$TorError_ConfigErrorImpl>
+ get copyWith =>
+ __$$TorError_ConfigErrorImplCopyWithImpl<_$TorError_ConfigErrorImpl>(
+ this, _$identity);
+
+ @override
+ @optionalTypeArgs
+ TResult when({
+ required TResult Function(String field0) bootstrapError,
+ required TResult Function(String field0) proxyStartError,
+ required TResult Function(String field0) proxyStopError,
+ required TResult Function() clientNotInitialized,
+ required TResult Function(String field0) runtimeError,
+ required TResult Function(String field0) configError,
+ }) {
+ return configError(field0);
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult? whenOrNull({
+ TResult? Function(String field0)? bootstrapError,
+ TResult? Function(String field0)? proxyStartError,
+ TResult? Function(String field0)? proxyStopError,
+ TResult? Function()? clientNotInitialized,
+ TResult? Function(String field0)? runtimeError,
+ TResult? Function(String field0)? configError,
+ }) {
+ return configError?.call(field0);
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult maybeWhen({
+ TResult Function(String field0)? bootstrapError,
+ TResult Function(String field0)? proxyStartError,
+ TResult Function(String field0)? proxyStopError,
+ TResult Function()? clientNotInitialized,
+ TResult Function(String field0)? runtimeError,
+ TResult Function(String field0)? configError,
+ required TResult orElse(),
+ }) {
+ if (configError != null) {
+ return configError(field0);
+ }
+ return orElse();
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult map({
+ required TResult Function(TorError_BootstrapError value) bootstrapError,
+ required TResult Function(TorError_ProxyStartError value) proxyStartError,
+ required TResult Function(TorError_ProxyStopError value) proxyStopError,
+ required TResult Function(TorError_ClientNotInitialized value)
+ clientNotInitialized,
+ required TResult Function(TorError_RuntimeError value) runtimeError,
+ required TResult Function(TorError_ConfigError value) configError,
+ }) {
+ return configError(this);
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult? mapOrNull({
+ TResult? Function(TorError_BootstrapError value)? bootstrapError,
+ TResult? Function(TorError_ProxyStartError value)? proxyStartError,
+ TResult? Function(TorError_ProxyStopError value)? proxyStopError,
+ TResult? Function(TorError_ClientNotInitialized value)?
+ clientNotInitialized,
+ TResult? Function(TorError_RuntimeError value)? runtimeError,
+ TResult? Function(TorError_ConfigError value)? configError,
+ }) {
+ return configError?.call(this);
+ }
+
+ @override
+ @optionalTypeArgs
+ TResult maybeMap({
+ TResult Function(TorError_BootstrapError value)? bootstrapError,
+ TResult Function(TorError_ProxyStartError value)? proxyStartError,
+ TResult Function(TorError_ProxyStopError value)? proxyStopError,
+ TResult Function(TorError_ClientNotInitialized value)? clientNotInitialized,
+ TResult Function(TorError_RuntimeError value)? runtimeError,
+ TResult Function(TorError_ConfigError value)? configError,
+ required TResult orElse(),
+ }) {
+ if (configError != null) {
+ return configError(this);
+ }
+ return orElse();
+ }
+}
+
+abstract class TorError_ConfigError extends TorError {
+ const factory TorError_ConfigError(final String field0) =
+ _$TorError_ConfigErrorImpl;
+ const TorError_ConfigError._() : super._();
+
+ String get field0;
+
+ /// Create a copy of TorError
+ /// with the given fields replaced by the non-null parameter values.
+ @JsonKey(includeFromJson: false, includeToJson: false)
+ _$$TorError_ConfigErrorImplCopyWith<_$TorError_ConfigErrorImpl>
+ get copyWith => throw _privateConstructorUsedError;
+}
diff --git a/lib/src/rust/frb_generated.dart b/lib/src/rust/frb_generated.dart
new file mode 100644
index 00000000..1981191c
--- /dev/null
+++ b/lib/src/rust/frb_generated.dart
@@ -0,0 +1,1111 @@
+// This file is automatically generated, so please do not edit it.
+// @generated by `flutter_rust_bridge`@ 2.11.1.
+
+// ignore_for_file: unused_import, unused_element, unnecessary_import, duplicate_ignore, invalid_use_of_internal_member, annotate_overrides, non_constant_identifier_names, curly_braces_in_flow_control_structures, prefer_const_literals_to_create_immutables, unused_field
+
+import 'api/tor.dart';
+import 'dart:async';
+import 'dart:convert';
+import 'frb_generated.dart';
+import 'frb_generated.io.dart'
+ if (dart.library.js_interop) 'frb_generated.web.dart';
+import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
+
+/// Main entrypoint of the Rust API
+class RustLib extends BaseEntrypoint {
+ @internal
+ static final instance = RustLib._();
+
+ RustLib._();
+
+ /// Initialize flutter_rust_bridge
+ static Future init({
+ RustLibApi? api,
+ BaseHandler? handler,
+ ExternalLibrary? externalLibrary,
+ bool forceSameCodegenVersion = true,
+ }) async {
+ await instance.initImpl(
+ api: api,
+ handler: handler,
+ externalLibrary: externalLibrary,
+ forceSameCodegenVersion: forceSameCodegenVersion,
+ );
+ }
+
+ /// Initialize flutter_rust_bridge in mock mode.
+ /// No libraries for FFI are loaded.
+ static void initMock({
+ required RustLibApi api,
+ }) {
+ instance.initMockImpl(
+ api: api,
+ );
+ }
+
+ /// Dispose flutter_rust_bridge
+ ///
+ /// The call to this function is optional, since flutter_rust_bridge (and everything else)
+ /// is automatically disposed when the app stops.
+ static void dispose() => instance.disposeImpl();
+
+ @override
+ ApiImplConstructor get apiImplConstructor =>
+ RustLibApiImpl.new;
+
+ @override
+ WireConstructor get wireConstructor =>
+ RustLibWire.fromExternalLibrary;
+
+ @override
+ Future executeRustInitializers() async {
+ await api.crateApiTorInitApp();
+ }
+
+ @override
+ ExternalLibraryLoaderConfig get defaultExternalLibraryLoaderConfig =>
+ kDefaultExternalLibraryLoaderConfig;
+
+ @override
+ String get codegenVersion => '2.11.1';
+
+ @override
+ int get rustContentHash => 333622112;
+
+ static const kDefaultExternalLibraryLoaderConfig =
+ ExternalLibraryLoaderConfig(
+ stem: 'rust_lib_tor',
+ ioDirectory: 'rust/target/release/',
+ webPrefix: 'pkg/',
+ );
+}
+
+abstract class RustLibApi extends BaseApi {
+ TorClientWrapper crateApiTorTorInstanceAutoAccessorGetClient(
+ {required TorInstance that});
+
+ TorProxyHandle crateApiTorTorInstanceAutoAccessorGetProxy(
+ {required TorInstance that});
+
+ int crateApiTorTorInstanceAutoAccessorGetSocksPort(
+ {required TorInstance that});
+
+ void crateApiTorTorInstanceAutoAccessorSetClient(
+ {required TorInstance that, required TorClientWrapper client});
+
+ void crateApiTorTorInstanceAutoAccessorSetProxy(
+ {required TorInstance that, required TorProxyHandle proxy});
+
+ void crateApiTorTorInstanceAutoAccessorSetSocksPort(
+ {required TorInstance that, required int socksPort});
+
+ Future crateApiTorBootstrap({required TorClientWrapper client});
+
+ Future crateApiTorGetNofileLimit();
+
+ Future crateApiTorHello();
+
+ Future crateApiTorInitApp();
+
+ Future crateApiTorSetDormant(
+ {required TorClientWrapper client, required bool softMode});
+
+ Future crateApiTorSetNofileLimit({required BigInt limit});
+
+ Future crateApiTorStartTor(
+ {required int socksPort,
+ required String stateDir,
+ required String cacheDir});
+
+ Future crateApiTorStopProxy({required TorProxyHandle proxy});
+
+ RustArcIncrementStrongCountFnType
+ get rust_arc_increment_strong_count_TorClientWrapper;
+
+ RustArcDecrementStrongCountFnType
+ get rust_arc_decrement_strong_count_TorClientWrapper;
+
+ CrossPlatformFinalizerArg
+ get rust_arc_decrement_strong_count_TorClientWrapperPtr;
+
+ RustArcIncrementStrongCountFnType
+ get rust_arc_increment_strong_count_TorInstance;
+
+ RustArcDecrementStrongCountFnType
+ get rust_arc_decrement_strong_count_TorInstance;
+
+ CrossPlatformFinalizerArg get rust_arc_decrement_strong_count_TorInstancePtr;
+
+ RustArcIncrementStrongCountFnType
+ get rust_arc_increment_strong_count_TorProxyHandle;
+
+ RustArcDecrementStrongCountFnType
+ get rust_arc_decrement_strong_count_TorProxyHandle;
+
+ CrossPlatformFinalizerArg
+ get rust_arc_decrement_strong_count_TorProxyHandlePtr;
+}
+
+class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
+ RustLibApiImpl({
+ required super.handler,
+ required super.wire,
+ required super.generalizedFrbRustBinding,
+ required super.portManager,
+ });
+
+ @override
+ TorClientWrapper crateApiTorTorInstanceAutoAccessorGetClient(
+ {required TorInstance that}) {
+ return handler.executeSync(SyncTask(
+ callFfi: () {
+ final serializer = SseSerializer(generalizedFrbRustBinding);
+ sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ that, serializer);
+ return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 1)!;
+ },
+ codec: SseCodec(
+ decodeSuccessData:
+ sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper,
+ decodeErrorData: null,
+ ),
+ constMeta: kCrateApiTorTorInstanceAutoAccessorGetClientConstMeta,
+ argValues: [that],
+ apiImpl: this,
+ ));
+ }
+
+ TaskConstMeta get kCrateApiTorTorInstanceAutoAccessorGetClientConstMeta =>
+ const TaskConstMeta(
+ debugName: "TorInstance_auto_accessor_get_client",
+ argNames: ["that"],
+ );
+
+ @override
+ TorProxyHandle crateApiTorTorInstanceAutoAccessorGetProxy(
+ {required TorInstance that}) {
+ return handler.executeSync(SyncTask(
+ callFfi: () {
+ final serializer = SseSerializer(generalizedFrbRustBinding);
+ sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ that, serializer);
+ return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 2)!;
+ },
+ codec: SseCodec(
+ decodeSuccessData:
+ sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle,
+ decodeErrorData: null,
+ ),
+ constMeta: kCrateApiTorTorInstanceAutoAccessorGetProxyConstMeta,
+ argValues: [that],
+ apiImpl: this,
+ ));
+ }
+
+ TaskConstMeta get kCrateApiTorTorInstanceAutoAccessorGetProxyConstMeta =>
+ const TaskConstMeta(
+ debugName: "TorInstance_auto_accessor_get_proxy",
+ argNames: ["that"],
+ );
+
+ @override
+ int crateApiTorTorInstanceAutoAccessorGetSocksPort(
+ {required TorInstance that}) {
+ return handler.executeSync(SyncTask(
+ callFfi: () {
+ final serializer = SseSerializer(generalizedFrbRustBinding);
+ sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ that, serializer);
+ return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 3)!;
+ },
+ codec: SseCodec(
+ decodeSuccessData: sse_decode_u_16,
+ decodeErrorData: null,
+ ),
+ constMeta: kCrateApiTorTorInstanceAutoAccessorGetSocksPortConstMeta,
+ argValues: [that],
+ apiImpl: this,
+ ));
+ }
+
+ TaskConstMeta get kCrateApiTorTorInstanceAutoAccessorGetSocksPortConstMeta =>
+ const TaskConstMeta(
+ debugName: "TorInstance_auto_accessor_get_socks_port",
+ argNames: ["that"],
+ );
+
+ @override
+ void crateApiTorTorInstanceAutoAccessorSetClient(
+ {required TorInstance that, required TorClientWrapper client}) {
+ return handler.executeSync(SyncTask(
+ callFfi: () {
+ final serializer = SseSerializer(generalizedFrbRustBinding);
+ sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ that, serializer);
+ sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ client, serializer);
+ return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 4)!;
+ },
+ codec: SseCodec(
+ decodeSuccessData: sse_decode_unit,
+ decodeErrorData: null,
+ ),
+ constMeta: kCrateApiTorTorInstanceAutoAccessorSetClientConstMeta,
+ argValues: [that, client],
+ apiImpl: this,
+ ));
+ }
+
+ TaskConstMeta get kCrateApiTorTorInstanceAutoAccessorSetClientConstMeta =>
+ const TaskConstMeta(
+ debugName: "TorInstance_auto_accessor_set_client",
+ argNames: ["that", "client"],
+ );
+
+ @override
+ void crateApiTorTorInstanceAutoAccessorSetProxy(
+ {required TorInstance that, required TorProxyHandle proxy}) {
+ return handler.executeSync(SyncTask(
+ callFfi: () {
+ final serializer = SseSerializer(generalizedFrbRustBinding);
+ sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ that, serializer);
+ sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle(
+ proxy, serializer);
+ return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 5)!;
+ },
+ codec: SseCodec(
+ decodeSuccessData: sse_decode_unit,
+ decodeErrorData: null,
+ ),
+ constMeta: kCrateApiTorTorInstanceAutoAccessorSetProxyConstMeta,
+ argValues: [that, proxy],
+ apiImpl: this,
+ ));
+ }
+
+ TaskConstMeta get kCrateApiTorTorInstanceAutoAccessorSetProxyConstMeta =>
+ const TaskConstMeta(
+ debugName: "TorInstance_auto_accessor_set_proxy",
+ argNames: ["that", "proxy"],
+ );
+
+ @override
+ void crateApiTorTorInstanceAutoAccessorSetSocksPort(
+ {required TorInstance that, required int socksPort}) {
+ return handler.executeSync(SyncTask(
+ callFfi: () {
+ final serializer = SseSerializer(generalizedFrbRustBinding);
+ sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ that, serializer);
+ sse_encode_u_16(socksPort, serializer);
+ return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 6)!;
+ },
+ codec: SseCodec(
+ decodeSuccessData: sse_decode_unit,
+ decodeErrorData: null,
+ ),
+ constMeta: kCrateApiTorTorInstanceAutoAccessorSetSocksPortConstMeta,
+ argValues: [that, socksPort],
+ apiImpl: this,
+ ));
+ }
+
+ TaskConstMeta get kCrateApiTorTorInstanceAutoAccessorSetSocksPortConstMeta =>
+ const TaskConstMeta(
+ debugName: "TorInstance_auto_accessor_set_socks_port",
+ argNames: ["that", "socksPort"],
+ );
+
+ @override
+ Future crateApiTorBootstrap({required TorClientWrapper client}) {
+ return handler.executeNormal(NormalTask(
+ callFfi: (port_) {
+ final serializer = SseSerializer(generalizedFrbRustBinding);
+ sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ client, serializer);
+ pdeCallFfi(generalizedFrbRustBinding, serializer,
+ funcId: 7, port: port_);
+ },
+ codec: SseCodec(
+ decodeSuccessData: sse_decode_unit,
+ decodeErrorData: sse_decode_tor_error,
+ ),
+ constMeta: kCrateApiTorBootstrapConstMeta,
+ argValues: [client],
+ apiImpl: this,
+ ));
+ }
+
+ TaskConstMeta get kCrateApiTorBootstrapConstMeta => const TaskConstMeta(
+ debugName: "bootstrap",
+ argNames: ["client"],
+ );
+
+ @override
+ Future crateApiTorGetNofileLimit() {
+ return handler.executeNormal(NormalTask(
+ callFfi: (port_) {
+ final serializer = SseSerializer(generalizedFrbRustBinding);
+ pdeCallFfi(generalizedFrbRustBinding, serializer,
+ funcId: 8, port: port_);
+ },
+ codec: SseCodec(
+ decodeSuccessData: sse_decode_u_64,
+ decodeErrorData: sse_decode_tor_error,
+ ),
+ constMeta: kCrateApiTorGetNofileLimitConstMeta,
+ argValues: [],
+ apiImpl: this,
+ ));
+ }
+
+ TaskConstMeta get kCrateApiTorGetNofileLimitConstMeta => const TaskConstMeta(
+ debugName: "get_nofile_limit",
+ argNames: [],
+ );
+
+ @override
+ Future crateApiTorHello() {
+ return handler.executeNormal(NormalTask(
+ callFfi: (port_) {
+ final serializer = SseSerializer(generalizedFrbRustBinding);
+ pdeCallFfi(generalizedFrbRustBinding, serializer,
+ funcId: 9, port: port_);
+ },
+ codec: SseCodec(
+ decodeSuccessData: sse_decode_unit,
+ decodeErrorData: null,
+ ),
+ constMeta: kCrateApiTorHelloConstMeta,
+ argValues: [],
+ apiImpl: this,
+ ));
+ }
+
+ TaskConstMeta get kCrateApiTorHelloConstMeta => const TaskConstMeta(
+ debugName: "hello",
+ argNames: [],
+ );
+
+ @override
+ Future crateApiTorInitApp() {
+ return handler.executeNormal(NormalTask(
+ callFfi: (port_) {
+ final serializer = SseSerializer(generalizedFrbRustBinding);
+ pdeCallFfi(generalizedFrbRustBinding, serializer,
+ funcId: 10, port: port_);
+ },
+ codec: SseCodec(
+ decodeSuccessData: sse_decode_unit,
+ decodeErrorData: null,
+ ),
+ constMeta: kCrateApiTorInitAppConstMeta,
+ argValues: [],
+ apiImpl: this,
+ ));
+ }
+
+ TaskConstMeta get kCrateApiTorInitAppConstMeta => const TaskConstMeta(
+ debugName: "init_app",
+ argNames: [],
+ );
+
+ @override
+ Future crateApiTorSetDormant(
+ {required TorClientWrapper client, required bool softMode}) {
+ return handler.executeNormal(NormalTask(
+ callFfi: (port_) {
+ final serializer = SseSerializer(generalizedFrbRustBinding);
+ sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ client, serializer);
+ sse_encode_bool(softMode, serializer);
+ pdeCallFfi(generalizedFrbRustBinding, serializer,
+ funcId: 11, port: port_);
+ },
+ codec: SseCodec(
+ decodeSuccessData: sse_decode_unit,
+ decodeErrorData: null,
+ ),
+ constMeta: kCrateApiTorSetDormantConstMeta,
+ argValues: [client, softMode],
+ apiImpl: this,
+ ));
+ }
+
+ TaskConstMeta get kCrateApiTorSetDormantConstMeta => const TaskConstMeta(
+ debugName: "set_dormant",
+ argNames: ["client", "softMode"],
+ );
+
+ @override
+ Future crateApiTorSetNofileLimit({required BigInt limit}) {
+ return handler.executeNormal(NormalTask(
+ callFfi: (port_) {
+ final serializer = SseSerializer(generalizedFrbRustBinding);
+ sse_encode_u_64(limit, serializer);
+ pdeCallFfi(generalizedFrbRustBinding, serializer,
+ funcId: 12, port: port_);
+ },
+ codec: SseCodec(
+ decodeSuccessData: sse_decode_u_64,
+ decodeErrorData: sse_decode_tor_error,
+ ),
+ constMeta: kCrateApiTorSetNofileLimitConstMeta,
+ argValues: [limit],
+ apiImpl: this,
+ ));
+ }
+
+ TaskConstMeta get kCrateApiTorSetNofileLimitConstMeta => const TaskConstMeta(
+ debugName: "set_nofile_limit",
+ argNames: ["limit"],
+ );
+
+ @override
+ Future crateApiTorStartTor(
+ {required int socksPort,
+ required String stateDir,
+ required String cacheDir}) {
+ return handler.executeNormal(NormalTask(
+ callFfi: (port_) {
+ final serializer = SseSerializer(generalizedFrbRustBinding);
+ sse_encode_u_16(socksPort, serializer);
+ sse_encode_String(stateDir, serializer);
+ sse_encode_String(cacheDir, serializer);
+ pdeCallFfi(generalizedFrbRustBinding, serializer,
+ funcId: 13, port: port_);
+ },
+ codec: SseCodec(
+ decodeSuccessData:
+ sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance,
+ decodeErrorData: sse_decode_tor_error,
+ ),
+ constMeta: kCrateApiTorStartTorConstMeta,
+ argValues: [socksPort, stateDir, cacheDir],
+ apiImpl: this,
+ ));
+ }
+
+ TaskConstMeta get kCrateApiTorStartTorConstMeta => const TaskConstMeta(
+ debugName: "start_tor",
+ argNames: ["socksPort", "stateDir", "cacheDir"],
+ );
+
+ @override
+ Future crateApiTorStopProxy({required TorProxyHandle proxy}) {
+ return handler.executeNormal(NormalTask(
+ callFfi: (port_) {
+ final serializer = SseSerializer(generalizedFrbRustBinding);
+ sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle(
+ proxy, serializer);
+ pdeCallFfi(generalizedFrbRustBinding, serializer,
+ funcId: 14, port: port_);
+ },
+ codec: SseCodec(
+ decodeSuccessData: sse_decode_unit,
+ decodeErrorData: sse_decode_tor_error,
+ ),
+ constMeta: kCrateApiTorStopProxyConstMeta,
+ argValues: [proxy],
+ apiImpl: this,
+ ));
+ }
+
+ TaskConstMeta get kCrateApiTorStopProxyConstMeta => const TaskConstMeta(
+ debugName: "stop_proxy",
+ argNames: ["proxy"],
+ );
+
+ RustArcIncrementStrongCountFnType
+ get rust_arc_increment_strong_count_TorClientWrapper => wire
+ .rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper;
+
+ RustArcDecrementStrongCountFnType
+ get rust_arc_decrement_strong_count_TorClientWrapper => wire
+ .rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper;
+
+ RustArcIncrementStrongCountFnType
+ get rust_arc_increment_strong_count_TorInstance => wire
+ .rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance;
+
+ RustArcDecrementStrongCountFnType
+ get rust_arc_decrement_strong_count_TorInstance => wire
+ .rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance;
+
+ RustArcIncrementStrongCountFnType
+ get rust_arc_increment_strong_count_TorProxyHandle => wire
+ .rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle;
+
+ RustArcDecrementStrongCountFnType
+ get rust_arc_decrement_strong_count_TorProxyHandle => wire
+ .rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle;
+
+ @protected
+ TorClientWrapper
+ dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ dynamic raw) {
+ // Codec=Dco (DartCObject based), see doc to use other codecs
+ return TorClientWrapperImpl.frbInternalDcoDecode(raw as List);
+ }
+
+ @protected
+ TorInstance
+ dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ dynamic raw) {
+ // Codec=Dco (DartCObject based), see doc to use other codecs
+ return TorInstanceImpl.frbInternalDcoDecode(raw as List);
+ }
+
+ @protected
+ TorProxyHandle
+ dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle(
+ dynamic raw) {
+ // Codec=Dco (DartCObject based), see doc to use other codecs
+ return TorProxyHandleImpl.frbInternalDcoDecode(raw as List);
+ }
+
+ @protected
+ TorInstance
+ dco_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ dynamic raw) {
+ // Codec=Dco (DartCObject based), see doc to use other codecs
+ return TorInstanceImpl.frbInternalDcoDecode(raw as List);
+ }
+
+ @protected
+ TorClientWrapper
+ dco_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ dynamic raw) {
+ // Codec=Dco (DartCObject based), see doc to use other codecs
+ return TorClientWrapperImpl.frbInternalDcoDecode(raw as List);
+ }
+
+ @protected
+ TorInstance
+ dco_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ dynamic raw) {
+ // Codec=Dco (DartCObject based), see doc to use other codecs
+ return TorInstanceImpl.frbInternalDcoDecode(raw as List);
+ }
+
+ @protected
+ TorClientWrapper
+ dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ dynamic raw) {
+ // Codec=Dco (DartCObject based), see doc to use other codecs
+ return TorClientWrapperImpl.frbInternalDcoDecode(raw as List);
+ }
+
+ @protected
+ TorInstance
+ dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ dynamic raw) {
+ // Codec=Dco (DartCObject based), see doc to use other codecs
+ return TorInstanceImpl.frbInternalDcoDecode(raw as List);
+ }
+
+ @protected
+ TorProxyHandle
+ dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle(
+ dynamic raw) {
+ // Codec=Dco (DartCObject based), see doc to use other codecs
+ return TorProxyHandleImpl.frbInternalDcoDecode(raw as List);
+ }
+
+ @protected
+ String dco_decode_String(dynamic raw) {
+ // Codec=Dco (DartCObject based), see doc to use other codecs
+ return raw as String;
+ }
+
+ @protected
+ bool dco_decode_bool(dynamic raw) {
+ // Codec=Dco (DartCObject based), see doc to use other codecs
+ return raw as bool;
+ }
+
+ @protected
+ Uint8List dco_decode_list_prim_u_8_strict(dynamic raw) {
+ // Codec=Dco (DartCObject based), see doc to use other codecs
+ return raw as Uint8List;
+ }
+
+ @protected
+ TorError dco_decode_tor_error(dynamic raw) {
+ // Codec=Dco (DartCObject based), see doc to use other codecs
+ switch (raw[0]) {
+ case 0:
+ return TorError_BootstrapError(
+ dco_decode_String(raw[1]),
+ );
+ case 1:
+ return TorError_ProxyStartError(
+ dco_decode_String(raw[1]),
+ );
+ case 2:
+ return TorError_ProxyStopError(
+ dco_decode_String(raw[1]),
+ );
+ case 3:
+ return TorError_ClientNotInitialized();
+ case 4:
+ return TorError_RuntimeError(
+ dco_decode_String(raw[1]),
+ );
+ case 5:
+ return TorError_ConfigError(
+ dco_decode_String(raw[1]),
+ );
+ default:
+ throw Exception("unreachable");
+ }
+ }
+
+ @protected
+ int dco_decode_u_16(dynamic raw) {
+ // Codec=Dco (DartCObject based), see doc to use other codecs
+ return raw as int;
+ }
+
+ @protected
+ BigInt dco_decode_u_64(dynamic raw) {
+ // Codec=Dco (DartCObject based), see doc to use other codecs
+ return dcoDecodeU64(raw);
+ }
+
+ @protected
+ int dco_decode_u_8(dynamic raw) {
+ // Codec=Dco (DartCObject based), see doc to use other codecs
+ return raw as int;
+ }
+
+ @protected
+ void dco_decode_unit(dynamic raw) {
+ // Codec=Dco (DartCObject based), see doc to use other codecs
+ return;
+ }
+
+ @protected
+ BigInt dco_decode_usize(dynamic raw) {
+ // Codec=Dco (DartCObject based), see doc to use other codecs
+ return dcoDecodeU64(raw);
+ }
+
+ @protected
+ TorClientWrapper
+ sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ SseDeserializer deserializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ return TorClientWrapperImpl.frbInternalSseDecode(
+ sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
+ }
+
+ @protected
+ TorInstance
+ sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ SseDeserializer deserializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ return TorInstanceImpl.frbInternalSseDecode(
+ sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
+ }
+
+ @protected
+ TorProxyHandle
+ sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle(
+ SseDeserializer deserializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ return TorProxyHandleImpl.frbInternalSseDecode(
+ sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
+ }
+
+ @protected
+ TorInstance
+ sse_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ SseDeserializer deserializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ return TorInstanceImpl.frbInternalSseDecode(
+ sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
+ }
+
+ @protected
+ TorClientWrapper
+ sse_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ SseDeserializer deserializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ return TorClientWrapperImpl.frbInternalSseDecode(
+ sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
+ }
+
+ @protected
+ TorInstance
+ sse_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ SseDeserializer deserializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ return TorInstanceImpl.frbInternalSseDecode(
+ sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
+ }
+
+ @protected
+ TorClientWrapper
+ sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ SseDeserializer deserializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ return TorClientWrapperImpl.frbInternalSseDecode(
+ sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
+ }
+
+ @protected
+ TorInstance
+ sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ SseDeserializer deserializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ return TorInstanceImpl.frbInternalSseDecode(
+ sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
+ }
+
+ @protected
+ TorProxyHandle
+ sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle(
+ SseDeserializer deserializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ return TorProxyHandleImpl.frbInternalSseDecode(
+ sse_decode_usize(deserializer), sse_decode_i_32(deserializer));
+ }
+
+ @protected
+ String sse_decode_String(SseDeserializer deserializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ var inner = sse_decode_list_prim_u_8_strict(deserializer);
+ return utf8.decoder.convert(inner);
+ }
+
+ @protected
+ bool sse_decode_bool(SseDeserializer deserializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ return deserializer.buffer.getUint8() != 0;
+ }
+
+ @protected
+ Uint8List sse_decode_list_prim_u_8_strict(SseDeserializer deserializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ var len_ = sse_decode_i_32(deserializer);
+ return deserializer.buffer.getUint8List(len_);
+ }
+
+ @protected
+ TorError sse_decode_tor_error(SseDeserializer deserializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+
+ var tag_ = sse_decode_i_32(deserializer);
+ switch (tag_) {
+ case 0:
+ var var_field0 = sse_decode_String(deserializer);
+ return TorError_BootstrapError(var_field0);
+ case 1:
+ var var_field0 = sse_decode_String(deserializer);
+ return TorError_ProxyStartError(var_field0);
+ case 2:
+ var var_field0 = sse_decode_String(deserializer);
+ return TorError_ProxyStopError(var_field0);
+ case 3:
+ return TorError_ClientNotInitialized();
+ case 4:
+ var var_field0 = sse_decode_String(deserializer);
+ return TorError_RuntimeError(var_field0);
+ case 5:
+ var var_field0 = sse_decode_String(deserializer);
+ return TorError_ConfigError(var_field0);
+ default:
+ throw UnimplementedError('');
+ }
+ }
+
+ @protected
+ int sse_decode_u_16(SseDeserializer deserializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ return deserializer.buffer.getUint16();
+ }
+
+ @protected
+ BigInt sse_decode_u_64(SseDeserializer deserializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ return deserializer.buffer.getBigUint64();
+ }
+
+ @protected
+ int sse_decode_u_8(SseDeserializer deserializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ return deserializer.buffer.getUint8();
+ }
+
+ @protected
+ void sse_decode_unit(SseDeserializer deserializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ }
+
+ @protected
+ BigInt sse_decode_usize(SseDeserializer deserializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ return deserializer.buffer.getBigUint64();
+ }
+
+ @protected
+ int sse_decode_i_32(SseDeserializer deserializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ return deserializer.buffer.getInt32();
+ }
+
+ @protected
+ void
+ sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ TorClientWrapper self, SseSerializer serializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ sse_encode_usize(
+ (self as TorClientWrapperImpl).frbInternalSseEncode(move: true),
+ serializer);
+ }
+
+ @protected
+ void
+ sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ TorInstance self, SseSerializer serializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ sse_encode_usize(
+ (self as TorInstanceImpl).frbInternalSseEncode(move: true), serializer);
+ }
+
+ @protected
+ void
+ sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle(
+ TorProxyHandle self, SseSerializer serializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ sse_encode_usize(
+ (self as TorProxyHandleImpl).frbInternalSseEncode(move: true),
+ serializer);
+ }
+
+ @protected
+ void
+ sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ TorInstance self, SseSerializer serializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ sse_encode_usize(
+ (self as TorInstanceImpl).frbInternalSseEncode(move: false),
+ serializer);
+ }
+
+ @protected
+ void
+ sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ TorClientWrapper self, SseSerializer serializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ sse_encode_usize(
+ (self as TorClientWrapperImpl).frbInternalSseEncode(move: false),
+ serializer);
+ }
+
+ @protected
+ void
+ sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ TorInstance self, SseSerializer serializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ sse_encode_usize(
+ (self as TorInstanceImpl).frbInternalSseEncode(move: false),
+ serializer);
+ }
+
+ @protected
+ void
+ sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ TorClientWrapper self, SseSerializer serializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ sse_encode_usize(
+ (self as TorClientWrapperImpl).frbInternalSseEncode(move: null),
+ serializer);
+ }
+
+ @protected
+ void
+ sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ TorInstance self, SseSerializer serializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ sse_encode_usize(
+ (self as TorInstanceImpl).frbInternalSseEncode(move: null), serializer);
+ }
+
+ @protected
+ void
+ sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle(
+ TorProxyHandle self, SseSerializer serializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ sse_encode_usize(
+ (self as TorProxyHandleImpl).frbInternalSseEncode(move: null),
+ serializer);
+ }
+
+ @protected
+ void sse_encode_String(String self, SseSerializer serializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ sse_encode_list_prim_u_8_strict(utf8.encoder.convert(self), serializer);
+ }
+
+ @protected
+ void sse_encode_bool(bool self, SseSerializer serializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ serializer.buffer.putUint8(self ? 1 : 0);
+ }
+
+ @protected
+ void sse_encode_list_prim_u_8_strict(
+ Uint8List self, SseSerializer serializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ sse_encode_i_32(self.length, serializer);
+ serializer.buffer.putUint8List(self);
+ }
+
+ @protected
+ void sse_encode_tor_error(TorError self, SseSerializer serializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ switch (self) {
+ case TorError_BootstrapError(field0: final field0):
+ sse_encode_i_32(0, serializer);
+ sse_encode_String(field0, serializer);
+ case TorError_ProxyStartError(field0: final field0):
+ sse_encode_i_32(1, serializer);
+ sse_encode_String(field0, serializer);
+ case TorError_ProxyStopError(field0: final field0):
+ sse_encode_i_32(2, serializer);
+ sse_encode_String(field0, serializer);
+ case TorError_ClientNotInitialized():
+ sse_encode_i_32(3, serializer);
+ case TorError_RuntimeError(field0: final field0):
+ sse_encode_i_32(4, serializer);
+ sse_encode_String(field0, serializer);
+ case TorError_ConfigError(field0: final field0):
+ sse_encode_i_32(5, serializer);
+ sse_encode_String(field0, serializer);
+ }
+ }
+
+ @protected
+ void sse_encode_u_16(int self, SseSerializer serializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ serializer.buffer.putUint16(self);
+ }
+
+ @protected
+ void sse_encode_u_64(BigInt self, SseSerializer serializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ serializer.buffer.putBigUint64(self);
+ }
+
+ @protected
+ void sse_encode_u_8(int self, SseSerializer serializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ serializer.buffer.putUint8(self);
+ }
+
+ @protected
+ void sse_encode_unit(void self, SseSerializer serializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ }
+
+ @protected
+ void sse_encode_usize(BigInt self, SseSerializer serializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ serializer.buffer.putBigUint64(self);
+ }
+
+ @protected
+ void sse_encode_i_32(int self, SseSerializer serializer) {
+ // Codec=Sse (Serialization based), see doc to use other codecs
+ serializer.buffer.putInt32(self);
+ }
+}
+
+@sealed
+class TorClientWrapperImpl extends RustOpaque implements TorClientWrapper {
+ // Not to be used by end users
+ TorClientWrapperImpl.frbInternalDcoDecode(List wire)
+ : super.frbInternalDcoDecode(wire, _kStaticData);
+
+ // Not to be used by end users
+ TorClientWrapperImpl.frbInternalSseDecode(
+ BigInt ptr, int externalSizeOnNative)
+ : super.frbInternalSseDecode(ptr, externalSizeOnNative, _kStaticData);
+
+ static final _kStaticData = RustArcStaticData(
+ rustArcIncrementStrongCount:
+ RustLib.instance.api.rust_arc_increment_strong_count_TorClientWrapper,
+ rustArcDecrementStrongCount:
+ RustLib.instance.api.rust_arc_decrement_strong_count_TorClientWrapper,
+ rustArcDecrementStrongCountPtr: RustLib
+ .instance.api.rust_arc_decrement_strong_count_TorClientWrapperPtr,
+ );
+}
+
+@sealed
+class TorInstanceImpl extends RustOpaque implements TorInstance {
+ // Not to be used by end users
+ TorInstanceImpl.frbInternalDcoDecode(List wire)
+ : super.frbInternalDcoDecode(wire, _kStaticData);
+
+ // Not to be used by end users
+ TorInstanceImpl.frbInternalSseDecode(BigInt ptr, int externalSizeOnNative)
+ : super.frbInternalSseDecode(ptr, externalSizeOnNative, _kStaticData);
+
+ static final _kStaticData = RustArcStaticData(
+ rustArcIncrementStrongCount:
+ RustLib.instance.api.rust_arc_increment_strong_count_TorInstance,
+ rustArcDecrementStrongCount:
+ RustLib.instance.api.rust_arc_decrement_strong_count_TorInstance,
+ rustArcDecrementStrongCountPtr:
+ RustLib.instance.api.rust_arc_decrement_strong_count_TorInstancePtr,
+ );
+
+ TorClientWrapper get client =>
+ RustLib.instance.api.crateApiTorTorInstanceAutoAccessorGetClient(
+ that: this,
+ );
+
+ TorProxyHandle get proxy =>
+ RustLib.instance.api.crateApiTorTorInstanceAutoAccessorGetProxy(
+ that: this,
+ );
+
+ int get socksPort =>
+ RustLib.instance.api.crateApiTorTorInstanceAutoAccessorGetSocksPort(
+ that: this,
+ );
+
+ set client(TorClientWrapper client) => RustLib.instance.api
+ .crateApiTorTorInstanceAutoAccessorSetClient(that: this, client: client);
+
+ set proxy(TorProxyHandle proxy) => RustLib.instance.api
+ .crateApiTorTorInstanceAutoAccessorSetProxy(that: this, proxy: proxy);
+
+ set socksPort(int socksPort) =>
+ RustLib.instance.api.crateApiTorTorInstanceAutoAccessorSetSocksPort(
+ that: this, socksPort: socksPort);
+}
+
+@sealed
+class TorProxyHandleImpl extends RustOpaque implements TorProxyHandle {
+ // Not to be used by end users
+ TorProxyHandleImpl.frbInternalDcoDecode(List wire)
+ : super.frbInternalDcoDecode(wire, _kStaticData);
+
+ // Not to be used by end users
+ TorProxyHandleImpl.frbInternalSseDecode(BigInt ptr, int externalSizeOnNative)
+ : super.frbInternalSseDecode(ptr, externalSizeOnNative, _kStaticData);
+
+ static final _kStaticData = RustArcStaticData(
+ rustArcIncrementStrongCount:
+ RustLib.instance.api.rust_arc_increment_strong_count_TorProxyHandle,
+ rustArcDecrementStrongCount:
+ RustLib.instance.api.rust_arc_decrement_strong_count_TorProxyHandle,
+ rustArcDecrementStrongCountPtr:
+ RustLib.instance.api.rust_arc_decrement_strong_count_TorProxyHandlePtr,
+ );
+}
diff --git a/lib/src/rust/frb_generated.io.dart b/lib/src/rust/frb_generated.io.dart
new file mode 100644
index 00000000..7af0d0b2
--- /dev/null
+++ b/lib/src/rust/frb_generated.io.dart
@@ -0,0 +1,366 @@
+// This file is automatically generated, so please do not edit it.
+// @generated by `flutter_rust_bridge`@ 2.11.1.
+
+// ignore_for_file: unused_import, unused_element, unnecessary_import, duplicate_ignore, invalid_use_of_internal_member, annotate_overrides, non_constant_identifier_names, curly_braces_in_flow_control_structures, prefer_const_literals_to_create_immutables, unused_field
+
+import 'api/tor.dart';
+import 'dart:async';
+import 'dart:convert';
+import 'dart:ffi' as ffi;
+import 'frb_generated.dart';
+import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated_io.dart';
+
+abstract class RustLibApiImplPlatform extends BaseApiImpl {
+ RustLibApiImplPlatform({
+ required super.handler,
+ required super.wire,
+ required super.generalizedFrbRustBinding,
+ required super.portManager,
+ });
+
+ CrossPlatformFinalizerArg
+ get rust_arc_decrement_strong_count_TorClientWrapperPtr => wire
+ ._rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapperPtr;
+
+ CrossPlatformFinalizerArg
+ get rust_arc_decrement_strong_count_TorInstancePtr => wire
+ ._rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstancePtr;
+
+ CrossPlatformFinalizerArg
+ get rust_arc_decrement_strong_count_TorProxyHandlePtr => wire
+ ._rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandlePtr;
+
+ @protected
+ TorClientWrapper
+ dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ dynamic raw);
+
+ @protected
+ TorInstance
+ dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ dynamic raw);
+
+ @protected
+ TorProxyHandle
+ dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle(
+ dynamic raw);
+
+ @protected
+ TorInstance
+ dco_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ dynamic raw);
+
+ @protected
+ TorClientWrapper
+ dco_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ dynamic raw);
+
+ @protected
+ TorInstance
+ dco_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ dynamic raw);
+
+ @protected
+ TorClientWrapper
+ dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ dynamic raw);
+
+ @protected
+ TorInstance
+ dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ dynamic raw);
+
+ @protected
+ TorProxyHandle
+ dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle(
+ dynamic raw);
+
+ @protected
+ String dco_decode_String(dynamic raw);
+
+ @protected
+ bool dco_decode_bool(dynamic raw);
+
+ @protected
+ Uint8List dco_decode_list_prim_u_8_strict(dynamic raw);
+
+ @protected
+ TorError dco_decode_tor_error(dynamic raw);
+
+ @protected
+ int dco_decode_u_16(dynamic raw);
+
+ @protected
+ BigInt dco_decode_u_64(dynamic raw);
+
+ @protected
+ int dco_decode_u_8(dynamic raw);
+
+ @protected
+ void dco_decode_unit(dynamic raw);
+
+ @protected
+ BigInt dco_decode_usize(dynamic raw);
+
+ @protected
+ TorClientWrapper
+ sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ SseDeserializer deserializer);
+
+ @protected
+ TorInstance
+ sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ SseDeserializer deserializer);
+
+ @protected
+ TorProxyHandle
+ sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle(
+ SseDeserializer deserializer);
+
+ @protected
+ TorInstance
+ sse_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ SseDeserializer deserializer);
+
+ @protected
+ TorClientWrapper
+ sse_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ SseDeserializer deserializer);
+
+ @protected
+ TorInstance
+ sse_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ SseDeserializer deserializer);
+
+ @protected
+ TorClientWrapper
+ sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ SseDeserializer deserializer);
+
+ @protected
+ TorInstance
+ sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ SseDeserializer deserializer);
+
+ @protected
+ TorProxyHandle
+ sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle(
+ SseDeserializer deserializer);
+
+ @protected
+ String sse_decode_String(SseDeserializer deserializer);
+
+ @protected
+ bool sse_decode_bool(SseDeserializer deserializer);
+
+ @protected
+ Uint8List sse_decode_list_prim_u_8_strict(SseDeserializer deserializer);
+
+ @protected
+ TorError sse_decode_tor_error(SseDeserializer deserializer);
+
+ @protected
+ int sse_decode_u_16(SseDeserializer deserializer);
+
+ @protected
+ BigInt sse_decode_u_64(SseDeserializer deserializer);
+
+ @protected
+ int sse_decode_u_8(SseDeserializer deserializer);
+
+ @protected
+ void sse_decode_unit(SseDeserializer deserializer);
+
+ @protected
+ BigInt sse_decode_usize(SseDeserializer deserializer);
+
+ @protected
+ int sse_decode_i_32(SseDeserializer deserializer);
+
+ @protected
+ void
+ sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ TorClientWrapper self, SseSerializer serializer);
+
+ @protected
+ void
+ sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ TorInstance self, SseSerializer serializer);
+
+ @protected
+ void
+ sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle(
+ TorProxyHandle self, SseSerializer serializer);
+
+ @protected
+ void
+ sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ TorInstance self, SseSerializer serializer);
+
+ @protected
+ void
+ sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ TorClientWrapper self, SseSerializer serializer);
+
+ @protected
+ void
+ sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ TorInstance self, SseSerializer serializer);
+
+ @protected
+ void
+ sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ TorClientWrapper self, SseSerializer serializer);
+
+ @protected
+ void
+ sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ TorInstance self, SseSerializer serializer);
+
+ @protected
+ void
+ sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle(
+ TorProxyHandle self, SseSerializer serializer);
+
+ @protected
+ void sse_encode_String(String self, SseSerializer serializer);
+
+ @protected
+ void sse_encode_bool(bool self, SseSerializer serializer);
+
+ @protected
+ void sse_encode_list_prim_u_8_strict(
+ Uint8List self, SseSerializer serializer);
+
+ @protected
+ void sse_encode_tor_error(TorError self, SseSerializer serializer);
+
+ @protected
+ void sse_encode_u_16(int self, SseSerializer serializer);
+
+ @protected
+ void sse_encode_u_64(BigInt self, SseSerializer serializer);
+
+ @protected
+ void sse_encode_u_8(int self, SseSerializer serializer);
+
+ @protected
+ void sse_encode_unit(void self, SseSerializer serializer);
+
+ @protected
+ void sse_encode_usize(BigInt self, SseSerializer serializer);
+
+ @protected
+ void sse_encode_i_32(int self, SseSerializer serializer);
+}
+
+// Section: wire_class
+
+class RustLibWire implements BaseWire {
+ factory RustLibWire.fromExternalLibrary(ExternalLibrary lib) =>
+ RustLibWire(lib.ffiDynamicLibrary);
+
+ /// Holds the symbol lookup function.
+ final ffi.Pointer Function(String symbolName)
+ _lookup;
+
+ /// The symbols are looked up in [dynamicLibrary].
+ RustLibWire(ffi.DynamicLibrary dynamicLibrary)
+ : _lookup = dynamicLibrary.lookup;
+
+ void
+ rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ ffi.Pointer ptr,
+ ) {
+ return _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ ptr,
+ );
+ }
+
+ late final _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapperPtr =
+ _lookup)>>(
+ 'frbgen_tor_rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper');
+ late final _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper =
+ _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapperPtr
+ .asFunction)>();
+
+ void
+ rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ ffi.Pointer ptr,
+ ) {
+ return _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ ptr,
+ );
+ }
+
+ late final _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapperPtr =
+ _lookup)>>(
+ 'frbgen_tor_rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper');
+ late final _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper =
+ _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapperPtr
+ .asFunction)>();
+
+ void
+ rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ ffi.Pointer ptr,
+ ) {
+ return _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ ptr,
+ );
+ }
+
+ late final _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstancePtr =
+ _lookup)>>(
+ 'frbgen_tor_rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance');
+ late final _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance =
+ _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstancePtr
+ .asFunction)>();
+
+ void
+ rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ ffi.Pointer ptr,
+ ) {
+ return _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ ptr,
+ );
+ }
+
+ late final _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstancePtr =
+ _lookup)>>(
+ 'frbgen_tor_rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance');
+ late final _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance =
+ _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstancePtr
+ .asFunction)>();
+
+ void
+ rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle(
+ ffi.Pointer ptr,
+ ) {
+ return _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle(
+ ptr,
+ );
+ }
+
+ late final _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandlePtr =
+ _lookup)>>(
+ 'frbgen_tor_rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle');
+ late final _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle =
+ _rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandlePtr
+ .asFunction)>();
+
+ void
+ rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle(
+ ffi.Pointer ptr,
+ ) {
+ return _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle(
+ ptr,
+ );
+ }
+
+ late final _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandlePtr =
+ _lookup)>>(
+ 'frbgen_tor_rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle');
+ late final _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle =
+ _rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandlePtr
+ .asFunction)>();
+}
diff --git a/lib/src/rust/frb_generated.web.dart b/lib/src/rust/frb_generated.web.dart
new file mode 100644
index 00000000..92d347f5
--- /dev/null
+++ b/lib/src/rust/frb_generated.web.dart
@@ -0,0 +1,330 @@
+// This file is automatically generated, so please do not edit it.
+// @generated by `flutter_rust_bridge`@ 2.11.1.
+
+// ignore_for_file: unused_import, unused_element, unnecessary_import, duplicate_ignore, invalid_use_of_internal_member, annotate_overrides, non_constant_identifier_names, curly_braces_in_flow_control_structures, prefer_const_literals_to_create_immutables, unused_field
+
+// Static analysis wrongly picks the IO variant, thus ignore this
+// ignore_for_file: argument_type_not_assignable
+
+import 'api/tor.dart';
+import 'dart:async';
+import 'dart:convert';
+import 'frb_generated.dart';
+import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated_web.dart';
+
+abstract class RustLibApiImplPlatform extends BaseApiImpl {
+ RustLibApiImplPlatform({
+ required super.handler,
+ required super.wire,
+ required super.generalizedFrbRustBinding,
+ required super.portManager,
+ });
+
+ CrossPlatformFinalizerArg
+ get rust_arc_decrement_strong_count_TorClientWrapperPtr => wire
+ .rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper;
+
+ CrossPlatformFinalizerArg
+ get rust_arc_decrement_strong_count_TorInstancePtr => wire
+ .rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance;
+
+ CrossPlatformFinalizerArg
+ get rust_arc_decrement_strong_count_TorProxyHandlePtr => wire
+ .rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle;
+
+ @protected
+ TorClientWrapper
+ dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ dynamic raw);
+
+ @protected
+ TorInstance
+ dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ dynamic raw);
+
+ @protected
+ TorProxyHandle
+ dco_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle(
+ dynamic raw);
+
+ @protected
+ TorInstance
+ dco_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ dynamic raw);
+
+ @protected
+ TorClientWrapper
+ dco_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ dynamic raw);
+
+ @protected
+ TorInstance
+ dco_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ dynamic raw);
+
+ @protected
+ TorClientWrapper
+ dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ dynamic raw);
+
+ @protected
+ TorInstance
+ dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ dynamic raw);
+
+ @protected
+ TorProxyHandle
+ dco_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle(
+ dynamic raw);
+
+ @protected
+ String dco_decode_String(dynamic raw);
+
+ @protected
+ bool dco_decode_bool(dynamic raw);
+
+ @protected
+ Uint8List dco_decode_list_prim_u_8_strict(dynamic raw);
+
+ @protected
+ TorError dco_decode_tor_error(dynamic raw);
+
+ @protected
+ int dco_decode_u_16(dynamic raw);
+
+ @protected
+ BigInt dco_decode_u_64(dynamic raw);
+
+ @protected
+ int dco_decode_u_8(dynamic raw);
+
+ @protected
+ void dco_decode_unit(dynamic raw);
+
+ @protected
+ BigInt dco_decode_usize(dynamic raw);
+
+ @protected
+ TorClientWrapper
+ sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ SseDeserializer deserializer);
+
+ @protected
+ TorInstance
+ sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ SseDeserializer deserializer);
+
+ @protected
+ TorProxyHandle
+ sse_decode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle(
+ SseDeserializer deserializer);
+
+ @protected
+ TorInstance
+ sse_decode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ SseDeserializer deserializer);
+
+ @protected
+ TorClientWrapper
+ sse_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ SseDeserializer deserializer);
+
+ @protected
+ TorInstance
+ sse_decode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ SseDeserializer deserializer);
+
+ @protected
+ TorClientWrapper
+ sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ SseDeserializer deserializer);
+
+ @protected
+ TorInstance
+ sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ SseDeserializer deserializer);
+
+ @protected
+ TorProxyHandle
+ sse_decode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle(
+ SseDeserializer deserializer);
+
+ @protected
+ String sse_decode_String(SseDeserializer deserializer);
+
+ @protected
+ bool sse_decode_bool(SseDeserializer deserializer);
+
+ @protected
+ Uint8List sse_decode_list_prim_u_8_strict(SseDeserializer deserializer);
+
+ @protected
+ TorError sse_decode_tor_error(SseDeserializer deserializer);
+
+ @protected
+ int sse_decode_u_16(SseDeserializer deserializer);
+
+ @protected
+ BigInt sse_decode_u_64(SseDeserializer deserializer);
+
+ @protected
+ int sse_decode_u_8(SseDeserializer deserializer);
+
+ @protected
+ void sse_decode_unit(SseDeserializer deserializer);
+
+ @protected
+ BigInt sse_decode_usize(SseDeserializer deserializer);
+
+ @protected
+ int sse_decode_i_32(SseDeserializer deserializer);
+
+ @protected
+ void
+ sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ TorClientWrapper self, SseSerializer serializer);
+
+ @protected
+ void
+ sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ TorInstance self, SseSerializer serializer);
+
+ @protected
+ void
+ sse_encode_Auto_Owned_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle(
+ TorProxyHandle self, SseSerializer serializer);
+
+ @protected
+ void
+ sse_encode_Auto_RefMut_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ TorInstance self, SseSerializer serializer);
+
+ @protected
+ void
+ sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ TorClientWrapper self, SseSerializer serializer);
+
+ @protected
+ void
+ sse_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ TorInstance self, SseSerializer serializer);
+
+ @protected
+ void
+ sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ TorClientWrapper self, SseSerializer serializer);
+
+ @protected
+ void
+ sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ TorInstance self, SseSerializer serializer);
+
+ @protected
+ void
+ sse_encode_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle(
+ TorProxyHandle self, SseSerializer serializer);
+
+ @protected
+ void sse_encode_String(String self, SseSerializer serializer);
+
+ @protected
+ void sse_encode_bool(bool self, SseSerializer serializer);
+
+ @protected
+ void sse_encode_list_prim_u_8_strict(
+ Uint8List self, SseSerializer serializer);
+
+ @protected
+ void sse_encode_tor_error(TorError self, SseSerializer serializer);
+
+ @protected
+ void sse_encode_u_16(int self, SseSerializer serializer);
+
+ @protected
+ void sse_encode_u_64(BigInt self, SseSerializer serializer);
+
+ @protected
+ void sse_encode_u_8(int self, SseSerializer serializer);
+
+ @protected
+ void sse_encode_unit(void self, SseSerializer serializer);
+
+ @protected
+ void sse_encode_usize(BigInt self, SseSerializer serializer);
+
+ @protected
+ void sse_encode_i_32(int self, SseSerializer serializer);
+}
+
+// Section: wire_class
+
+class RustLibWire implements BaseWire {
+ RustLibWire.fromExternalLibrary(ExternalLibrary lib);
+
+ void rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ int ptr) =>
+ wasmModule
+ .rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ ptr);
+
+ void rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ int ptr) =>
+ wasmModule
+ .rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ ptr);
+
+ void rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ int ptr) =>
+ wasmModule
+ .rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ ptr);
+
+ void rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ int ptr) =>
+ wasmModule
+ .rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ ptr);
+
+ void rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle(
+ int ptr) =>
+ wasmModule
+ .rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle(
+ ptr);
+
+ void rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle(
+ int ptr) =>
+ wasmModule
+ .rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle(
+ ptr);
+}
+
+@JS('wasm_bindgen')
+external RustLibWasmModule get wasmModule;
+
+@JS()
+@anonymous
+extension type RustLibWasmModule._(JSObject _) implements JSObject {
+ external void
+ rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ int ptr);
+
+ external void
+ rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorClientWrapper(
+ int ptr);
+
+ external void
+ rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ int ptr);
+
+ external void
+ rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorInstance(
+ int ptr);
+
+ external void
+ rust_arc_increment_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle(
+ int ptr);
+
+ external void
+ rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerTorProxyHandle(
+ int ptr);
+}
diff --git a/lib/tor.dart b/lib/tor.dart
index f2b57aac..ab4b1dfa 100644
--- a/lib/tor.dart
+++ b/lib/tor.dart
@@ -4,46 +4,43 @@
// SPDX-License-Identifier: MIT
import 'dart:async';
-import 'dart:ffi';
import 'dart:io';
-import 'dart:isolate';
import 'dart:math';
-import 'package:ffi/ffi.dart';
import 'package:flutter/foundation.dart';
+import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
import 'package:path_provider/path_provider.dart';
-import 'package:tor/generated_bindings.dart' as rust;
-
-DynamicLibrary load(String name) {
- if (Platform.isAndroid || Platform.isLinux) {
- return DynamicLibrary.open('lib$name.so');
- } else if (Platform.isIOS || Platform.isMacOS) {
- return DynamicLibrary.open('$name.framework/$name');
- } else if (Platform.isWindows) {
- return DynamicLibrary.open('$name.dll');
- } else {
- throw NotSupportedPlatform('${Platform.operatingSystem} is not supported!');
- }
-}
+
+import 'src/rust/frb_generated.dart';
+import 'src/rust/api/tor.dart' as rust;
+
+export 'src/rust/api/tor.dart' show TorError;
class CouldntBootstrapDirectory implements Exception {
String? rustError;
CouldntBootstrapDirectory({this.rustError});
+
+ @override
+ String toString() => 'CouldntBootstrapDirectory: $rustError';
}
class NotSupportedPlatform implements Exception {
- NotSupportedPlatform(String s);
+ final String platform;
+ NotSupportedPlatform(this.platform);
+
+ @override
+ String toString() => 'NotSupportedPlatform: $platform';
}
-class ClientNotActive implements Exception {}
+class ClientNotActive implements Exception {
+ @override
+ String toString() => 'ClientNotActive: Tor client is not active';
+}
class Tor {
- static const String libName = "tor";
- static late DynamicLibrary _lib;
-
- Pointer _clientPtr = nullptr;
- Pointer _proxyPtr = nullptr;
+ rust.TorClientWrapper? _client;
+ rust.TorProxyHandle? _proxy;
/// Flag to indicate that Tor client and proxy have started. Traffic is routed through the proxy only if it is also [enabled].
bool get started => _started;
@@ -92,6 +89,9 @@ class Tor {
/// Getter for the singleton instance of the Tor class.
static Tor get instance => _instance;
+ /// Whether RustLib has been initialized.
+ static bool _rustLibInitialized = false;
+
/// Initialize the Tor ffi lib instance if it hasn't already been set. Nothing
/// changes if _tor is already been set.
///
@@ -101,13 +101,18 @@ class Tor {
static Future init({bool enabled = true}) async {
var singleton = Tor._instance;
singleton._enabled = enabled;
+
+ // Initialize RustLib if not already done
+ if (!_rustLibInitialized) {
+ await RustLib.init();
+ _rustLibInitialized = true;
+ }
+
return singleton;
}
/// Private constructor for the Tor class.
Tor._internal() {
- _lib = load(libName);
-
if (kDebugMode) {
print("Instance of Tor created!");
}
@@ -155,6 +160,12 @@ class Tor {
Future start() async {
broadcastState();
+ // Ensure RustLib is initialized
+ if (!_rustLibInitialized) {
+ await RustLib.init();
+ _rustLibInitialized = true;
+ }
+
// Set the state and cache directories.
final Directory appSupportDir = await getApplicationSupportDirectory();
final stateDir =
@@ -165,36 +176,27 @@ class Tor {
// Generate a random port.
int newPort = await _getRandomUnusedPort();
- // Start the Tor service in an isolate.
- final tor = await Isolate.run(() async {
- // Load the Tor library.
- var lib = rust.NativeLibrary(load(libName));
-
- // Start the Tor service.
- final tor = lib.tor_start(
- newPort,
- stateDir.path.toNativeUtf8() as Pointer,
- cacheDir.path.toNativeUtf8() as Pointer);
-
- // Throw an exception if the Tor service fails to start.
- if (tor.client == nullptr) {
- throwRustException(lib);
- }
-
- return tor;
- });
-
- // Set the client pointer and started flag.
- _clientPtr = Pointer.fromAddress(tor.client.address);
- _proxyPtr = Pointer.fromAddress(tor.proxy.address);
- _started = true;
-
- // Bootstrap the Tor service.
- bootstrap();
-
- // Set the proxy port.
- _proxyPort = newPort;
- broadcastState();
+ try {
+ // Start Tor - this is a blocking operation
+ final torInstance = await rust.startTor(
+ socksPort: newPort,
+ stateDir: stateDir.path,
+ cacheDir: cacheDir.path,
+ );
+
+ _client = torInstance.client;
+ _proxy = torInstance.proxy;
+ _proxyPort = torInstance.socksPort;
+ _started = true;
+ _bootstrapped = true; // startTor creates a bootstrapped client
+
+ broadcastState();
+ } on rust.TorError catch (e) {
+ throw CouldntBootstrapDirectory(rustError: e.toString());
+ } on PanicException catch (e) {
+ // FRB converts Rust panics to PanicException - this is the key benefit!
+ throw CouldntBootstrapDirectory(rustError: 'Rust panic: ${e.message}');
+ }
}
/// Bootstrap the Tor service.
@@ -207,16 +209,17 @@ class Tor {
/// Throws an exception if the Tor service fails to bootstrap.
///
/// Returns void.
- void bootstrap() {
- // Load the Tor library.
- final lib = rust.NativeLibrary(_lib);
-
- // Bootstrap the Tor service.
- _bootstrapped = lib.tor_client_bootstrap(_clientPtr);
+ Future bootstrap() async {
+ if (_client == null) {
+ throw ClientNotActive();
+ }
- // Throw an exception if the Tor service fails to bootstrap.
- if (!bootstrapped) {
- throwRustException(lib);
+ try {
+ await rust.bootstrap(client: _client!);
+ _bootstrapped = true;
+ } on rust.TorError catch (e) {
+ _bootstrapped = false;
+ throw CouldntBootstrapDirectory(rustError: e.toString());
}
}
@@ -229,25 +232,37 @@ class Tor {
/// Stops the proxy
Future stop() async {
// Return early if already stopped
- if (_proxyPtr == nullptr) {
+ if (_proxy == null) {
return;
}
- final lib = rust.NativeLibrary(_lib);
- lib.tor_proxy_stop(_proxyPtr);
- _proxyPtr = nullptr;
+ try {
+ // This is now safe! FRB catches any panic and throws PanicException
+ await rust.stopProxy(proxy: _proxy!);
+ } on rust.TorError catch (e) {
+ if (kDebugMode) {
+ print('Error stopping proxy: $e');
+ }
+ } on PanicException catch (e) {
+ // Previously this would SIGABRT the app, now it's catchable!
+ if (kDebugMode) {
+ print('Proxy stop panicked (caught safely): ${e.message}');
+ }
+ }
+
+ _proxy = null;
+ _client = null;
_started = false;
_bootstrapped = false;
broadcastState();
}
Future setClientDormant(bool dormant) async {
- if (_clientPtr == nullptr || !started || !bootstrapped) {
+ if (_client == null || !started || !bootstrapped) {
throw ClientNotActive();
}
- final lib = rust.NativeLibrary(_lib);
- lib.tor_client_set_dormant(_clientPtr, dormant);
+ await rust.setDormant(client: _client!, softMode: dormant);
}
Future isReady() async {
@@ -269,21 +284,7 @@ class Tor {
}));
}
- static void throwRustException(rust.NativeLibrary lib) {
- String rustError = lib.tor_last_error_message().cast().toDartString();
-
- throw _getRustException(rustError);
- }
-
- static Exception _getRustException(String rustError) {
- if (rustError.contains('Unable to bootstrap a working directory')) {
- return CouldntBootstrapDirectory(rustError: rustError);
- } else {
- return Exception(rustError);
- }
- }
-
void hello() {
- rust.NativeLibrary(_lib).tor_hello();
+ rust.hello();
}
}
diff --git a/lib/util.dart b/lib/util.dart
index e6557a03..6fd3a71b 100644
--- a/lib/util.dart
+++ b/lib/util.dart
@@ -2,13 +2,14 @@
//
// SPDX-License-Identifier: MIT
-import 'package:tor/generated_bindings.dart' as rust;
-import 'package:tor/tor.dart';
+import 'src/rust/api/tor.dart' as rust;
-int getNofileLimit() {
- return rust.NativeLibrary(load(Tor.libName)).tor_get_nofile_limit();
+Future getNofileLimit() async {
+ final limit = await rust.getNofileLimit();
+ return limit.toInt();
}
-int setNofileLimit(int limit) {
- return rust.NativeLibrary(load(Tor.libName)).tor_set_nofile_limit(limit);
+Future setNofileLimit(int limit) async {
+ final result = await rust.setNofileLimit(limit: BigInt.from(limit));
+ return result.toInt();
}
diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt
index d753f853..46709393 100644
--- a/linux/CMakeLists.txt
+++ b/linux/CMakeLists.txt
@@ -8,20 +8,16 @@
cmake_minimum_required(VERSION 3.10)
# Project-level configuration.
-set(PROJECT_NAME "tor")
+set(PROJECT_NAME "rust_lib_tor")
project(${PROJECT_NAME} LANGUAGES CXX)
-# Invoke the build for native code shared with the other target platforms.
-# This can be changed to accommodate different builds.
include("../cargokit/cmake/cargokit.cmake")
-apply_cargokit(${PROJECT_NAME} ../rust tor "")
+apply_cargokit(${PROJECT_NAME} ../rust rust_lib_tor "")
# List of absolute paths to libraries that should be bundled with the plugin.
# This list could contain prebuilt libraries, or libraries created by an
# external build triggered from this build file.
-set(tor_bundled_libraries
- # Defined in ../src/CMakeLists.txt.
- # This can be changed to accommodate different builds.
+set(rust_lib_tor_bundled_libraries
"${${PROJECT_NAME}_cargokit_lib}"
PARENT_SCOPE
)
diff --git a/macos/Classes/dummy_file.c b/macos/Classes/dummy_file.c
new file mode 100644
index 00000000..a092da28
--- /dev/null
+++ b/macos/Classes/dummy_file.c
@@ -0,0 +1,7 @@
+/*
+ * SPDX-FileCopyrightText: 2024 Foundation Devices Inc
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+// This is an empty file to force CocoaPods to create a framework.
diff --git a/macos/Classes/tor_ffi_plugin.c b/macos/Classes/tor_ffi_plugin.c
deleted file mode 100644
index bc3f15a2..00000000
--- a/macos/Classes/tor_ffi_plugin.c
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
- *
- * SPDX-License-Identifier: MIT
- */
-
-// SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-//
-// SPDX-License-Identifier: MIT
-
-// Relative import to be able to reuse the C sources.
-// See the comment in ../{projectName}}.podspec for more information.
diff --git a/macos/rust_lib_backup.podspec.license b/macos/rust_lib_backup.podspec.license
new file mode 100644
index 00000000..b28499ea
--- /dev/null
+++ b/macos/rust_lib_backup.podspec.license
@@ -0,0 +1,3 @@
+SPDX-FileCopyrightText: 2024 Foundation Devices Inc
+
+SPDX-License-Identifier: MIT
diff --git a/macos/rust_lib_tor.podspec b/macos/rust_lib_tor.podspec
new file mode 100644
index 00000000..2e7ceff0
--- /dev/null
+++ b/macos/rust_lib_tor.podspec
@@ -0,0 +1,45 @@
+#
+# SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
+# SPDX-License-Identifier: MIT
+#
+# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
+# Run `pod lib lint rust_lib_tor.podspec` to validate before publishing.
+#
+Pod::Spec.new do |s|
+ s.name = 'rust_lib_tor'
+ s.version = '0.0.1'
+ s.summary = 'Rust library for Tor proxy'
+ s.description = <<-DESC
+Rust library providing Tor proxy functionality via arti.
+ DESC
+ s.homepage = 'https://github.com/Foundation-Devices/tor'
+ s.license = { :file => '../LICENSE' }
+ s.author = { 'Foundation Devices' => 'hello@foundation.xyz' }
+
+ # This will ensure the source files in Classes/ are included in the native
+ # builds of apps using this FFI plugin. Podspec does not support relative
+ # paths, so Classes contains a forwarder C file that relatively imports
+ # `../src/*` so that the C sources can be shared among all target platforms.
+ s.source = { :path => '.' }
+ s.source_files = 'Classes/**/*'
+ s.dependency 'FlutterMacOS'
+
+ s.platform = :osx, '10.11'
+ s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' }
+ s.swift_version = '5.0'
+
+ s.script_phase = {
+ :name => 'Build Rust library',
+ # First argument is relative path to the `rust` folder, second is name of rust library
+ :script => 'sh "$PODS_TARGET_SRCROOT/../cargokit/build_pod.sh" ../rust rust_lib_tor',
+ :execution_position => :before_compile,
+ :input_files => ['${BUILT_PRODUCTS_DIR}/cargokit_phony'],
+ # Let XCode know that the static library referenced in -force_load below is
+ # created by this build step.
+ :output_files => ["${BUILT_PRODUCTS_DIR}/librust_lib_tor.a"],
+ }
+ s.pod_target_xcconfig = {
+ 'DEFINES_MODULE' => 'YES',
+ 'OTHER_LDFLAGS' => '-force_load ${BUILT_PRODUCTS_DIR}/librust_lib_tor.a',
+ }
+end
diff --git a/macos/tor.podspec b/macos/tor.podspec
deleted file mode 100644
index c134b8eb..00000000
--- a/macos/tor.podspec
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
-# Run `pod lib lint tor.podspec` to validate before publishing.
-#
-Pod::Spec.new do |s|
- s.name = 'tor'
- s.version = '0.0.1'
- s.summary = 'A new Flutter FFI plugin project.'
- s.description = <<-DESC
-A new Flutter FFI plugin project.
- DESC
- s.homepage = 'http://example.com'
- s.license = { :file => '../LICENSE' }
- s.author = { 'Your Company' => 'email@example.com' }
-
- s.source = { :path => '.' }
- s.source_files = 'Classes/**/*'
- s.platform = :osx, '10.13'
-
- s.script_phase = {
- :name => 'Build Rust library',
- # First argument is relative path to the `rust` folder, second is name of rust library
- :script => 'sh "$PODS_TARGET_SRCROOT/../cargokit/build_pod.sh" ../rust tor',
- :execution_position => :before_compile,
- :input_files => ['${BUILT_PRODUCTS_DIR}/cargokit_phony'],
- # Let XCode know that the static library referenced in -force_load below is
- # created by this build step.
- :output_files => ["${BUILT_PRODUCTS_DIR}/libtor.a"],
- }
- s.pod_target_xcconfig = {
- 'DEFINES_MODULE' => 'YES',
- # We use `-force_load` instead of `-l` since Xcode strips out unused symbols from static libraries.
- 'OTHER_LDFLAGS' => '-force_load ${BUILT_PRODUCTS_DIR}/libtor.a',
- 'DEAD_CODE_STRIPPING' => 'YES',
- 'STRIP_INSTALLED_PRODUCT[config=Release][sdk=*][arch=*]' => "YES",
- 'STRIP_STYLE[config=Release][sdk=*][arch=*]' => "non-global",
- 'DEPLOYMENT_POSTPROCESSING[config=Release][sdk=*][arch=*]' => "YES",
- }
-end
\ No newline at end of file
diff --git a/macos/tor.podspec.license b/macos/tor.podspec.license
deleted file mode 100644
index 7b44746f..00000000
--- a/macos/tor.podspec.license
+++ /dev/null
@@ -1,3 +0,0 @@
-SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-
-SPDX-License-Identifier: MIT
diff --git a/pubspec.yaml b/pubspec.yaml
index d8a9cc67..eb99a0c2 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -4,79 +4,28 @@
name: tor
description: A multi-platform Flutter plugin for managing a Tor proxy. Based on arti.
-version: 0.1.1
+version: 0.2.0
homepage: https://github.com/Foundation-Devices/tor
-platforms:
- android:
- ios:
- linux:
- macos:
- windows:
-
environment:
- sdk: '>=3.0.0 <4.0.0'
+ sdk: '>=3.3.0 <4.0.0'
flutter: ">=3.3.0"
dependencies:
flutter:
sdk: flutter
path_provider: ^2.1.5
- ffi: ^2.1.4
- plugin_platform_interface: ^2.1.8
+ flutter_rust_bridge: 2.11.1
+ freezed_annotation: ^2.4.1
dev_dependencies:
- ffigen: ^19.1.0
flutter_test:
sdk: flutter
flutter_lints: ^6.0.0
+ freezed: ^2.4.5
+ build_runner: ^2.4.7
-ffigen:
- output: 'lib/generated_bindings.dart'
- llvm-path:
- - '/usr/lib/llvm-14/lib/libclang.so.1'
- functions:
- include:
- - tor_.*
- structs:
- exclude:
- - .*
- unions:
- exclude:
- - .*
- enums:
- exclude:
- - _.*
- unnamed-enums:
- exclude:
- - _.*
- macros:
- exclude:
- - _.*
- globals:
- exclude:
- - _.*
- headers:
- entry-points:
- - 'rust/target/tor.h'
-
-# For information on the generic Dart part of this file, see the
-# following page: https://dart.dev/tools/pub/pubspec
-
-# The following section is specific to Flutter packages.
flutter:
- # This section identifies this Flutter project as a plugin project.
- # The 'pluginClass' specifies the class (in Java, Kotlin, Swift, Objective-C, etc.)
- # which should be registered in the plugin registry. This is required for
- # using method channels.
- # The Android 'package' specifies package in which the registered class is.
- # This is required for using method channels on Android.
- # The 'ffiPlugin' specifies that native code should be built and bundled.
- # This is required for using `dart:ffi`.
- # All these are used by the tooling to maintain consistency when
- # adding or updating assets for this project.
- #
- # Please refer to README.md for a detailed explanation.
plugin:
platforms:
android:
diff --git a/rust/Cargo.lock b/rust/Cargo.lock
index a5383fab..4b943311 100644
--- a/rust/Cargo.lock
+++ b/rust/Cargo.lock
@@ -38,6 +38,17 @@ dependencies = [
"memchr",
]
+[[package]]
+name = "allo-isolate"
+version = "0.1.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "449e356a4864c017286dbbec0e12767ea07efba29e3b7d984194c2a7ff3c4550"
+dependencies = [
+ "anyhow",
+ "atomic 0.5.3",
+ "backtrace",
+]
+
[[package]]
name = "amplify"
version = "4.8.1"
@@ -88,6 +99,23 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
+[[package]]
+name = "android_log-sys"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "84521a3cf562bc62942e294181d9eef17eb38ceb8c68677bc49f144e4c3d4f8d"
+
+[[package]]
+name = "android_logger"
+version = "0.15.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dbb4e440d04be07da1f1bf44fb4495ebd58669372fe0cffa6e48595ac5bd88a3"
+dependencies = [
+ "android_log-sys",
+ "env_filter",
+ "log",
+]
+
[[package]]
name = "android_system_properties"
version = "0.1.5"
@@ -174,7 +202,7 @@ dependencies = [
"anyhow",
"arti-client",
"cfg-if",
- "clap 4.5.38",
+ "clap",
"derive_builder_fork_arti",
"fs-mistrust",
"futures",
@@ -398,17 +426,6 @@ dependencies = [
"bytemuck",
]
-[[package]]
-name = "atty"
-version = "0.2.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
-dependencies = [
- "hermit-abi",
- "libc",
- "winapi",
-]
-
[[package]]
name = "autocfg"
version = "1.4.0"
@@ -513,6 +530,12 @@ dependencies = [
"serde",
]
+[[package]]
+name = "build-target"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "832133bbabbbaa9fbdba793456a2827627a7d2b8fb96032fa1e7666d7895832b"
+
[[package]]
name = "bumpalo"
version = "3.17.0"
@@ -555,25 +578,6 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
-[[package]]
-name = "cbindgen"
-version = "0.24.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a6358dedf60f4d9b8db43ad187391afe959746101346fe51bb978126bec61dfb"
-dependencies = [
- "clap 3.2.25",
- "heck 0.4.1",
- "indexmap 1.9.3",
- "log",
- "proc-macro2",
- "quote",
- "serde",
- "serde_json",
- "syn 1.0.109",
- "tempfile",
- "toml 0.5.11",
-]
-
[[package]]
name = "cc"
version = "1.2.23"
@@ -642,21 +646,6 @@ dependencies = [
"zeroize",
]
-[[package]]
-name = "clap"
-version = "3.2.25"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123"
-dependencies = [
- "atty",
- "bitflags 1.3.2",
- "clap_lex 0.2.4",
- "indexmap 1.9.3",
- "strsim 0.10.0",
- "termcolor",
- "textwrap",
-]
-
[[package]]
name = "clap"
version = "4.5.38"
@@ -675,7 +664,7 @@ checksum = "379026ff283facf611b0ea629334361c4211d1b12ee01024eec1591133b04120"
dependencies = [
"anstream",
"anstyle",
- "clap_lex 0.7.4",
+ "clap_lex",
"strsim 0.11.1",
"terminal_size",
]
@@ -686,21 +675,12 @@ version = "4.5.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7"
dependencies = [
- "heck 0.5.0",
+ "heck",
"proc-macro2",
"quote",
"syn 2.0.101",
]
-[[package]]
-name = "clap_lex"
-version = "0.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
-dependencies = [
- "os_str_bytes",
-]
-
[[package]]
name = "clap_lex"
version = "0.7.4"
@@ -733,6 +713,16 @@ dependencies = [
"crossbeam-utils",
]
+[[package]]
+name = "console_error_panic_hook"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc"
+dependencies = [
+ "cfg-if",
+ "wasm-bindgen",
+]
+
[[package]]
name = "const-oid"
version = "0.9.6"
@@ -800,7 +790,7 @@ dependencies = [
"anes",
"cast",
"ciborium",
- "clap 4.5.38",
+ "clap",
"criterion-plot",
"itertools 0.13.0",
"num-traits",
@@ -1017,12 +1007,45 @@ dependencies = [
"syn 2.0.101",
]
+[[package]]
+name = "dart-sys"
+version = "4.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57967e4b200d767d091b961d6ab42cc7d0cc14fe9e052e75d0d3cf9eb732d895"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "dashmap"
+version = "5.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856"
+dependencies = [
+ "cfg-if",
+ "hashbrown 0.14.5",
+ "lock_api",
+ "once_cell",
+ "parking_lot_core",
+]
+
[[package]]
name = "data-encoding"
version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476"
+[[package]]
+name = "delegate-attr"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51aac4c99b2e6775164b412ea33ae8441b2fde2dbf05a20bc0052a63d08c475b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.101",
+]
+
[[package]]
name = "der"
version = "0.7.10"
@@ -1065,7 +1088,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8ea84d0109517cc2253d4a679bdda1e8989e9bd86987e9e4f75ffdda0095fd1"
dependencies = [
"derive-deftly-macros 0.14.6",
- "heck 0.5.0",
+ "heck",
]
[[package]]
@@ -1075,7 +1098,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d308ebe4b10924331bd079044b418da7b227d724d3e2408567a47ad7c3da2a0"
dependencies = [
"derive-deftly-macros 1.3.0",
- "heck 0.5.0",
+ "heck",
]
[[package]]
@@ -1084,7 +1107,7 @@ version = "0.14.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "357422a457ccb850dc8f1c1680e0670079560feaad6c2e247e3f345c4fab8a3f"
dependencies = [
- "heck 0.5.0",
+ "heck",
"indexmap 2.12.1",
"itertools 0.14.0",
"proc-macro-crate",
@@ -1102,7 +1125,7 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd5f2b7218a51c827a11d22d1439b598121fac94bf9b99452e4afffe512d78c9"
dependencies = [
- "heck 0.5.0",
+ "heck",
"indexmap 2.12.1",
"itertools 0.14.0",
"proc-macro-crate",
@@ -1315,7 +1338,7 @@ version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc"
dependencies = [
- "heck 0.5.0",
+ "heck",
"proc-macro2",
"quote",
"syn 2.0.101",
@@ -1346,6 +1369,16 @@ dependencies = [
"syn 2.0.101",
]
+[[package]]
+name = "env_filter"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2"
+dependencies = [
+ "log",
+ "regex",
+]
+
[[package]]
name = "equivalent"
version = "1.0.2"
@@ -1448,6 +1481,48 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "749cff877dc1af878a0b31a41dd221a753634401ea0ef2f87b62d3171522485a"
+[[package]]
+name = "flutter_rust_bridge"
+version = "2.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dde126295b2acc5f0a712e265e91b6fdc0ed38767496483e592ae7134db83725"
+dependencies = [
+ "allo-isolate",
+ "android_logger",
+ "anyhow",
+ "build-target",
+ "bytemuck",
+ "byteorder",
+ "console_error_panic_hook",
+ "dart-sys",
+ "delegate-attr",
+ "flutter_rust_bridge_macros",
+ "futures",
+ "js-sys",
+ "lazy_static",
+ "log",
+ "oslog",
+ "portable-atomic",
+ "threadpool",
+ "tokio",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "web-sys",
+]
+
+[[package]]
+name = "flutter_rust_bridge_macros"
+version = "2.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d5f0420326b13675321b194928bb7830043b68cf8b810e1c651285c747abb080"
+dependencies = [
+ "hex",
+ "md-5",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.101",
+]
+
[[package]]
name = "fnv"
version = "1.0.7"
@@ -1690,6 +1765,12 @@ version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+[[package]]
+name = "hashbrown"
+version = "0.14.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
+
[[package]]
name = "hashbrown"
version = "0.15.3"
@@ -1714,12 +1795,6 @@ dependencies = [
"hashbrown 0.15.3",
]
-[[package]]
-name = "heck"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
-
[[package]]
name = "heck"
version = "0.5.0"
@@ -1728,12 +1803,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hermit-abi"
-version = "0.1.19"
+version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
-dependencies = [
- "libc",
-]
+checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
[[package]]
name = "hex"
@@ -2212,6 +2284,16 @@ dependencies = [
"regex-automata",
]
+[[package]]
+name = "md-5"
+version = "0.10.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf"
+dependencies = [
+ "cfg-if",
+ "digest",
+]
+
[[package]]
name = "memchr"
version = "2.7.4"
@@ -2404,6 +2486,16 @@ dependencies = [
"libm",
]
+[[package]]
+name = "num_cpus"
+version = "1.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b"
+dependencies = [
+ "hermit-abi",
+ "libc",
+]
+
[[package]]
name = "num_enum"
version = "0.7.3"
@@ -2556,6 +2648,17 @@ dependencies = [
"memchr",
]
+[[package]]
+name = "oslog"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "80d2043d1f61d77cb2f4b1f7b7b2295f40507f5f8e9d1c8bf10a1ca5f97a3969"
+dependencies = [
+ "cc",
+ "dashmap",
+ "log",
+]
+
[[package]]
name = "p256"
version = "0.13.2"
@@ -3134,6 +3237,25 @@ dependencies = [
"time",
]
+[[package]]
+name = "rust_lib_tor"
+version = "0.2.0"
+dependencies = [
+ "anyhow",
+ "arti",
+ "arti-client",
+ "flutter_rust_bridge",
+ "lazy_static",
+ "log",
+ "rlimit",
+ "security-framework",
+ "thiserror 1.0.69",
+ "time",
+ "tokio",
+ "tor-config",
+ "tor-rtcompat",
+]
+
[[package]]
name = "rustc-demangle"
version = "0.1.24"
@@ -3634,7 +3756,7 @@ version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c77a8c5abcaf0f9ce05d62342b7d298c346515365c36b673df4ebe3ced01fde8"
dependencies = [
- "heck 0.5.0",
+ "heck",
"proc-macro2",
"quote",
"rustversion",
@@ -3719,15 +3841,6 @@ dependencies = [
"windows-sys 0.59.0",
]
-[[package]]
-name = "termcolor"
-version = "1.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
-dependencies = [
- "winapi-util",
-]
-
[[package]]
name = "terminal_size"
version = "0.4.2"
@@ -3738,12 +3851,6 @@ dependencies = [
"windows-sys 0.59.0",
]
-[[package]]
-name = "textwrap"
-version = "0.16.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057"
-
[[package]]
name = "thiserror"
version = "1.0.69"
@@ -3794,6 +3901,15 @@ dependencies = [
"once_cell",
]
+[[package]]
+name = "threadpool"
+version = "1.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa"
+dependencies = [
+ "num_cpus",
+]
+
[[package]]
name = "time"
version = "0.3.41"
@@ -3903,15 +4019,6 @@ dependencies = [
"tokio",
]
-[[package]]
-name = "toml"
-version = "0.5.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
-dependencies = [
- "serde",
-]
-
[[package]]
name = "toml"
version = "0.8.22"
@@ -3992,24 +4099,6 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df8b2b54733674ad286d16267dcfc7a71ed5c776e4ac7aa3c3e2561f7c637bf2"
-[[package]]
-name = "tor"
-version = "0.1.1"
-dependencies = [
- "anyhow",
- "arti",
- "arti-client",
- "cbindgen",
- "lazy_static",
- "log",
- "rlimit",
- "security-framework",
- "time",
- "tokio",
- "tor-config",
- "tor-rtcompat",
-]
-
[[package]]
name = "tor-async-utils"
version = "0.36.0"
@@ -5290,6 +5379,19 @@ dependencies = [
"wasm-bindgen-shared",
]
+[[package]]
+name = "wasm-bindgen-futures"
+version = "0.4.50"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61"
+dependencies = [
+ "cfg-if",
+ "js-sys",
+ "once_cell",
+ "wasm-bindgen",
+ "web-sys",
+]
+
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.100"
diff --git a/rust/Cargo.toml b/rust/Cargo.toml
index 60e4c019..f7050c9b 100644
--- a/rust/Cargo.toml
+++ b/rust/Cargo.toml
@@ -3,15 +3,16 @@
# SPDX-License-Identifier: MIT
[package]
-name = "tor"
-version = "0.1.1"
+name = "rust_lib_tor"
+version = "0.2.0"
authors = ["Igor Cota "]
edition = "2021"
[lib]
-crate-type = ["cdylib", "staticlib"]
+crate-type = ["cdylib", "staticlib", "rlib"]
[dependencies]
+flutter_rust_bridge = "=2.11.1"
lazy_static = "1.4"
tokio = { version = "1", features = ["full"] }
arti-client = { version = "0.36.0", features = ["static", "onion-service-client"] }
@@ -19,14 +20,14 @@ arti = { version = "1.7.0", features = ["experimental-api", "static"] }
tor-rtcompat = { version = "0.36.0", features = ["static"] }
tor-config = "0.36.0"
log = "0.4.20"
-#android_log-sys = "0.3.1"
rlimit = "0.10.1"
anyhow = "1.0.79"
time = "0.3.36"
+thiserror = "1.0"
[target.'cfg(target_os = "ios")'.dependencies]
# Specific version for iOS
security-framework = "=2.10.0"
-[build-dependencies]
-cbindgen = "= 0.24.3"
+[lints.rust]
+unexpected_cfgs = { level = "warn", check-cfg = ['cfg(frb_expand)'] }
diff --git a/rust/build.rs b/rust/build.rs
deleted file mode 100644
index eb3c238f..00000000
--- a/rust/build.rs
+++ /dev/null
@@ -1,36 +0,0 @@
-// SPDX-FileCopyrightText: 2023 Foundation Devices Inc.
-// SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-//
-// SPDX-License-Identifier: MIT
-
-use cbindgen::{Config, Language};
-use std::env;
-use std::path::PathBuf;
-
-fn main() {
- // Create C header files for Dart
- let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
- let package_name = env::var("CARGO_PKG_NAME").unwrap();
-
- let output_file = target_dir()
- .join(format!("{}.h", package_name))
- .display()
- .to_string();
-
- let config = Config {
- language: Language::C,
- ..Default::default()
- };
-
- cbindgen::generate_with_config(crate_dir, config)
- .unwrap()
- .write_to_file(output_file);
-}
-
-fn target_dir() -> PathBuf {
- if let Ok(target) = env::var("CARGO_TARGET_DIR") {
- PathBuf::from(target)
- } else {
- PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()).join("target")
- }
-}
diff --git a/rust/src/api/mod.rs b/rust/src/api/mod.rs
new file mode 100644
index 00000000..df75aa30
--- /dev/null
+++ b/rust/src/api/mod.rs
@@ -0,0 +1,5 @@
+// SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
+//
+// SPDX-License-Identifier: MIT
+
+pub mod tor;
diff --git a/rust/src/api/tor.rs b/rust/src/api/tor.rs
new file mode 100644
index 00000000..faae3fc1
--- /dev/null
+++ b/rust/src/api/tor.rs
@@ -0,0 +1,227 @@
+// SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
+//
+// SPDX-License-Identifier: MIT
+
+use anyhow::Result;
+use arti::proxy;
+use arti_client::config::CfgPath;
+use arti_client::{DormantMode, TorClient, TorClientConfig};
+use flutter_rust_bridge::frb;
+use lazy_static::lazy_static;
+use std::io;
+use std::sync::Arc;
+use tokio::runtime::{Builder, Runtime};
+use tokio::task::JoinHandle;
+use tor_config::Listen;
+use tor_rtcompat::tokio::TokioNativeTlsRuntime;
+use tor_rtcompat::ToplevelBlockOn;
+
+lazy_static! {
+ static ref RUNTIME: io::Result = Builder::new_multi_thread().enable_all().build();
+}
+
+/// Custom error types for Tor operations
+#[derive(Debug, thiserror::Error)]
+pub enum TorError {
+ #[error("Failed to bootstrap Tor: {0}")]
+ BootstrapError(String),
+
+ #[error("Failed to start proxy: {0}")]
+ ProxyStartError(String),
+
+ #[error("Failed to stop proxy: {0}")]
+ ProxyStopError(String),
+
+ #[error("Client not initialized")]
+ ClientNotInitialized,
+
+ #[error("Runtime error: {0}")]
+ RuntimeError(String),
+
+ #[error("Configuration error: {0}")]
+ ConfigError(String),
+}
+
+/// Opaque wrapper for TorClient - FRB handles this automatically
+#[frb(opaque)]
+pub struct TorClientWrapper {
+ client: Arc>,
+ runtime: TokioNativeTlsRuntime,
+}
+
+impl Clone for TorClientWrapper {
+ fn clone(&self) -> Self {
+ TorClientWrapper {
+ client: Arc::clone(&self.client),
+ runtime: self.runtime.clone(),
+ }
+ }
+}
+
+/// Opaque wrapper for proxy handle
+#[frb(opaque)]
+pub struct TorProxyHandle {
+ handle: Arc>>>>,
+}
+
+impl Clone for TorProxyHandle {
+ fn clone(&self) -> Self {
+ TorProxyHandle {
+ handle: Arc::clone(&self.handle),
+ }
+ }
+}
+
+/// Result of starting Tor - contains both client and proxy
+pub struct TorInstance {
+ pub client: TorClientWrapper,
+ pub proxy: TorProxyHandle,
+ pub socks_port: u16,
+}
+
+/// Initialize FRB
+#[frb(init)]
+pub fn init_app() {
+ flutter_rust_bridge::setup_default_user_utils();
+}
+
+/// Start Tor client and proxy
+///
+/// This is a blocking operation that may take several seconds.
+/// It bootstraps the Tor network connection and starts a SOCKS proxy.
+pub fn start_tor(
+ socks_port: u16,
+ state_dir: String,
+ cache_dir: String,
+) -> Result {
+ let runtime =
+ TokioNativeTlsRuntime::create().map_err(|e| TorError::RuntimeError(e.to_string()))?;
+
+ let mut cfg_builder = TorClientConfig::builder();
+ cfg_builder
+ .storage()
+ .state_dir(CfgPath::new(state_dir))
+ .cache_dir(CfgPath::new(cache_dir));
+ cfg_builder.address_filter().allow_onion_addrs(true);
+ cfg_builder
+ .preemptive_circuits()
+ .disable_at_threshold(1)
+ .min_exit_circs_for_port(1)
+ .initial_predicted_ports()
+ .clear();
+
+ let cfg = cfg_builder
+ .build()
+ .map_err(|e| TorError::ConfigError(e.to_string()))?;
+
+ let client = runtime
+ .block_on(async {
+ TorClient::with_runtime(runtime.clone())
+ .config(cfg)
+ .create_bootstrapped()
+ .await
+ })
+ .map_err(|e| TorError::BootstrapError(e.to_string()))?;
+
+ let client_arc = Arc::new(client);
+ let proxy_handle = start_proxy_internal(socks_port, Arc::clone(&client_arc))?;
+
+ Ok(TorInstance {
+ client: TorClientWrapper {
+ client: client_arc,
+ runtime,
+ },
+ proxy: TorProxyHandle {
+ handle: Arc::new(std::sync::Mutex::new(Some(proxy_handle))),
+ },
+ socks_port,
+ })
+}
+
+fn start_proxy_internal(
+ port: u16,
+ client: Arc>,
+) -> Result>, TorError> {
+ let rt = RUNTIME
+ .as_ref()
+ .map_err(|e| TorError::RuntimeError(e.to_string()))?;
+
+ let client_ref = client.as_ref();
+ Ok(rt.spawn(proxy::run_proxy(
+ client_ref.runtime().clone(),
+ client_ref.clone(),
+ Listen::new_localhost(port),
+ None,
+ )))
+}
+
+/// Re-bootstrap the Tor client
+///
+/// Call this after network changes or to refresh the connection.
+pub fn bootstrap(client: &TorClientWrapper) -> Result<(), TorError> {
+ client
+ .runtime
+ .block_on(client.client.as_ref().bootstrap())
+ .map_err(|e| TorError::BootstrapError(e.to_string()))
+}
+
+/// Set the client dormant mode
+///
+/// * `soft_mode` - If true, uses Soft dormant mode (keeps some circuits warm)
+/// If false, uses Normal mode (full operation)
+pub fn set_dormant(client: &TorClientWrapper, soft_mode: bool) {
+ let dormant_mode = if soft_mode {
+ DormantMode::Soft
+ } else {
+ DormantMode::Normal
+ };
+ client.client.as_ref().set_dormant(dormant_mode);
+}
+
+/// Stop the Tor proxy
+///
+/// This safely aborts the proxy task. Previously this could panic
+/// and crash the app - with FRB, any panic becomes a catchable exception.
+pub fn stop_proxy(proxy: TorProxyHandle) -> Result<(), TorError> {
+ // Take the handle out of the Option to abort it
+ // This ensures we only abort once even if called multiple times
+ let mut guard = proxy
+ .handle
+ .lock()
+ .map_err(|e| TorError::ProxyStopError(e.to_string()))?;
+
+ if let Some(handle) = guard.take() {
+ // The abort() call is safe with FRB - any panic becomes PanicException
+ handle.abort();
+ }
+
+ Ok(())
+}
+
+/// Test function to verify library linking
+pub fn hello() {
+ println!("HELLO THERE");
+}
+
+// Platform-specific rlimit functions
+#[cfg(not(target_os = "windows"))]
+pub fn get_nofile_limit() -> Result {
+ rlimit::getrlimit(rlimit::Resource::NOFILE)
+ .map(|(soft, _hard)| soft)
+ .map_err(|e| TorError::RuntimeError(e.to_string()))
+}
+
+#[cfg(not(target_os = "windows"))]
+pub fn set_nofile_limit(limit: u64) -> Result {
+ rlimit::increase_nofile_limit(limit).map_err(|e| TorError::RuntimeError(e.to_string()))
+}
+
+#[cfg(target_os = "windows")]
+pub fn get_nofile_limit() -> Result {
+ Ok(0) // Not applicable on Windows
+}
+
+#[cfg(target_os = "windows")]
+pub fn set_nofile_limit(_limit: u64) -> Result {
+ Ok(0) // Not applicable on Windows
+}
diff --git a/rust/src/error.rs b/rust/src/error.rs
deleted file mode 100644
index 8a496eaf..00000000
--- a/rust/src/error.rs
+++ /dev/null
@@ -1,61 +0,0 @@
-// SPDX-FileCopyrightText: 2023 Foundation Devices Inc.
-// SPDX-FileCopyrightText: 2024 Foundation Devices Inc.
-//
-// SPDX-License-Identifier: MIT
-
-use log::{error, warn};
-use std::cell::RefCell;
-use std::error::Error;
-use std::ffi::{c_char, CString};
-//pub(crate) use crate::unwrap_or_return;
-
-thread_local! {
- static LAST_ERROR: RefCell