From b29135843e08cf63318ab292ae76c04647eef5c7 Mon Sep 17 00:00:00 2001 From: Brendan Allan Date: Wed, 20 Oct 2021 14:54:17 +0800 Subject: [PATCH 1/2] Use swift-rs --- src-tauri/Cargo.lock | 12 ++++ src-tauri/Cargo.toml | 4 +- src-tauri/src/build.rs | 82 ++-------------------------- src-tauri/src/commands.rs | 3 +- src-tauri/src/swift/mod.rs | 55 +------------------ src-tauri/swift-lib/Package.resolved | 16 ++++++ src-tauri/swift-lib/Package.swift | 3 +- src-tauri/swift-lib/src/lib.swift | 69 +---------------------- 8 files changed, 42 insertions(+), 202 deletions(-) create mode 100644 src-tauri/swift-lib/Package.resolved diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 79f2dc41b..e98534b03 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -33,6 +33,7 @@ dependencies = [ "snafu", "sqlx", "strum 0.21.0", + "swift-rs", "tauri", "tauri-build", "walkdir", @@ -4057,6 +4058,17 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +[[package]] +name = "swift-rs" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e56047444883f07ced9a621d23c8af8c7a3bbdafc16e02e00f4799943002e20" +dependencies = [ + "base64", + "serde", + "serde_json", +] + [[package]] name = "syn" version = "0.11.11" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index ec6b05123..af9a8ec98 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -11,8 +11,7 @@ build = "src/build.rs" [build-dependencies] tauri-build = { version = "1.0.0-beta.3" } -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" +swift-rs = "0.1.0" [dependencies] tauri = { version = "1.0.0-beta.5", features = ["api-all", "menu"] } @@ -45,6 +44,7 @@ log = "0.4.14" objc = "0.2.7" cocoa = "0.24.0" objc-foundation = "0.1.1" +swift-rs = "0.1.0" [features] default = [ "custom-protocol" ] diff --git a/src-tauri/src/build.rs b/src-tauri/src/build.rs index 38c00a494..b437eca05 100644 --- a/src-tauri/src/build.rs +++ b/src-tauri/src/build.rs @@ -1,82 +1,8 @@ -use serde::Deserialize; -use serde_json; -use std::env; -use std::process::Command; - -const MACOS_TARGET_VERSION: &str = "11"; - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -struct SwiftTargetInfo { - triple: String, - unversioned_triple: String, - module_triple: String, - swift_runtime_compatibility_version: String, - #[serde(rename = "librariesRequireRPath")] - libraries_require_rpath: bool, -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -struct SwiftPaths { - runtime_library_paths: Vec, - runtime_library_import_paths: Vec, - runtime_resource_path: String, -} - -#[derive(Debug, Deserialize)] -struct SwiftTarget { - target: SwiftTargetInfo, - paths: SwiftPaths, -} - -/// Builds mac_ddc library Swift project, sets the library search options right so we link -/// against Swift run-time correctly. -fn build_swift_natives() { - let profile = env::var("PROFILE").unwrap(); - let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap(); - let target = format!("{}-apple-macosx{}", arch, MACOS_TARGET_VERSION); - - let swift_target_info_str = Command::new("swift") - .args(&["-target", &target, "-print-target-info"]) - .output() - .unwrap() - .stdout; - let swift_target_info: SwiftTarget = serde_json::from_slice(&swift_target_info_str).unwrap(); - if swift_target_info.target.libraries_require_rpath { - panic!("Libraries require RPath! Change minimum MacOS value to fix.") - } - - if !Command::new("swift") - .args(&["build", "-c", &profile]) - .current_dir("./swift-lib") - .status() - .unwrap() - .success() - { - panic!("Swift natives compilation failed") - } - - swift_target_info - .paths - .runtime_library_paths - .iter() - .for_each(|path| { - println!("cargo:rustc-link-search=native={}", path); - }); - println!( - "cargo:rustc-link-search=native=./swift-lib/.build/{}/{}", - swift_target_info.target.unversioned_triple, profile - ); - println!("cargo:rustc-link-lib=static=swift-lib"); - println!("cargo:rerun-if-changed=swift-lib/src/*.swift"); - println!( - "cargo:rustc-env=MACOSX_DEPLOYMENT_TARGET={}", - MACOS_TARGET_VERSION - ); -} +use swift_rs::build_utils::{link_swift, link_swift_package}; fn main() { - build_swift_natives(); + link_swift(); + link_swift_package("swift-lib", "./swift-lib/"); + tauri_build::build(); } diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs index fa7749132..93e32200d 100644 --- a/src-tauri/src/commands.rs +++ b/src-tauri/src/commands.rs @@ -35,8 +35,7 @@ pub async fn scan_dir(path: String) -> Result<(), String> { } #[tauri::command(async)] pub async fn get_file_thumb(path: &str) -> Result { - let path = &path.to_string(); - let thumbnail_b46 = get_file_thumbnail_base64(path.into()).to_string(); + let thumbnail_b46 = get_file_thumbnail_base64(path).to_string(); Ok(thumbnail_b46) } diff --git a/src-tauri/src/swift/mod.rs b/src-tauri/src/swift/mod.rs index 0806cf32e..6aa335b8d 100644 --- a/src-tauri/src/swift/mod.rs +++ b/src-tauri/src/swift/mod.rs @@ -1,59 +1,10 @@ -#[derive(Debug)] -#[repr(C)] -struct SRArray { - _nsobject_offset: u8, - data: *mut T, - length: usize, -} - -impl SRArray { - fn into_slice(&self) -> &'static [T] { - unsafe { std::slice::from_raw_parts(self.data, self.length) } - } -} - -#[derive(Debug)] -#[repr(C)] -struct SRData { - _nsobject_offset: u8, - data: *mut SRArray, -} - -impl SRData { - pub fn into_slice(&self) -> &'static [u8] { - unsafe { (*self.data).into_slice() } - } - - pub fn data(&self) -> &SRArray { - unsafe { &*(self.data) } - } -} - -#[derive(Debug)] -#[repr(C)] -pub struct SRString(SRData); - -impl SRString { - pub fn to_string(&self) -> String { - unsafe { std::str::from_utf8_unchecked(self.0.into_slice()) }.into() - } -} - -impl From<&String> for &SRString { - fn from(string: &String) -> &'static SRString { - unsafe { allocate_string(string.as_ptr(), string.len()) } - } -} +use swift_rs::types::SRString; extern "C" { - fn return_data() -> &'static SRData; - fn return_string() -> &'static SRString; - fn echo_string(string: &SRString); - fn allocate_string(data: *const u8, size: usize) -> &'static SRString; #[link_name = "get_file_thumbnail_base64"] fn get_file_thumbnail_base64_(path: &SRString) -> &'static SRString; } -pub fn get_file_thumbnail_base64(path: &SRString) -> &'static SRString { - unsafe { get_file_thumbnail_base64_(path) } +pub fn get_file_thumbnail_base64(path: &str) -> &'static SRString { + unsafe { get_file_thumbnail_base64_(path.into()) } } diff --git a/src-tauri/swift-lib/Package.resolved b/src-tauri/swift-lib/Package.resolved new file mode 100644 index 000000000..b8762d025 --- /dev/null +++ b/src-tauri/swift-lib/Package.resolved @@ -0,0 +1,16 @@ +{ + "object": { + "pins": [ + { + "package": "SwiftRs", + "repositoryURL": "https://github.com/Brendonovich/swift-rs", + "state": { + "branch": "master", + "revision": "1827da87300a581b5cd828dd5c9bd5dcd26243b6", + "version": null + } + } + ] + }, + "version": 1 +} diff --git a/src-tauri/swift-lib/Package.swift b/src-tauri/swift-lib/Package.swift index 207a5f590..5af0e05ab 100644 --- a/src-tauri/swift-lib/Package.swift +++ b/src-tauri/swift-lib/Package.swift @@ -18,13 +18,14 @@ let package = Package( dependencies: [ // Dependencies declare other packages that this package depends on. // .package(url: /* package url */, from: "1.0.0"), + .package(name: "SwiftRs", url: "https://github.com/Brendonovich/swift-rs", branch: "master") ], targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. // Targets can depend on other targets in this package, and on products in packages this package depends on. .target( name: "swift-lib", - dependencies: [], + dependencies: [.product(name: "SwiftRs", package: "SwiftRs")], path: "src") ] ) diff --git a/src-tauri/swift-lib/src/lib.swift b/src-tauri/swift-lib/src/lib.swift index 817b7cae4..592a63ec8 100644 --- a/src-tauri/swift-lib/src/lib.swift +++ b/src-tauri/swift-lib/src/lib.swift @@ -1,70 +1,6 @@ import Foundation import AppKit - -// Size: 24 bytes -public class SRArray: NSObject { - var pointer: UnsafePointer - var length: Int - - init(_ data: [T]) { - let mut_data = UnsafeMutablePointer.allocate(capacity: data.count) - mut_data.initialize(from: data, count: data.count) - - self.pointer = UnsafePointer(mut_data) - self.length = data.count - } -} - -// Size: 16 bytes -public class SRData: NSObject { - var data: SRArray - - init(_ data: [UInt8]) { - self.data = SRArray(data) - } - - func to_data() -> Data { - return Data(bytes: self.data.pointer, count: self.data.length) - } -} - -// Size: 16 bytes -public class SRString: SRData { - init(_ string: String) { - super.init(Array(string.utf8)) - } - - func to_string() -> String { - return String(bytes: self.to_data(), encoding: .utf8)! - } -} - -@_cdecl("return_data") -public func returnData() -> SRData { - return SRData([1,2,3]) -} - - -@_cdecl("return_string") -public func returnString() -> SRString { - return SRString("123456") -} - -@_cdecl("echo_string") -public func echoString(string: SRString) { - print(string.to_string()) -} - -// SRstring pointer is passed to rust correctly -// data pointer is passed to rust correctly -// guessing that the type of SRArray isn't the same -@_cdecl("allocate_string") -public func allocate_string(data: UnsafePointer, size: Int) -> SRString { - let buffer = UnsafeBufferPointer(start: data, count: size) - let string = String(bytes: buffer, encoding: .utf8)!; - let SRstring = SRString(string); - return SRstring -} +import SwiftRs @_cdecl("get_file_thumbnail_base64") public func getFileThumbnailBase64(path: SRString) -> SRString { @@ -74,5 +10,4 @@ public func getFileThumbnailBase64(path: SRString) -> SRString { let bitmap = NSBitmapImageRep(data: image.tiffRepresentation!)!.representation(using: .png, properties: [:])! return SRString(bitmap.base64EncodedString()) -} - +} \ No newline at end of file From 076b395501995911ce96902f01f38c975937143a Mon Sep 17 00:00:00 2001 From: Brendan Allan Date: Wed, 20 Oct 2021 15:04:26 +0800 Subject: [PATCH 2/2] use versioned SwiftRs --- src-tauri/swift-lib/Package.resolved | 6 +++--- src-tauri/swift-lib/Package.swift | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src-tauri/swift-lib/Package.resolved b/src-tauri/swift-lib/Package.resolved index b8762d025..e36fa4754 100644 --- a/src-tauri/swift-lib/Package.resolved +++ b/src-tauri/swift-lib/Package.resolved @@ -5,9 +5,9 @@ "package": "SwiftRs", "repositoryURL": "https://github.com/Brendonovich/swift-rs", "state": { - "branch": "master", - "revision": "1827da87300a581b5cd828dd5c9bd5dcd26243b6", - "version": null + "branch": null, + "revision": "196359dfb25a9520d534655c1321150e36c1b1dd", + "version": "0.1.0" } } ] diff --git a/src-tauri/swift-lib/Package.swift b/src-tauri/swift-lib/Package.swift index 5af0e05ab..6d724cb79 100644 --- a/src-tauri/swift-lib/Package.swift +++ b/src-tauri/swift-lib/Package.swift @@ -18,7 +18,7 @@ let package = Package( dependencies: [ // Dependencies declare other packages that this package depends on. // .package(url: /* package url */, from: "1.0.0"), - .package(name: "SwiftRs", url: "https://github.com/Brendonovich/swift-rs", branch: "master") + .package(name: "SwiftRs", url: "https://github.com/Brendonovich/swift-rs", from: "0.1.0") ], targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite.