diff --git a/Cargo.lock b/Cargo.lock index 048a3ffb..e2cb2e55 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -422,16 +422,6 @@ dependencies = [ "objc", ] -[[package]] -name = "codespan-reporting" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" -dependencies = [ - "termcolor", - "unicode-width", -] - [[package]] name = "color_quant" version = "1.1.0" @@ -536,50 +526,6 @@ dependencies = [ "cfg-if 1.0.0", ] -[[package]] -name = "cxx" -version = "1.0.129" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbdc8cca144dce1c4981b5c9ab748761619979e515c3d53b5df385c677d1d007" -dependencies = [ - "cc", - "cxxbridge-flags", - "cxxbridge-macro", - "link-cplusplus", -] - -[[package]] -name = "cxx-build" -version = "1.0.129" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5764c3142ab44fcf857101d12c0ddf09c34499900557c764f5ad0597159d1fc" -dependencies = [ - "cc", - "codespan-reporting", - "once_cell", - "proc-macro2", - "quote", - "scratch", - "syn 2.0.87", -] - -[[package]] -name = "cxxbridge-flags" -version = "1.0.129" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d422aff542b4fa28c2ce8e5cc202d42dbf24702345c1fba3087b2d3f8a1b90ff" - -[[package]] -name = "cxxbridge-macro" -version = "1.0.129" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1719100f31492cd6adeeab9a0f46cdbc846e615fdb66d7b398aa46ec7fdd06f" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - [[package]] name = "deranged" version = "0.3.11" @@ -1238,15 +1184,6 @@ dependencies = [ "libc", ] -[[package]] -name = "link-cplusplus" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d240c6f7e1ba3a28b0249f774e6a9dd0175054b52dfbb61b16eb8505c3785c9" -dependencies = [ - "cc", -] - [[package]] name = "linux-raw-sys" version = "0.4.14" @@ -2342,8 +2279,6 @@ name = "velopack_libc" version = "0.0.0-local" dependencies = [ "anyhow", - "cxx", - "cxx-build", "lazy_static", "log", "velopack", diff --git a/Cargo.toml b/Cargo.toml index fdbfdea6..32108b78 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,8 +23,6 @@ edition = "2021" rust-version = "1.75" [workspace.dependencies] -cxx = "1.0" -cxx-build = "1.0" velopack = { path = "src/lib-rust" } log = "0.4" ureq = "2.10" diff --git a/src/lib-cpp/Cargo.toml b/src/lib-cpp/Cargo.toml index fe9598e3..f1d145ef 100644 --- a/src/lib-cpp/Cargo.toml +++ b/src/lib-cpp/Cargo.toml @@ -18,11 +18,7 @@ path = "src/lib.rs" crate-type = ["cdylib"] [dependencies] -cxx.workspace = true velopack.workspace = true anyhow.workspace = true lazy_static.workspace = true -log.workspace = true - -[build-dependencies] -cxx-build.workspace = true \ No newline at end of file +log.workspace = true \ No newline at end of file diff --git a/src/lib-cpp/build.rs b/src/lib-cpp/build.rs index 061f74de..6b88c2b6 100644 --- a/src/lib-cpp/build.rs +++ b/src/lib-cpp/build.rs @@ -1,19 +1,21 @@ fn main() { - cxx_build::bridge("src/lib.rs") - .file("src/bridge.cc") - .warnings_into_errors(true) - .flag_if_supported("/std:c++17") - .flag_if_supported("/EHsc") // exception unwind handling - .flag_if_supported("-Wno-unused-function") // allow unused functions - .define("VELOPACK_LIBC_EXPORTS", Some("1")) - .std("c++17") - .compile("velopack_libc"); + // cc::Build::new() + // .cpp(true) + // .static_crt(true) + // .file("src/bridge.cc") + // .warnings_into_errors(true) + // .flag_if_supported("/std:c++17") + // .flag_if_supported("/EHsc") // exception unwind handling + // .flag_if_supported("-Wno-unused-function") // allow unused functions + // .define("VELOPACK_LIBC_EXPORTS", Some("1")) + // .std("c++17") + // .compile("velopack_libc"); - println!("cargo:rerun-if-changed=include/Velopack.h"); - println!("cargo:rerun-if-changed=src/lib.rs"); - println!("cargo:rerun-if-changed=src/bridge.hpp"); - println!("cargo:rerun-if-changed=src/bridge.cc"); + // println!("cargo:rerun-if-changed=include/Velopack.h"); + // println!("cargo:rerun-if-changed=src/lib.rs"); + // println!("cargo:rerun-if-changed=src/bridge.hpp"); + // println!("cargo:rerun-if-changed=src/bridge.cc"); - #[cfg(target_os = "windows")] - println!("cargo:rustc-link-arg=/WHOLEARCHIVE:velopack_libc.lib"); + // #[cfg(target_os = "windows")] + // println!("cargo:rustc-link-arg=/WHOLEARCHIVE:velopack_libc.lib"); } \ No newline at end of file diff --git a/src/lib-cpp/include/Velopack.h b/src/lib-cpp/include/Velopack.h index 76668d0c..44106b8f 100644 --- a/src/lib-cpp/include/Velopack.h +++ b/src/lib-cpp/include/Velopack.h @@ -20,39 +20,6 @@ #include #endif -#if defined(VELOPACK_LIBC_EXPORTS) && defined(_WIN32) -#define VPKC_EXPORT __declspec(dllexport) -#define VPKC_CALL __cdecl -#pragma comment(linker, "/EXPORT:vpkc_new_update_manager") -#pragma comment(linker, "/EXPORT:vpkc_get_current_version") -#pragma comment(linker, "/EXPORT:vpkc_get_app_id") -#pragma comment(linker, "/EXPORT:vpkc_is_portable") -#pragma comment(linker, "/EXPORT:vpkc_update_pending_restart") -#pragma comment(linker, "/EXPORT:vpkc_download_updates") -#pragma comment(linker, "/EXPORT:vpkc_wait_exit_then_apply_update") -#pragma comment(linker, "/EXPORT:vpkc_app_set_auto_apply_on_startup") -#pragma comment(linker, "/EXPORT:vpkc_app_set_args") -#pragma comment(linker, "/EXPORT:vpkc_app_set_locator") -#pragma comment(linker, "/EXPORT:vpkc_app_set_hook_after_install") -#pragma comment(linker, "/EXPORT:vpkc_app_set_hook_before_uninstall") -#pragma comment(linker, "/EXPORT:vpkc_app_set_hook_before_update") -#pragma comment(linker, "/EXPORT:vpkc_app_set_hook_after_update") -#pragma comment(linker, "/EXPORT:vpkc_app_set_hook_first_run") -#pragma comment(linker, "/EXPORT:vpkc_app_set_hook_restarted") -#pragma comment(linker, "/EXPORT:vpkc_app_run") -#pragma comment(linker, "/EXPORT:vpkc_get_last_error") -#pragma comment(linker, "/EXPORT:vpkc_set_logger") -#pragma comment(linker, "/EXPORT:vpkc_free_update_manager") -#pragma comment(linker, "/EXPORT:vpkc_free_update_info") -#pragma comment(linker, "/EXPORT:vpkc_free_asset") -#elif defined(VELOPACK_LIBC_EXPORTS) && !defined(_WIN32) -#define VPKC_EXPORT __attribute__((visibility("default"))) __attribute__((used)) -#define VPKC_CALL -#else -#define VPKC_EXPORT -#define VPKC_CALL -#endif - #ifdef __cplusplus extern "C" { #endif @@ -63,9 +30,10 @@ typedef void (*vpkc_log_callback_t)(void* pUserData, const char* pszLevel, const typedef void (*vpkc_hook_callback_t)(void* pUserData, const char* pszAppVersion); typedef enum vpkc_update_check_t { + UPDATE_ERROR = -1, UPDATE_AVAILABLE = 0, NO_UPDATE_AVAILABLE = 1, - UPDATE_ERROR = 2, + REMOTE_IS_EMPTY = 2, } vpkc_update_check_t; // !! AUTO-GENERATED-START C_TYPES @@ -138,55 +106,55 @@ typedef struct vpkc_update_options_t { /// Creates a new vpkc_update_manager_t. Free with vpkc_free_update_manager. /// \group UpdateManager -VPKC_EXPORT bool VPKC_CALL vpkc_new_update_manager(const char* pszUrlOrString, vpkc_update_options_t* pOptions, vpkc_locator_config_t* pLocator, vpkc_update_manager_t** pManager); +bool vpkc_new_update_manager(const char* pszUrlOrString, vpkc_update_options_t* pOptions, vpkc_locator_config_t* pLocator, vpkc_update_manager_t** pManager); /// \group UpdateManager -VPKC_EXPORT size_t VPKC_CALL vpkc_get_current_version(vpkc_update_manager_t* pManager, char* pszVersion, size_t cVersion); +size_t vpkc_get_current_version(vpkc_update_manager_t* pManager, char* pszVersion, size_t cVersion); /// \group UpdateManager -VPKC_EXPORT size_t VPKC_CALL vpkc_get_app_id(vpkc_update_manager_t* pManager, char* pszId, size_t cId); +size_t vpkc_get_app_id(vpkc_update_manager_t* pManager, char* pszId, size_t cId); /// \group UpdateManager -VPKC_EXPORT bool VPKC_CALL vpkc_is_portable(vpkc_update_manager_t* pManager); +bool vpkc_is_portable(vpkc_update_manager_t* pManager); /// \group UpdateManager -VPKC_EXPORT bool VPKC_CALL vpkc_update_pending_restart(vpkc_update_manager_t* pManager, vpkc_asset_t* pAsset); +bool vpkc_update_pending_restart(vpkc_update_manager_t* pManager, vpkc_asset_t* pAsset); /// \group UpdateManager -VPKC_EXPORT vpkc_update_check_t VPKC_CALL vpkc_check_for_updates(vpkc_update_manager_t* pManager, vpkc_update_info_t* pUpdate); +vpkc_update_check_t vpkc_check_for_updates(vpkc_update_manager_t* pManager, vpkc_update_info_t* pUpdate); /// \group UpdateManager -VPKC_EXPORT bool VPKC_CALL vpkc_download_updates(vpkc_update_manager_t* pManager, vpkc_update_info_t* pUpdate, vpkc_progress_callback_t cbProgress, void* pUserData = 0); +bool vpkc_download_updates(vpkc_update_manager_t* pManager, vpkc_update_info_t* pUpdate, vpkc_progress_callback_t cbProgress, void* pUserData = 0); /// \group UpdateManager -VPKC_EXPORT bool VPKC_CALL vpkc_wait_exit_then_apply_update(vpkc_update_manager_t* pManager, vpkc_asset_t* pAsset, bool bSilent, bool bRestart, char** pRestartArgs, size_t cRestartArgs); +bool vpkc_wait_exit_then_apply_update(vpkc_update_manager_t* pManager, vpkc_asset_t* pAsset, bool bSilent, bool bRestart, char** pRestartArgs, size_t cRestartArgs); /// \group UpdateManager -VPKC_EXPORT void VPKC_CALL vpkc_free_update_manager(vpkc_update_manager_t* pManager); +void vpkc_free_update_manager(vpkc_update_manager_t* pManager); /// \group UpdateManager -VPKC_EXPORT void VPKC_CALL vpkc_free_update_info(vpkc_update_info_t* pUpdateInfo); +void vpkc_free_update_info(vpkc_update_info_t* pUpdateInfo); /// \group UpdateManager -VPKC_EXPORT void VPKC_CALL vpkc_free_asset(vpkc_asset_t* pAsset); +void vpkc_free_asset(vpkc_asset_t* pAsset); /// Should be run at the beginning of your application to handle Velopack events. /// \group VelopackApp -VPKC_EXPORT void VPKC_CALL vpkc_app_run(void* pUserData = 0); +void vpkc_app_run(void* pUserData = 0); /// \group VelopackApp -VPKC_EXPORT void VPKC_CALL vpkc_app_set_auto_apply_on_startup(bool bAutoApply); +void vpkc_app_set_auto_apply_on_startup(bool bAutoApply); /// \group VelopackApp -VPKC_EXPORT void VPKC_CALL vpkc_app_set_args(char** pArgs, size_t cArgs); +void vpkc_app_set_args(char** pArgs, size_t cArgs); /// \group VelopackApp -VPKC_EXPORT void VPKC_CALL vpkc_app_set_locator(vpkc_locator_config_t* pLocator); +void vpkc_app_set_locator(vpkc_locator_config_t* pLocator); /// \group VelopackApp -VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_after_install(vpkc_hook_callback_t cbAfterInstall); +void vpkc_app_set_hook_after_install(vpkc_hook_callback_t cbAfterInstall); /// \group VelopackApp -VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_before_uninstall(vpkc_hook_callback_t cbBeforeUninstall); +void vpkc_app_set_hook_before_uninstall(vpkc_hook_callback_t cbBeforeUninstall); /// \group VelopackApp -VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_before_update(vpkc_hook_callback_t cbBeforeUpdate); +void vpkc_app_set_hook_before_update(vpkc_hook_callback_t cbBeforeUpdate); /// \group VelopackApp -VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_after_update(vpkc_hook_callback_t cbAfterUpdate); +void vpkc_app_set_hook_after_update(vpkc_hook_callback_t cbAfterUpdate); /// \group VelopackApp -VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_first_run(vpkc_hook_callback_t cbFirstRun); +void vpkc_app_set_hook_first_run(vpkc_hook_callback_t cbFirstRun); /// \group VelopackApp -VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_restarted(vpkc_hook_callback_t cbRestarted); +void vpkc_app_set_hook_restarted(vpkc_hook_callback_t cbRestarted); /// Given a function has returned a failure, this function will return the last error message as a string. -VPKC_EXPORT size_t VPKC_CALL vpkc_get_last_error(char* pszError, size_t cError); +size_t vpkc_get_last_error(char* pszError, size_t cError); /// Sets the callback to be used/called with log messages from Velopack. -VPKC_EXPORT void VPKC_CALL vpkc_set_logger(vpkc_log_callback_t cbLog, void* pUserData = 0); +void vpkc_set_logger(vpkc_log_callback_t cbLog, void* pUserData = 0); #ifdef __cplusplus // end of extern "C" } @@ -594,6 +562,7 @@ public: throw_last_error(); return std::nullopt; case vpkc_update_check_t::NO_UPDATE_AVAILABLE: + case vpkc_update_check_t::REMOTE_IS_EMPTY: return std::nullopt; case vpkc_update_check_t::UPDATE_AVAILABLE: UpdateInfo cpp_info = to_cpp(update); diff --git a/src/lib-cpp/src/bridge.cc b/src/lib-cpp/src/bridge.cc index 243bfd33..94998bf7 100644 --- a/src/lib-cpp/src/bridge.cc +++ b/src/lib-cpp/src/bridge.cc @@ -1,408 +1,408 @@ -// Uncomment to enable debug type checking -// #pragma include_alias( "velopack_libc/src/lib.rs.h", "../../../target/cxxbridge/velopack_libc/src/lib.rs.h" ) -// #pragma include_alias( "velopack_libc/include/Velopack.h", "../include/Velopack.h" ) -// #pragma include_alias( "velopack_libc/src/bridge.hpp", "bridge.hpp" ) -// #pragma include_alias( "rust/cxx.h", "../../../target/cxxbridge/rust/cxx.h" ) +// // Uncomment to enable debug type checking +// // #pragma include_alias( "velopack_libc/src/lib.rs.h", "../../../target/cxxbridge/velopack_libc/src/lib.rs.h" ) +// // #pragma include_alias( "velopack_libc/include/Velopack.h", "../include/Velopack.h" ) +// // #pragma include_alias( "velopack_libc/src/bridge.hpp", "bridge.hpp" ) +// // #pragma include_alias( "rust/cxx.h", "../../../target/cxxbridge/rust/cxx.h" ) -#include "velopack_libc/src/lib.rs.h" +// #include "velopack_libc/src/lib.rs.h" -static inline std::string to_bridgestring(const char* psz) { - return psz == nullptr ? "" : psz; -} +// static inline std::string to_bridgestring(const char* psz) { +// return psz == nullptr ? "" : psz; +// } -static inline char* to_cstring(const std::string& str) { - return const_cast(str.c_str()); -} +// static inline char* to_cstring(const std::string& str) { +// return const_cast(str.c_str()); +// } -static inline char* to_cstring_opt(const std::optional& str) { - return str.has_value() ? to_cstring(str.value()) : nullptr; -} +// static inline char* to_cstring_opt(const std::optional& str) { +// return str.has_value() ? to_cstring(str.value()) : nullptr; +// } -static inline StringOption to_bridgestring_opt(const char* psz) { - StringOption opt; - if (psz == nullptr) { - opt.has_data = false; - return opt; - } - opt.has_data = true; - opt.data = psz; - return opt; -} +// static inline StringOption to_bridgestring_opt(const char* psz) { +// StringOption opt; +// if (psz == nullptr) { +// opt.has_data = false; +// return opt; +// } +// opt.has_data = true; +// opt.data = psz; +// return opt; +// } -static inline void allocate_string(::rust::String& str, char** ppsz) { -#ifdef _WIN32 - *ppsz = _strdup(str.c_str()); -#else - *ppsz = strdup(str.c_str()); -#endif -} +// static inline void allocate_string(::rust::String& str, char** ppsz) { +// #ifdef _WIN32 +// *ppsz = _strdup(str.c_str()); +// #else +// *ppsz = strdup(str.c_str()); +// #endif +// } -static inline void allocate_string_opt(StringOption str, char** ppsz) { - if (str.has_data) { - allocate_string(str.data, ppsz); - } else { - *ppsz = nullptr; - } -} +// static inline void allocate_string_opt(StringOption str, char** ppsz) { +// if (str.has_data) { +// allocate_string(str.data, ppsz); +// } else { +// *ppsz = nullptr; +// } +// } -// !! AUTO-GENERATED-START BRIDGE_MAPPING -static inline VelopackLocatorConfigDto to_bridge(vpkc_locator_config_t* pDto) { - if (pDto == nullptr) { return {}; } - return { - to_bridgestring(pDto->RootAppDir), - to_bridgestring(pDto->UpdateExePath), - to_bridgestring(pDto->PackagesDir), - to_bridgestring(pDto->ManifestPath), - to_bridgestring(pDto->CurrentBinaryDir), - pDto->IsPortable, - }; -} +// // !! AUTO-GENERATED-START BRIDGE_MAPPING +// static inline VelopackLocatorConfigDto to_bridge(vpkc_locator_config_t* pDto) { +// if (pDto == nullptr) { return {}; } +// return { +// to_bridgestring(pDto->RootAppDir), +// to_bridgestring(pDto->UpdateExePath), +// to_bridgestring(pDto->PackagesDir), +// to_bridgestring(pDto->ManifestPath), +// to_bridgestring(pDto->CurrentBinaryDir), +// pDto->IsPortable, +// }; +// } -static inline VelopackLocatorConfigDtoOption to_bridge_opt(vpkc_locator_config_t* pDto) { - VelopackLocatorConfigDtoOption opt; - if (pDto == nullptr) { - opt.has_data = false; - return opt; - } +// static inline VelopackLocatorConfigDtoOption to_bridge_opt(vpkc_locator_config_t* pDto) { +// VelopackLocatorConfigDtoOption opt; +// if (pDto == nullptr) { +// opt.has_data = false; +// return opt; +// } - opt.has_data = true; - opt.data = to_bridge(pDto); - return opt; -} +// opt.has_data = true; +// opt.data = to_bridge(pDto); +// return opt; +// } -static inline void allocate_velopacklocatorconfig(VelopackLocatorConfigDto bridgeDto, vpkc_locator_config_t* pDto) { - if (pDto == nullptr) { return; } - allocate_string(bridgeDto.RootAppDir, &pDto->RootAppDir); - allocate_string(bridgeDto.UpdateExePath, &pDto->UpdateExePath); - allocate_string(bridgeDto.PackagesDir, &pDto->PackagesDir); - allocate_string(bridgeDto.ManifestPath, &pDto->ManifestPath); - allocate_string(bridgeDto.CurrentBinaryDir, &pDto->CurrentBinaryDir); - pDto->IsPortable = bridgeDto.IsPortable; -} +// static inline void allocate_velopacklocatorconfig(VelopackLocatorConfigDto bridgeDto, vpkc_locator_config_t* pDto) { +// if (pDto == nullptr) { return; } +// allocate_string(bridgeDto.RootAppDir, &pDto->RootAppDir); +// allocate_string(bridgeDto.UpdateExePath, &pDto->UpdateExePath); +// allocate_string(bridgeDto.PackagesDir, &pDto->PackagesDir); +// allocate_string(bridgeDto.ManifestPath, &pDto->ManifestPath); +// allocate_string(bridgeDto.CurrentBinaryDir, &pDto->CurrentBinaryDir); +// pDto->IsPortable = bridgeDto.IsPortable; +// } -static inline void free_velopacklocatorconfig(vpkc_locator_config_t* pDto) { - if (pDto == nullptr) { return; } - free(pDto->RootAppDir); - free(pDto->UpdateExePath); - free(pDto->PackagesDir); - free(pDto->ManifestPath); - free(pDto->CurrentBinaryDir); -} +// static inline void free_velopacklocatorconfig(vpkc_locator_config_t* pDto) { +// if (pDto == nullptr) { return; } +// free(pDto->RootAppDir); +// free(pDto->UpdateExePath); +// free(pDto->PackagesDir); +// free(pDto->ManifestPath); +// free(pDto->CurrentBinaryDir); +// } -static inline VelopackAssetDto to_bridge(vpkc_asset_t* pDto) { - if (pDto == nullptr) { return {}; } - return { - to_bridgestring(pDto->PackageId), - to_bridgestring(pDto->Version), - to_bridgestring(pDto->Type), - to_bridgestring(pDto->FileName), - to_bridgestring(pDto->SHA1), - to_bridgestring(pDto->SHA256), - pDto->Size, - to_bridgestring(pDto->NotesMarkdown), - to_bridgestring(pDto->NotesHtml), - }; -} +// static inline VelopackAssetDto to_bridge(vpkc_asset_t* pDto) { +// if (pDto == nullptr) { return {}; } +// return { +// to_bridgestring(pDto->PackageId), +// to_bridgestring(pDto->Version), +// to_bridgestring(pDto->Type), +// to_bridgestring(pDto->FileName), +// to_bridgestring(pDto->SHA1), +// to_bridgestring(pDto->SHA256), +// pDto->Size, +// to_bridgestring(pDto->NotesMarkdown), +// to_bridgestring(pDto->NotesHtml), +// }; +// } -static inline VelopackAssetDtoOption to_bridge_opt(vpkc_asset_t* pDto) { - VelopackAssetDtoOption opt; - if (pDto == nullptr) { - opt.has_data = false; - return opt; - } +// static inline VelopackAssetDtoOption to_bridge_opt(vpkc_asset_t* pDto) { +// VelopackAssetDtoOption opt; +// if (pDto == nullptr) { +// opt.has_data = false; +// return opt; +// } - opt.has_data = true; - opt.data = to_bridge(pDto); - return opt; -} +// opt.has_data = true; +// opt.data = to_bridge(pDto); +// return opt; +// } -static inline void allocate_velopackasset(VelopackAssetDto bridgeDto, vpkc_asset_t* pDto) { - if (pDto == nullptr) { return; } - allocate_string(bridgeDto.PackageId, &pDto->PackageId); - allocate_string(bridgeDto.Version, &pDto->Version); - allocate_string(bridgeDto.Type, &pDto->Type); - allocate_string(bridgeDto.FileName, &pDto->FileName); - allocate_string(bridgeDto.SHA1, &pDto->SHA1); - allocate_string(bridgeDto.SHA256, &pDto->SHA256); - pDto->Size = bridgeDto.Size; - allocate_string(bridgeDto.NotesMarkdown, &pDto->NotesMarkdown); - allocate_string(bridgeDto.NotesHtml, &pDto->NotesHtml); -} +// static inline void allocate_velopackasset(VelopackAssetDto bridgeDto, vpkc_asset_t* pDto) { +// if (pDto == nullptr) { return; } +// allocate_string(bridgeDto.PackageId, &pDto->PackageId); +// allocate_string(bridgeDto.Version, &pDto->Version); +// allocate_string(bridgeDto.Type, &pDto->Type); +// allocate_string(bridgeDto.FileName, &pDto->FileName); +// allocate_string(bridgeDto.SHA1, &pDto->SHA1); +// allocate_string(bridgeDto.SHA256, &pDto->SHA256); +// pDto->Size = bridgeDto.Size; +// allocate_string(bridgeDto.NotesMarkdown, &pDto->NotesMarkdown); +// allocate_string(bridgeDto.NotesHtml, &pDto->NotesHtml); +// } -static inline void free_velopackasset(vpkc_asset_t* pDto) { - if (pDto == nullptr) { return; } - free(pDto->PackageId); - free(pDto->Version); - free(pDto->Type); - free(pDto->FileName); - free(pDto->SHA1); - free(pDto->SHA256); - free(pDto->NotesMarkdown); - free(pDto->NotesHtml); -} +// static inline void free_velopackasset(vpkc_asset_t* pDto) { +// if (pDto == nullptr) { return; } +// free(pDto->PackageId); +// free(pDto->Version); +// free(pDto->Type); +// free(pDto->FileName); +// free(pDto->SHA1); +// free(pDto->SHA256); +// free(pDto->NotesMarkdown); +// free(pDto->NotesHtml); +// } -static inline UpdateInfoDto to_bridge(vpkc_update_info_t* pDto) { - if (pDto == nullptr) { return {}; } - return { - to_bridge(&pDto->TargetFullRelease), - pDto->IsDowngrade, - }; -} +// static inline UpdateInfoDto to_bridge(vpkc_update_info_t* pDto) { +// if (pDto == nullptr) { return {}; } +// return { +// to_bridge(&pDto->TargetFullRelease), +// pDto->IsDowngrade, +// }; +// } -static inline UpdateInfoDtoOption to_bridge_opt(vpkc_update_info_t* pDto) { - UpdateInfoDtoOption opt; - if (pDto == nullptr) { - opt.has_data = false; - return opt; - } +// static inline UpdateInfoDtoOption to_bridge_opt(vpkc_update_info_t* pDto) { +// UpdateInfoDtoOption opt; +// if (pDto == nullptr) { +// opt.has_data = false; +// return opt; +// } - opt.has_data = true; - opt.data = to_bridge(pDto); - return opt; -} +// opt.has_data = true; +// opt.data = to_bridge(pDto); +// return opt; +// } -static inline void allocate_updateinfo(UpdateInfoDto bridgeDto, vpkc_update_info_t* pDto) { - if (pDto == nullptr) { return; } - allocate_velopackasset(bridgeDto.TargetFullRelease, &pDto->TargetFullRelease); - pDto->IsDowngrade = bridgeDto.IsDowngrade; -} +// static inline void allocate_updateinfo(UpdateInfoDto bridgeDto, vpkc_update_info_t* pDto) { +// if (pDto == nullptr) { return; } +// allocate_velopackasset(bridgeDto.TargetFullRelease, &pDto->TargetFullRelease); +// pDto->IsDowngrade = bridgeDto.IsDowngrade; +// } -static inline void free_updateinfo(vpkc_update_info_t* pDto) { - if (pDto == nullptr) { return; } - free_velopackasset(&pDto->TargetFullRelease); -} +// static inline void free_updateinfo(vpkc_update_info_t* pDto) { +// if (pDto == nullptr) { return; } +// free_velopackasset(&pDto->TargetFullRelease); +// } -static inline UpdateOptionsDto to_bridge(vpkc_update_options_t* pDto) { - if (pDto == nullptr) { return {}; } - return { - pDto->AllowVersionDowngrade, - to_bridgestring_opt(pDto->ExplicitChannel), - }; -} +// static inline UpdateOptionsDto to_bridge(vpkc_update_options_t* pDto) { +// if (pDto == nullptr) { return {}; } +// return { +// pDto->AllowVersionDowngrade, +// to_bridgestring_opt(pDto->ExplicitChannel), +// }; +// } -static inline UpdateOptionsDtoOption to_bridge_opt(vpkc_update_options_t* pDto) { - UpdateOptionsDtoOption opt; - if (pDto == nullptr) { - opt.has_data = false; - return opt; - } +// static inline UpdateOptionsDtoOption to_bridge_opt(vpkc_update_options_t* pDto) { +// UpdateOptionsDtoOption opt; +// if (pDto == nullptr) { +// opt.has_data = false; +// return opt; +// } - opt.has_data = true; - opt.data = to_bridge(pDto); - return opt; -} +// opt.has_data = true; +// opt.data = to_bridge(pDto); +// return opt; +// } -static inline void allocate_updateoptions(UpdateOptionsDto bridgeDto, vpkc_update_options_t* pDto) { - if (pDto == nullptr) { return; } - pDto->AllowVersionDowngrade = bridgeDto.AllowVersionDowngrade; - allocate_string_opt(bridgeDto.ExplicitChannel, &pDto->ExplicitChannel); -} +// static inline void allocate_updateoptions(UpdateOptionsDto bridgeDto, vpkc_update_options_t* pDto) { +// if (pDto == nullptr) { return; } +// pDto->AllowVersionDowngrade = bridgeDto.AllowVersionDowngrade; +// allocate_string_opt(bridgeDto.ExplicitChannel, &pDto->ExplicitChannel); +// } -static inline void free_updateoptions(vpkc_update_options_t* pDto) { - if (pDto == nullptr) { return; } - free(pDto->ExplicitChannel); -} -// !! AUTO-GENERATED-END BRIDGE_MAPPING +// static inline void free_updateoptions(vpkc_update_options_t* pDto) { +// if (pDto == nullptr) { return; } +// free(pDto->ExplicitChannel); +// } +// // !! AUTO-GENERATED-END BRIDGE_MAPPING -static inline size_t return_c_string(std::string& value, char* psz, size_t csz) { - if (value.empty()) { - return 0; - } +// static inline size_t return_c_string(std::string& value, char* psz, size_t csz) { +// if (value.empty()) { +// return 0; +// } - const char* c_str = value.c_str(); - size_t len = strlen(c_str); - if (psz == nullptr || csz == 0 || len == 0) { - // no buffer has been provided, return the length - return len; - } +// const char* c_str = value.c_str(); +// size_t len = strlen(c_str); +// if (psz == nullptr || csz == 0 || len == 0) { +// // no buffer has been provided, return the length +// return len; +// } - // shorten the length if it's longer than the buffer - if (len > csz) { - len = csz; - } +// // shorten the length if it's longer than the buffer +// if (len > csz) { +// len = csz; +// } - // copy the string to the buffer - memcpy(psz, c_str, len); - return len; -} +// // copy the string to the buffer +// memcpy(psz, c_str, len); +// return len; +// } -// Error handling -std::string lastError; -VPKC_EXPORT size_t VPKC_CALL vpkc_get_last_error(char* pszError, size_t cError) { - return return_c_string(lastError, pszError, cError); -} -static inline void set_last_error(const char* pszError) { - lastError = pszError; -} -static inline void clear_last_error() { - lastError.clear(); -} +// // Error handling +// std::string lastError; +// VPKC_EXPORT size_t VPKC_CALL vpkc_get_last_error(char* pszError, size_t cError) { +// return return_c_string(lastError, pszError, cError); +// } +// static inline void set_last_error(const char* pszError) { +// lastError = pszError; +// } +// static inline void clear_last_error() { +// lastError.clear(); +// } -// Update Manager -VPKC_EXPORT bool VPKC_CALL vpkc_new_update_manager(const char* pszUrlOrString, vpkc_update_options_t* pOptions, vpkc_locator_config_t* pLocator, vpkc_update_manager_t** pManager) { - clear_last_error(); - try { - if (pManager == nullptr) { - set_last_error("pManager cannot be null"); - return false; - } +// // Update Manager +// VPKC_EXPORT bool VPKC_CALL vpkc_new_update_manager(const char* pszUrlOrString, vpkc_update_options_t* pOptions, vpkc_locator_config_t* pLocator, vpkc_update_manager_t** pManager) { +// clear_last_error(); +// try { +// if (pManager == nullptr) { +// set_last_error("pManager cannot be null"); +// return false; +// } - VelopackLocatorConfigDtoOption locator = to_bridge_opt(pLocator); - UpdateOptionsDtoOption options = to_bridge_opt(pOptions); +// VelopackLocatorConfigDtoOption locator = to_bridge_opt(pLocator); +// UpdateOptionsDtoOption options = to_bridge_opt(pOptions); - ::rust::Box<::UpdateManagerOpaque> manager = bridge_new_update_manager(pszUrlOrString, options, locator); - UpdateManagerOpaque* pOpaque = manager.into_raw(); - *pManager = reinterpret_cast(pOpaque); - return true; - } catch (const std::exception& e) { - set_last_error(e.what()); - return false; - } -} -VPKC_EXPORT size_t VPKC_CALL vpkc_get_current_version(vpkc_update_manager_t* pManager, char* pszVersion, size_t cVersion) { - UpdateManagerOpaque* pOpaque = reinterpret_cast(pManager); - std::string version = (std::string)bridge_get_current_version(*pOpaque); - return return_c_string(version, pszVersion, cVersion); -} -VPKC_EXPORT size_t VPKC_CALL vpkc_get_app_id(vpkc_update_manager_t* pManager, char* pszId, size_t cId) { - UpdateManagerOpaque* pOpaque = reinterpret_cast(pManager); - std::string id = (std::string)bridge_get_app_id(*pOpaque); - return return_c_string(id, pszId, cId); +// ::rust::Box<::UpdateManagerOpaque> manager = bridge_new_update_manager(pszUrlOrString, options, locator); +// UpdateManagerOpaque* pOpaque = manager.into_raw(); +// *pManager = reinterpret_cast(pOpaque); +// return true; +// } catch (const std::exception& e) { +// set_last_error(e.what()); +// return false; +// } +// } +// VPKC_EXPORT size_t VPKC_CALL vpkc_get_current_version(vpkc_update_manager_t* pManager, char* pszVersion, size_t cVersion) { +// UpdateManagerOpaque* pOpaque = reinterpret_cast(pManager); +// std::string version = (std::string)bridge_get_current_version(*pOpaque); +// return return_c_string(version, pszVersion, cVersion); +// } +// VPKC_EXPORT size_t VPKC_CALL vpkc_get_app_id(vpkc_update_manager_t* pManager, char* pszId, size_t cId) { +// UpdateManagerOpaque* pOpaque = reinterpret_cast(pManager); +// std::string id = (std::string)bridge_get_app_id(*pOpaque); +// return return_c_string(id, pszId, cId); -} -VPKC_EXPORT bool VPKC_CALL vpkc_is_portable(vpkc_update_manager_t* pManager) { - UpdateManagerOpaque* pOpaque = reinterpret_cast(pManager); - return bridge_is_portable(*pOpaque); -} -VPKC_EXPORT bool VPKC_CALL vpkc_update_pending_restart(vpkc_update_manager_t* pManager, vpkc_asset_t* pAsset) { - UpdateManagerOpaque* pOpaque = reinterpret_cast(pManager); - VelopackAssetDtoOption asset = bridge_update_pending_restart(*pOpaque); - if (asset.has_data) { - allocate_velopackasset(asset.data, pAsset); - return true; - } - return false; -} -VPKC_EXPORT vpkc_update_check_t VPKC_CALL vpkc_check_for_updates(vpkc_update_manager_t* pManager, vpkc_update_info_t* pUpdate) { - clear_last_error(); - try { - UpdateManagerOpaque* pOpaque = reinterpret_cast(pManager); - UpdateInfoDtoOption update = bridge_check_for_updates(*pOpaque); - if (update.has_data) { - allocate_updateinfo(update.data, pUpdate); - return vpkc_update_check_t::UPDATE_AVAILABLE; - } - return vpkc_update_check_t::NO_UPDATE_AVAILABLE; - } - catch (const std::exception& e) { - set_last_error(e.what()); - return vpkc_update_check_t::UPDATE_ERROR; - } -} -VPKC_EXPORT bool VPKC_CALL vpkc_download_updates(vpkc_update_manager_t* pManager, vpkc_update_info_t* pUpdate, vpkc_progress_callback_t cbProgress, void* pUserData) { - clear_last_error(); - try { - if (!pUpdate) { - set_last_error("pUpdate is a required parameter"); - return false; - } +// } +// VPKC_EXPORT bool VPKC_CALL vpkc_is_portable(vpkc_update_manager_t* pManager) { +// UpdateManagerOpaque* pOpaque = reinterpret_cast(pManager); +// return bridge_is_portable(*pOpaque); +// } +// VPKC_EXPORT bool VPKC_CALL vpkc_update_pending_restart(vpkc_update_manager_t* pManager, vpkc_asset_t* pAsset) { +// UpdateManagerOpaque* pOpaque = reinterpret_cast(pManager); +// VelopackAssetDtoOption asset = bridge_update_pending_restart(*pOpaque); +// if (asset.has_data) { +// allocate_velopackasset(asset.data, pAsset); +// return true; +// } +// return false; +// } +// VPKC_EXPORT vpkc_update_check_t VPKC_CALL vpkc_check_for_updates(vpkc_update_manager_t* pManager, vpkc_update_info_t* pUpdate) { +// clear_last_error(); +// try { +// UpdateManagerOpaque* pOpaque = reinterpret_cast(pManager); +// UpdateInfoDtoOption update = bridge_check_for_updates(*pOpaque); +// if (update.has_data) { +// allocate_updateinfo(update.data, pUpdate); +// return vpkc_update_check_t::UPDATE_AVAILABLE; +// } +// return vpkc_update_check_t::NO_UPDATE_AVAILABLE; +// } +// catch (const std::exception& e) { +// set_last_error(e.what()); +// return vpkc_update_check_t::UPDATE_ERROR; +// } +// } +// VPKC_EXPORT bool VPKC_CALL vpkc_download_updates(vpkc_update_manager_t* pManager, vpkc_update_info_t* pUpdate, vpkc_progress_callback_t cbProgress, void* pUserData) { +// clear_last_error(); +// try { +// if (!pUpdate) { +// set_last_error("pUpdate is a required parameter"); +// return false; +// } - UpdateManagerOpaque* pOpaque = reinterpret_cast(pManager); - UpdateInfoDto update = to_bridge(pUpdate); +// UpdateManagerOpaque* pOpaque = reinterpret_cast(pManager); +// UpdateInfoDto update = to_bridge(pUpdate); - DownloadCallbackManager download{}; - download.progress_cb = cbProgress; - download.user_data = pUserData; - bridge_download_updates(*pOpaque, update, download); - return true; - } - catch (const std::exception& e) { - set_last_error(e.what()); - return false; - } -} -VPKC_EXPORT bool VPKC_CALL vpkc_wait_exit_then_apply_update(vpkc_update_manager_t* pManager, vpkc_asset_t* pAsset, bool bSilent, bool bRestart, char** pRestartArgs, size_t cRestartArgs) { - clear_last_error(); - try { - if (!pAsset) { - set_last_error("pAsset is a required parameter"); - return false; - } +// DownloadCallbackManager download{}; +// download.progress_cb = cbProgress; +// download.user_data = pUserData; +// bridge_download_updates(*pOpaque, update, download); +// return true; +// } +// catch (const std::exception& e) { +// set_last_error(e.what()); +// return false; +// } +// } +// VPKC_EXPORT bool VPKC_CALL vpkc_wait_exit_then_apply_update(vpkc_update_manager_t* pManager, vpkc_asset_t* pAsset, bool bSilent, bool bRestart, char** pRestartArgs, size_t cRestartArgs) { +// clear_last_error(); +// try { +// if (!pAsset) { +// set_last_error("pAsset is a required parameter"); +// return false; +// } - UpdateManagerOpaque* pOpaque = reinterpret_cast(pManager); - VelopackAssetDto asset = to_bridge(pAsset); +// UpdateManagerOpaque* pOpaque = reinterpret_cast(pManager); +// VelopackAssetDto asset = to_bridge(pAsset); - ::rust::Vec<::rust::String> restartArgs{}; - for (size_t i = 0; i < cRestartArgs; i++) { - restartArgs.push_back(pRestartArgs[i]); - } +// ::rust::Vec<::rust::String> restartArgs{}; +// for (size_t i = 0; i < cRestartArgs; i++) { +// restartArgs.push_back(pRestartArgs[i]); +// } - bridge_wait_exit_then_apply_update(*pOpaque, asset, bSilent, bRestart, restartArgs); - return true; - } - catch (const std::exception& e) { - set_last_error(e.what()); - return false; - } -} +// bridge_wait_exit_then_apply_update(*pOpaque, asset, bSilent, bRestart, restartArgs); +// return true; +// } +// catch (const std::exception& e) { +// set_last_error(e.what()); +// return false; +// } +// } -// VelopackApp -bool autoApply = true; -StringArrayOption args{}; -VelopackLocatorConfigDtoOption locator{}; -HookCallbackManager hooks{}; +// // VelopackApp +// bool autoApply = true; +// StringArrayOption args{}; +// VelopackLocatorConfigDtoOption locator{}; +// HookCallbackManager hooks{}; -VPKC_EXPORT void VPKC_CALL vpkc_app_set_auto_apply_on_startup(bool bAutoApply) { - autoApply = bAutoApply; -} -VPKC_EXPORT void VPKC_CALL vpkc_app_set_args(char** pArgs, size_t cArgs) { - args.has_data = true; - args.data.clear(); - for (size_t i = 0; i < cArgs; i++) { - args.data.push_back(pArgs[i]); - } -} -VPKC_EXPORT void VPKC_CALL vpkc_app_set_locator(vpkc_locator_config_t* pLocator) { - locator = to_bridge_opt(pLocator); -} -VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_after_install(vpkc_hook_callback_t cbAfterInstall) { - hooks.after_install = cbAfterInstall; -} -VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_before_uninstall(vpkc_hook_callback_t cbBeforeUninstall) { - hooks.before_uninstall = cbBeforeUninstall; -} -VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_before_update(vpkc_hook_callback_t cbBeforeUpdate) { - hooks.before_update = cbBeforeUpdate; -} -VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_after_update(vpkc_hook_callback_t cbAfterUpdate) { - hooks.after_update = cbAfterUpdate; -} -VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_first_run(vpkc_hook_callback_t cbFirstRun) { - hooks.first_run = cbFirstRun; -} -VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_restarted(vpkc_hook_callback_t cbRestarted) { - hooks.restarted = cbRestarted; -} -VPKC_EXPORT void VPKC_CALL vpkc_app_run(void* pUserData) { - hooks.user_data = pUserData; - bridge_appbuilder_run(hooks, args, locator, autoApply); -} +// VPKC_EXPORT void VPKC_CALL vpkc_app_set_auto_apply_on_startup(bool bAutoApply) { +// autoApply = bAutoApply; +// } +// VPKC_EXPORT void VPKC_CALL vpkc_app_set_args(char** pArgs, size_t cArgs) { +// args.has_data = true; +// args.data.clear(); +// for (size_t i = 0; i < cArgs; i++) { +// args.data.push_back(pArgs[i]); +// } +// } +// VPKC_EXPORT void VPKC_CALL vpkc_app_set_locator(vpkc_locator_config_t* pLocator) { +// locator = to_bridge_opt(pLocator); +// } +// VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_after_install(vpkc_hook_callback_t cbAfterInstall) { +// hooks.after_install = cbAfterInstall; +// } +// VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_before_uninstall(vpkc_hook_callback_t cbBeforeUninstall) { +// hooks.before_uninstall = cbBeforeUninstall; +// } +// VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_before_update(vpkc_hook_callback_t cbBeforeUpdate) { +// hooks.before_update = cbBeforeUpdate; +// } +// VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_after_update(vpkc_hook_callback_t cbAfterUpdate) { +// hooks.after_update = cbAfterUpdate; +// } +// VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_first_run(vpkc_hook_callback_t cbFirstRun) { +// hooks.first_run = cbFirstRun; +// } +// VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_restarted(vpkc_hook_callback_t cbRestarted) { +// hooks.restarted = cbRestarted; +// } +// VPKC_EXPORT void VPKC_CALL vpkc_app_run(void* pUserData) { +// hooks.user_data = pUserData; +// bridge_appbuilder_run(hooks, args, locator, autoApply); +// } -// Misc functions -LoggerCallbackManager logMgr{}; -VPKC_EXPORT void VPKC_CALL vpkc_set_logger(vpkc_log_callback_t cbLog, void* pUserData) { - logMgr.lob_cb = cbLog; - logMgr.user_data = pUserData; - bridge_set_logger_callback(&logMgr); -} -VPKC_EXPORT void VPKC_CALL vpkc_free_update_manager(vpkc_update_manager_t* pManager) { - UpdateManagerOpaque* pOpaque = reinterpret_cast(pManager); - auto box = ::rust::Box<::UpdateManagerOpaque>::from_raw(pOpaque); - // this will free when the box goes out of scope -} -VPKC_EXPORT void VPKC_CALL vpkc_free_update_info(vpkc_update_info_t* pUpdateInfo) { - free_updateinfo(pUpdateInfo); -} -VPKC_EXPORT void VPKC_CALL vpkc_free_asset(vpkc_asset_t* pAsset) { - free_velopackasset(pAsset); -} \ No newline at end of file +// // Misc functions +// LoggerCallbackManager logMgr{}; +// VPKC_EXPORT void VPKC_CALL vpkc_set_logger(vpkc_log_callback_t cbLog, void* pUserData) { +// logMgr.lob_cb = cbLog; +// logMgr.user_data = pUserData; +// bridge_set_logger_callback(&logMgr); +// } +// VPKC_EXPORT void VPKC_CALL vpkc_free_update_manager(vpkc_update_manager_t* pManager) { +// UpdateManagerOpaque* pOpaque = reinterpret_cast(pManager); +// auto box = ::rust::Box<::UpdateManagerOpaque>::from_raw(pOpaque); +// // this will free when the box goes out of scope +// } +// VPKC_EXPORT void VPKC_CALL vpkc_free_update_info(vpkc_update_info_t* pUpdateInfo) { +// free_updateinfo(pUpdateInfo); +// } +// VPKC_EXPORT void VPKC_CALL vpkc_free_asset(vpkc_asset_t* pAsset) { +// free_velopackasset(pAsset); +// } \ No newline at end of file diff --git a/src/lib-cpp/src/bridge.hpp b/src/lib-cpp/src/bridge.hpp index 3a646275..740eb1d4 100644 --- a/src/lib-cpp/src/bridge.hpp +++ b/src/lib-cpp/src/bridge.hpp @@ -1,69 +1,69 @@ -#pragma once -#include "rust/cxx.h" -#include "velopack_libc/include/Velopack.h" +// #pragma once +// #include "rust/cxx.h" +// #include "velopack_libc/include/Velopack.h" -struct HookCallbackManager { - vpkc_hook_callback_t after_install = nullptr; - vpkc_hook_callback_t before_uninstall = nullptr; - vpkc_hook_callback_t before_update = nullptr; - vpkc_hook_callback_t after_update = nullptr; - vpkc_hook_callback_t first_run = nullptr; - vpkc_hook_callback_t restarted = nullptr; - void* user_data = nullptr; +// struct HookCallbackManager { +// vpkc_hook_callback_t after_install = nullptr; +// vpkc_hook_callback_t before_uninstall = nullptr; +// vpkc_hook_callback_t before_update = nullptr; +// vpkc_hook_callback_t after_update = nullptr; +// vpkc_hook_callback_t first_run = nullptr; +// vpkc_hook_callback_t restarted = nullptr; +// void* user_data = nullptr; - void install_hook(::rust::String app_version) const { - if (after_install) { - after_install(user_data, app_version.c_str()); - } - }; +// void install_hook(::rust::String app_version) const { +// if (after_install) { +// after_install(user_data, app_version.c_str()); +// } +// }; - void update_hook(::rust::String app_version) const { - if (after_update) { - after_update(user_data, app_version.c_str()); - } - }; +// void update_hook(::rust::String app_version) const { +// if (after_update) { +// after_update(user_data, app_version.c_str()); +// } +// }; - void obsolete_hook(::rust::String app_version) const { - if (before_update) { - before_update(user_data, app_version.c_str()); - } - }; +// void obsolete_hook(::rust::String app_version) const { +// if (before_update) { +// before_update(user_data, app_version.c_str()); +// } +// }; - void uninstall_hook(::rust::String app_version) const { - if (before_uninstall) { - before_uninstall(user_data, app_version.c_str()); - } - }; +// void uninstall_hook(::rust::String app_version) const { +// if (before_uninstall) { +// before_uninstall(user_data, app_version.c_str()); +// } +// }; - void firstrun_hook(::rust::String app_version) const { - if (first_run) { - first_run(user_data, app_version.c_str()); - } - }; +// void firstrun_hook(::rust::String app_version) const { +// if (first_run) { +// first_run(user_data, app_version.c_str()); +// } +// }; - void restarted_hook(::rust::String app_version) const { - if (restarted) { - restarted(user_data, app_version.c_str()); - } - }; -}; +// void restarted_hook(::rust::String app_version) const { +// if (restarted) { +// restarted(user_data, app_version.c_str()); +// } +// }; +// }; -struct DownloadCallbackManager { - vpkc_progress_callback_t progress_cb = nullptr; - void* user_data = nullptr; - void download_progress(int16_t progress) const { - if (progress_cb) { - progress_cb(user_data, progress); - } - }; -}; +// struct DownloadCallbackManager { +// vpkc_progress_callback_t progress_cb = nullptr; +// void* user_data = nullptr; +// void download_progress(int16_t progress) const { +// if (progress_cb) { +// progress_cb(user_data, progress); +// } +// }; +// }; -struct LoggerCallbackManager { - vpkc_log_callback_t lob_cb = nullptr; - void* user_data = nullptr; - void log(::rust::String level, ::rust::String message) const { - if (lob_cb) { - lob_cb(user_data, level.c_str(), message.c_str()); - } - }; -}; \ No newline at end of file +// struct LoggerCallbackManager { +// vpkc_log_callback_t lob_cb = nullptr; +// void* user_data = nullptr; +// void log(::rust::String level, ::rust::String message) const { +// if (lob_cb) { +// lob_cb(user_data, level.c_str(), message.c_str()); +// } +// }; +// }; \ No newline at end of file diff --git a/src/lib-cpp/src/lib.rs b/src/lib-cpp/src/lib.rs index 8888254d..4478d875 100644 --- a/src/lib-cpp/src/lib.rs +++ b/src/lib-cpp/src/lib.rs @@ -1,143 +1,352 @@ #![allow(dead_code)] #![allow(non_snake_case)] +#![allow(non_camel_case_types)] -mod map; -use map::*; +mod statics; +use statics::*; -use anyhow::{bail, Result}; -use log::{Level, Log, Metadata, Record}; -use std::sync::atomic::{AtomicUsize, Ordering}; +mod types; +use types::*; + +use anyhow::{anyhow, bail}; +use std::ffi::{c_char, c_void, CString}; use velopack::{sources, Error as VelopackError, UpdateCheck, UpdateManager, VelopackApp}; -#[cxx::bridge] -mod ffi { - // Shared structs with fields visible to both languages. - #[derive(Default)] - pub struct StringOption { - pub data: String, - pub has_data: bool, +#[repr(C)] +pub enum vpkc_update_check_t { + UPDATE_ERROR = -1, + UPDATE_AVAILABLE = 0, + NO_UPDATE_AVAILABLE = 1, + REMOTE_IS_EMPTY = 2, +} + +#[no_mangle] +pub extern "C" fn vpkc_new_update_manager( + psz_url_or_string: *const c_char, + p_options: *mut vpkc_update_options_t, + p_locator: *mut vpkc_locator_config_t, + p_manager: *mut *mut c_void, +) -> bool { + wrap_error(|| { + let update_url = c_to_string_opt(psz_url_or_string).ok_or(anyhow!("URL or path is null"))?; + let source = sources::AutoSource::new(&update_url); + let options = c_to_updateoptions_opt(p_options); + let locator = c_to_velopacklocatorconfig_opt(p_locator); + let manager = UpdateManager::new(source, options, locator)?; + let opaque = Box::new(UpdateManagerOpaque::new(manager)); + unsafe { *p_manager = Box::into_raw(opaque) as *mut c_void }; + Ok(()) + }) +} + +#[no_mangle] +pub extern "C" fn vpkc_get_current_version(p_manager: *mut c_void, psz_version: *mut c_char, c_version: usize) -> usize { + if p_manager.is_null() { + return 0; } - #[derive(Default)] - pub struct StringArrayOption { - pub data: Vec, - pub has_data: bool, + let manager = unsafe { &*(p_manager as *mut UpdateManagerOpaque) }; + let version = manager.obj.get_current_version_as_string(); + return_cstr(psz_version, c_version, &version) +} + +#[no_mangle] +pub extern "C" fn vpkc_get_app_id(p_manager: *mut c_void, psz_id: *mut c_char, c_id: usize) -> usize { + if p_manager.is_null() { + return 0; } - // !! AUTO-GENERATED-START BRIDGE_DTOS - #[derive(Default)] - pub struct VelopackLocatorConfigDto { - pub RootAppDir: String, - pub UpdateExePath: String, - pub PackagesDir: String, - pub ManifestPath: String, - pub CurrentBinaryDir: String, - pub IsPortable: bool, + let manager = unsafe { &*(p_manager as *mut UpdateManagerOpaque) }; + let app_id = manager.obj.get_app_id(); + return_cstr(psz_id, c_id, &app_id) +} + +#[no_mangle] +pub extern "C" fn vpkc_is_portable(p_manager: *mut c_void) -> bool { + if p_manager.is_null() { + return false; } - #[derive(Default)] - pub struct VelopackLocatorConfigDtoOption { - pub data: VelopackLocatorConfigDto, - pub has_data: bool, + let manager = unsafe { &*(p_manager as *mut UpdateManagerOpaque) }; + manager.obj.get_is_portable() +} + +#[no_mangle] +pub extern "C" fn vpkc_update_pending_restart(p_manager: *mut c_void, p_asset: *mut vpkc_asset_t) -> bool { + if p_manager.is_null() { + return false; } - #[derive(Default)] - pub struct VelopackAssetDto { - pub PackageId: String, - pub Version: String, - pub Type: String, - pub FileName: String, - pub SHA1: String, - pub SHA256: String, - pub Size: u64, - pub NotesMarkdown: String, - pub NotesHtml: String, + let manager = unsafe { &*(p_manager as *mut UpdateManagerOpaque) }; + let asset_opt = manager.obj.get_update_pending_restart(); + + if let Some(asset) = asset_opt { + unsafe { allocate_velopackasset(asset, p_asset) }; + true + } else { + false + } +} + +#[no_mangle] +pub extern "C" fn vpkc_check_for_updates(p_manager: *mut c_void, p_update: *mut vpkc_update_info_t) -> vpkc_update_check_t { + if p_manager.is_null() { + set_last_error("pManager must not be null"); + return vpkc_update_check_t::UPDATE_ERROR; } - #[derive(Default)] - pub struct VelopackAssetDtoOption { - pub data: VelopackAssetDto, - pub has_data: bool, + let manager = unsafe { &*(p_manager as *mut UpdateManagerOpaque) }; + + match manager.obj.check_for_updates() { + Ok(UpdateCheck::UpdateAvailable(info)) => { + unsafe { + allocate_updateinfo(info, p_update); + } + vpkc_update_check_t::UPDATE_AVAILABLE + } + Ok(UpdateCheck::RemoteIsEmpty) => vpkc_update_check_t::REMOTE_IS_EMPTY, + Ok(UpdateCheck::NoUpdateAvailable) => vpkc_update_check_t::NO_UPDATE_AVAILABLE, + Err(e) => { + set_last_error(&format!("{:?}", e)); + vpkc_update_check_t::UPDATE_ERROR + } + } +} + +#[no_mangle] +pub extern "C" fn vpkc_download_updates( + p_manager: *mut c_void, + p_update: *mut vpkc_update_info_t, + cb_progress: vpkc_progress_callback_t, + p_user_data: *mut c_void, +) -> bool { + wrap_error(|| { + if p_manager.is_null() { + bail!("pManager must not be null"); + } + + let manager = unsafe { &*(p_manager as *mut UpdateManagerOpaque) }; + let update = c_to_updateinfo_opt(p_update).ok_or(anyhow!("pUpdate must not be null"))?; + + let (progress_sender, progress_receiver) = std::sync::mpsc::channel::(); + let (completion_sender, completion_receiver) = std::sync::mpsc::channel::>(); + + // Move the download_updates call into a new thread + let manager = manager.clone(); + std::thread::spawn(move || { + let result = manager.obj.download_updates(&update, Some(progress_sender)); + let _ = completion_sender.send(result); + }); + + // Process progress updates on the caller's thread + loop { + // Try to receive progress updates without blocking + match progress_receiver.try_recv() { + Ok(progress) => { + cb_progress(p_user_data, progress as usize); + } + _ => { + // No progress updates available, sleep for a short time to avoid busy-waiting + std::thread::sleep(std::time::Duration::from_millis(50)); + } + } + + // Check if download is complete + match completion_receiver.try_recv() { + Ok(result) => { + // Download is complete, return the result (propagating any errors) + result?; + return Ok(()); + } + Err(std::sync::mpsc::TryRecvError::Empty) => { + // Download is still in progress, continue processing progress updates + } + Err(std::sync::mpsc::TryRecvError::Disconnected) => { + bail!("Download thread disconnected unexpectedly without returning a result"); + } + } + } + }) +} + +#[no_mangle] +pub extern "C" fn vpkc_wait_exit_then_apply_update( + p_manager: *mut c_void, + p_asset: *mut vpkc_asset_t, + b_silent: bool, + b_restart: bool, + p_restart_args: *mut *mut c_char, + c_restart_args: usize, +) -> bool { + wrap_error(|| { + if p_manager.is_null() { + bail!("pManager must not be null"); + } + + let manager = unsafe { &*(p_manager as *mut UpdateManagerOpaque) }; + let asset = c_to_velopackasset_opt(p_asset).ok_or(anyhow!("pAsset must not be null"))?; + let restart_args = c_to_string_array_opt(p_restart_args, c_restart_args).unwrap_or_default(); + manager.obj.wait_exit_then_apply_updates(&asset, b_silent, b_restart, &restart_args)?; + Ok(()) + }) +} + +#[no_mangle] +pub extern "C" fn vpkc_free_update_manager(p_manager: *mut c_void) { + if !p_manager.is_null() { + // Convert the raw pointer back into a Box to deallocate it properly + let _ = unsafe { Box::from_raw(p_manager as *mut UpdateManagerOpaque) }; + } +} + +#[no_mangle] +pub extern "C" fn vpkc_free_update_info(p_update_info: *mut vpkc_update_info_t) { + if !p_update_info.is_null() { + unsafe { free_updateinfo(p_update_info) }; + } +} + +#[no_mangle] +pub extern "C" fn vpkc_free_asset(p_asset: *mut vpkc_asset_t) { + if !p_asset.is_null() { + unsafe { free_velopackasset(p_asset) }; + } +} + +#[no_mangle] +pub extern "C" fn vpkc_app_run(p_user_data: *mut c_void) { + let app_options = VELOPACK_APP.read().unwrap(); + let mut app = VelopackApp::build(); + + if let Some(auto_apply) = app_options.auto_apply { + app = app.set_auto_apply_on_startup(auto_apply); } - #[derive(Default)] - pub struct UpdateInfoDto { - pub TargetFullRelease: VelopackAssetDto, - pub IsDowngrade: bool, + if let Some(args) = &app_options.args { + app = app.set_args(args.clone()); } - #[derive(Default)] - pub struct UpdateInfoDtoOption { - pub data: UpdateInfoDto, - pub has_data: bool, + if let Some(locator) = &app_options.locator { + app = app.set_locator(locator.clone()); } - #[derive(Default)] - pub struct UpdateOptionsDto { - pub AllowVersionDowngrade: bool, - pub ExplicitChannel: StringOption, + if let Some(hook) = &app_options.install_hook { + app = app.on_after_install_fast_callback(|version| { + let c_string = CString::new(version.to_string()).unwrap(); + hook(p_user_data, c_string.as_ptr()); + }); } - #[derive(Default)] - pub struct UpdateOptionsDtoOption { - pub data: UpdateOptionsDto, - pub has_data: bool, - } - // !! AUTO-GENERATED-END BRIDGE_DTOS - - // C++ types and signatures exposed to Rust. - unsafe extern "C++" { - include!("velopack_libc/include/Velopack.h"); - include!("velopack_libc/src/bridge.hpp"); - - type HookCallbackManager; - fn install_hook(self: &HookCallbackManager, app_version: String); - fn update_hook(self: &HookCallbackManager, app_version: String); - fn obsolete_hook(self: &HookCallbackManager, app_version: String); - fn uninstall_hook(self: &HookCallbackManager, app_version: String); - fn firstrun_hook(self: &HookCallbackManager, app_version: String); - fn restarted_hook(self: &HookCallbackManager, app_version: String); - - type DownloadCallbackManager; - fn download_progress(self: &DownloadCallbackManager, progress: i16); - - type LoggerCallbackManager; - fn log(self: &LoggerCallbackManager, level: String, message: String); + if let Some(hook) = &app_options.uninstall_hook { + app = app.on_before_uninstall_fast_callback(|version| { + let c_string = CString::new(version.to_string()).unwrap(); + hook(p_user_data, c_string.as_ptr()); + }); } - // Rust types and signatures exposed to C++. - extern "Rust" { - type UpdateManagerOpaque; - fn bridge_new_update_manager( - url_or_path: &String, - options: &UpdateOptionsDtoOption, - locator: &VelopackLocatorConfigDtoOption, - ) -> Result>; - fn bridge_get_current_version(manager: &UpdateManagerOpaque) -> String; - fn bridge_get_app_id(manager: &UpdateManagerOpaque) -> String; - fn bridge_is_portable(manager: &UpdateManagerOpaque) -> bool; - fn bridge_update_pending_restart(manager: &UpdateManagerOpaque) -> VelopackAssetDtoOption; - fn bridge_check_for_updates(manager: &UpdateManagerOpaque) -> Result; - fn bridge_download_updates( - manager: &UpdateManagerOpaque, - to_download: &UpdateInfoDto, - progress: &DownloadCallbackManager, - ) -> Result<()>; - fn bridge_wait_exit_then_apply_update( - manager: &UpdateManagerOpaque, - to_apply: &VelopackAssetDto, - silent: bool, - restart: bool, - restart_args: &Vec, - ) -> Result<()>; - fn bridge_appbuilder_run( - cb: &HookCallbackManager, - custom_args: &StringArrayOption, - locator: &VelopackLocatorConfigDtoOption, - auto_apply: bool, - ); - unsafe fn bridge_set_logger_callback(cb: *mut LoggerCallbackManager); + if let Some(hook) = &app_options.obsolete_hook { + app = app.on_before_update_fast_callback(|version| { + let c_string = CString::new(version.to_string()).unwrap(); + hook(p_user_data, c_string.as_ptr()); + }); } + + if let Some(hook) = &app_options.update_hook { + app = app.on_after_update_fast_callback(|version| { + let c_string = CString::new(version.to_string()).unwrap(); + hook(p_user_data, c_string.as_ptr()); + }); + } + + if let Some(hook) = &app_options.firstrun_hook { + app = app.on_first_run(|version| { + let c_string = CString::new(version.to_string()).unwrap(); + hook(p_user_data, c_string.as_ptr()); + }); + } + + if let Some(hook) = &app_options.restarted_hook { + app = app.on_restarted(|version| { + let c_string = CString::new(version.to_string()).unwrap(); + hook(p_user_data, c_string.as_ptr()); + }); + } + + app.run(); +} + +#[no_mangle] +pub extern "C" fn vpkc_app_set_auto_apply_on_startup(b_auto_apply: bool) { + update_app_options(|opt| { + opt.auto_apply = Some(b_auto_apply); + }); +} + +#[no_mangle] +pub extern "C" fn vpkc_app_set_args(p_args: *mut *mut c_char, c_args: usize) { + update_app_options(|opt| { + opt.args = c_to_string_array_opt(p_args, c_args); + }); +} + +#[no_mangle] +pub extern "C" fn vpkc_app_set_locator(p_locator: *mut vpkc_locator_config_t) { + update_app_options(|opt| { + opt.locator = c_to_velopacklocatorconfig_opt(p_locator); + }); +} + +#[no_mangle] +pub extern "C" fn vpkc_app_set_hook_after_install(cb_after_install: vpkc_hook_callback_t) { + update_app_options(|opt| { + opt.install_hook = Some(cb_after_install); + }); +} + +#[no_mangle] +pub extern "C" fn vpkc_app_set_hook_before_uninstall(cb_before_uninstall: vpkc_hook_callback_t) { + update_app_options(|opt| { + opt.uninstall_hook = Some(cb_before_uninstall); + }); +} + +#[no_mangle] +pub extern "C" fn vpkc_app_set_hook_before_update(cb_before_update: vpkc_hook_callback_t) { + update_app_options(|opt| { + opt.obsolete_hook = Some(cb_before_update); + }); +} + +#[no_mangle] +pub extern "C" fn vpkc_app_set_hook_after_update(cb_after_update: vpkc_hook_callback_t) { + update_app_options(|opt| { + opt.update_hook = Some(cb_after_update); + }); +} + +#[no_mangle] +pub extern "C" fn vpkc_app_set_hook_first_run(cb_first_run: vpkc_hook_callback_t) { + update_app_options(|opt| { + opt.firstrun_hook = Some(cb_first_run); + }); +} + +#[no_mangle] +pub extern "C" fn vpkc_app_set_hook_restarted(cb_restarted: vpkc_hook_callback_t) { + update_app_options(|opt| { + opt.restarted_hook = Some(cb_restarted); + }); +} + +#[no_mangle] +pub extern "C" fn vpkc_get_last_error(psz_error: *mut c_char, c_error: usize) -> usize { + let error = get_last_error(); + return_cstr(psz_error, c_error, &error) +} + +#[no_mangle] +pub extern "C" fn vpkc_set_logger(cb_log: vpkc_log_callback_t, p_user_data: *mut c_void) { + set_log_callback(cb_log, p_user_data); } #[derive(Clone)] @@ -157,185 +366,3 @@ impl Drop for UpdateManagerOpaque { log::debug!("UpdateManagerOpaque dropped"); } } - -fn bridge_new_update_manager( - url_or_path: &String, - options: &ffi::UpdateOptionsDtoOption, - locator: &ffi::VelopackLocatorConfigDtoOption, -) -> Result> { - let source = sources::AutoSource::new(url_or_path); - let options = updateoptions_to_core_option(options); - let locator = velopacklocatorconfig_to_core_option(locator); - let update_manager = UpdateManager::new(source, options, locator)?; - Ok(Box::new(UpdateManagerOpaque::new(update_manager))) -} - -fn bridge_get_current_version(manager: &UpdateManagerOpaque) -> String { - manager.obj.get_current_version_as_string() -} - -fn bridge_get_app_id(manager: &UpdateManagerOpaque) -> String { - manager.obj.get_app_id() -} - -fn bridge_is_portable(manager: &UpdateManagerOpaque) -> bool { - manager.obj.get_is_portable() -} - -fn bridge_update_pending_restart(manager: &UpdateManagerOpaque) -> ffi::VelopackAssetDtoOption { - let asset_opt = manager.obj.get_update_pending_restart(); - velopackasset_to_bridge_option(&asset_opt) -} - -fn bridge_check_for_updates(manager: &UpdateManagerOpaque) -> Result { - let info_opt = if let UpdateCheck::UpdateAvailable(info) = manager.obj.check_for_updates()? { Some(info) } else { None }; - Ok(updateinfo_to_bridge_option(&info_opt)) -} - -fn bridge_download_updates( - manager: &UpdateManagerOpaque, - to_download: &ffi::UpdateInfoDto, - cb: &ffi::DownloadCallbackManager, -) -> Result<()> { - let info = updateinfo_to_core(&to_download); - let (progress_sender, progress_receiver) = std::sync::mpsc::channel::(); - let (completion_sender, completion_receiver) = std::sync::mpsc::channel::>(); - - // Move the download_updates call into a new thread - let manager = manager.clone(); - std::thread::spawn(move || { - let result = manager.obj.download_updates(&info, Some(progress_sender)); - let _ = completion_sender.send(result); - }); - - // Process progress updates on the caller's thread - loop { - // Try to receive progress updates without blocking - match progress_receiver.try_recv() { - Ok(progress) => { - cb.download_progress(progress); - } - _ => { - // No progress updates available, sleep for a short time to avoid busy-waiting - std::thread::sleep(std::time::Duration::from_millis(50)); - } - } - - // Check if download is complete - match completion_receiver.try_recv() { - Ok(result) => { - // Download is complete, return the result (propagating any errors) - result?; - return Ok(()); - } - Err(std::sync::mpsc::TryRecvError::Empty) => { - // Download is still in progress, continue processing progress updates - } - Err(std::sync::mpsc::TryRecvError::Disconnected) => { - bail!("Download thread disconnected unexpectedly without returning a result"); - } - } - } -} - -fn bridge_wait_exit_then_apply_update( - manager: &UpdateManagerOpaque, - to_apply: &ffi::VelopackAssetDto, - silent: bool, - restart: bool, - restart_args: &Vec, -) -> Result<()> { - let asset = velopackasset_to_core(&to_apply); - manager.obj.wait_exit_then_apply_updates(&asset, silent, restart, restart_args)?; - Ok(()) -} - -fn bridge_appbuilder_run( - cb: &ffi::HookCallbackManager, - custom_args: &ffi::StringArrayOption, - locator: &ffi::VelopackLocatorConfigDtoOption, - auto_apply: bool, -) { - let mut app = VelopackApp::build() - .set_auto_apply_on_startup(auto_apply) - .on_first_run(|v| cb.firstrun_hook(v.to_string())) - .on_restarted(|v| cb.restarted_hook(v.to_string())); - - #[cfg(windows)] - { - app = app - .on_after_install_fast_callback(|v| cb.install_hook(v.to_string())) - .on_after_update_fast_callback(|v| cb.update_hook(v.to_string())) - .on_before_update_fast_callback(|v| cb.obsolete_hook(v.to_string())) - .on_before_uninstall_fast_callback(|v| cb.uninstall_hook(v.to_string())); - } - - if locator.has_data { - let locator = velopacklocatorconfig_to_core(&locator.data); - app = app.set_locator(locator); - } - - if custom_args.has_data { - app = app.set_args(custom_args.data.clone()); - } - - app.run(); -} - -struct LoggerImpl {} - -static LOGGER: LoggerImpl = LoggerImpl {}; - -impl Log for LoggerImpl { - fn enabled(&self, metadata: &Metadata) -> bool { - metadata.level() <= log::max_level() - } - - fn log(&self, record: &Record) { - if !self.enabled(record.metadata()) { - return; - } - - let text = format!("{}", record.args()); - - let level = match record.level() { - Level::Error => "error", - Level::Warn => "warn", - Level::Info => "info", - Level::Debug => "debug", - Level::Trace => "trace", - } - .to_string(); - - if let Some(cb) = get_logger() { - if let Some(cb) = unsafe { cb.as_mut() } { - cb.log(level, text); - } - } - } - - fn flush(&self) {} -} - -lazy_static::lazy_static! { - static ref LOGGER_CB: AtomicUsize = AtomicUsize::new(0); -} - -fn store_logger(ptr: *mut ffi::LoggerCallbackManager) { - LOGGER_CB.store(ptr as usize, Ordering::SeqCst); -} - -fn get_logger() -> Option<*mut ffi::LoggerCallbackManager> { - let ptr = LOGGER_CB.load(Ordering::SeqCst); - if ptr == 0 { - None - } else { - Some(ptr as *mut ffi::LoggerCallbackManager) - } -} - -unsafe fn bridge_set_logger_callback(cb: *mut ffi::LoggerCallbackManager) { - let _ = log::set_logger(&LOGGER); - log::set_max_level(log::LevelFilter::Trace); - store_logger(cb); -} diff --git a/src/lib-cpp/src/map.rs b/src/lib-cpp/src/map.rs deleted file mode 100644 index 7ba86f36..00000000 --- a/src/lib-cpp/src/map.rs +++ /dev/null @@ -1,160 +0,0 @@ -use std::path::PathBuf; -use velopack::locator::VelopackLocatorConfig; -use velopack::{UpdateInfo, UpdateOptions, VelopackAsset}; -use crate::ffi::*; - -fn pathbuf_to_core(dto: &String) -> PathBuf { - PathBuf::from(dto) -} - -fn pathbuf_to_bridge(dto: &PathBuf) -> String { - dto.to_string_lossy().to_string() -} - -fn string_to_core(dto: &String) -> String { - dto.clone() -} - -fn string_to_bridge(dto: &String) -> String { - dto.clone() -} - -fn bool_to_core(dto: &bool) -> bool { - *dto -} - -fn bool_to_bridge(dto: &bool) -> bool { - *dto -} - -fn u64_to_core(dto: &u64) -> u64 { - *dto -} - -fn u64_to_bridge(dto: &u64) -> u64 { - *dto -} - -// !! AUTO-GENERATED-START CORE_MAPPING -pub fn velopacklocatorconfig_to_core(dto: &VelopackLocatorConfigDto) -> VelopackLocatorConfig { - VelopackLocatorConfig { - RootAppDir: pathbuf_to_core(&dto.RootAppDir), - UpdateExePath: pathbuf_to_core(&dto.UpdateExePath), - PackagesDir: pathbuf_to_core(&dto.PackagesDir), - ManifestPath: pathbuf_to_core(&dto.ManifestPath), - CurrentBinaryDir: pathbuf_to_core(&dto.CurrentBinaryDir), - IsPortable: bool_to_core(&dto.IsPortable), - } -} - -pub fn velopacklocatorconfig_to_bridge(dto: &VelopackLocatorConfig) -> VelopackLocatorConfigDto { - VelopackLocatorConfigDto { - RootAppDir: pathbuf_to_bridge(&dto.RootAppDir), - UpdateExePath: pathbuf_to_bridge(&dto.UpdateExePath), - PackagesDir: pathbuf_to_bridge(&dto.PackagesDir), - ManifestPath: pathbuf_to_bridge(&dto.ManifestPath), - CurrentBinaryDir: pathbuf_to_bridge(&dto.CurrentBinaryDir), - IsPortable: bool_to_bridge(&dto.IsPortable), - } -} - -pub fn velopacklocatorconfig_to_core_option(dto: &VelopackLocatorConfigDtoOption) -> Option { - if dto.has_data { Some(velopacklocatorconfig_to_core(&dto.data)) } else { None } -} - -pub fn velopacklocatorconfig_to_bridge_option(dto: &Option) -> VelopackLocatorConfigDtoOption { - match dto { - Some(dto) => VelopackLocatorConfigDtoOption { data: velopacklocatorconfig_to_bridge(dto), has_data: true }, - None => VelopackLocatorConfigDtoOption { data: Default::default(), has_data: false }, - } -} - -pub fn velopackasset_to_core(dto: &VelopackAssetDto) -> VelopackAsset { - VelopackAsset { - PackageId: string_to_core(&dto.PackageId), - Version: string_to_core(&dto.Version), - Type: string_to_core(&dto.Type), - FileName: string_to_core(&dto.FileName), - SHA1: string_to_core(&dto.SHA1), - SHA256: string_to_core(&dto.SHA256), - Size: u64_to_core(&dto.Size), - NotesMarkdown: string_to_core(&dto.NotesMarkdown), - NotesHtml: string_to_core(&dto.NotesHtml), - } -} - -pub fn velopackasset_to_bridge(dto: &VelopackAsset) -> VelopackAssetDto { - VelopackAssetDto { - PackageId: string_to_bridge(&dto.PackageId), - Version: string_to_bridge(&dto.Version), - Type: string_to_bridge(&dto.Type), - FileName: string_to_bridge(&dto.FileName), - SHA1: string_to_bridge(&dto.SHA1), - SHA256: string_to_bridge(&dto.SHA256), - Size: u64_to_bridge(&dto.Size), - NotesMarkdown: string_to_bridge(&dto.NotesMarkdown), - NotesHtml: string_to_bridge(&dto.NotesHtml), - } -} - -pub fn velopackasset_to_core_option(dto: &VelopackAssetDtoOption) -> Option { - if dto.has_data { Some(velopackasset_to_core(&dto.data)) } else { None } -} - -pub fn velopackasset_to_bridge_option(dto: &Option) -> VelopackAssetDtoOption { - match dto { - Some(dto) => VelopackAssetDtoOption { data: velopackasset_to_bridge(dto), has_data: true }, - None => VelopackAssetDtoOption { data: Default::default(), has_data: false }, - } -} - -pub fn updateinfo_to_core(dto: &UpdateInfoDto) -> UpdateInfo { - UpdateInfo { - TargetFullRelease: velopackasset_to_core(&dto.TargetFullRelease), - IsDowngrade: bool_to_core(&dto.IsDowngrade), - } -} - -pub fn updateinfo_to_bridge(dto: &UpdateInfo) -> UpdateInfoDto { - UpdateInfoDto { - TargetFullRelease: velopackasset_to_bridge(&dto.TargetFullRelease), - IsDowngrade: bool_to_bridge(&dto.IsDowngrade), - } -} - -pub fn updateinfo_to_core_option(dto: &UpdateInfoDtoOption) -> Option { - if dto.has_data { Some(updateinfo_to_core(&dto.data)) } else { None } -} - -pub fn updateinfo_to_bridge_option(dto: &Option) -> UpdateInfoDtoOption { - match dto { - Some(dto) => UpdateInfoDtoOption { data: updateinfo_to_bridge(dto), has_data: true }, - None => UpdateInfoDtoOption { data: Default::default(), has_data: false }, - } -} - -pub fn updateoptions_to_core(dto: &UpdateOptionsDto) -> UpdateOptions { - UpdateOptions { - AllowVersionDowngrade: bool_to_core(&dto.AllowVersionDowngrade), - ExplicitChannel: if dto.ExplicitChannel.has_data { Some(string_to_core(&dto.ExplicitChannel.data)) } else { None }, - } -} - -pub fn updateoptions_to_bridge(dto: &UpdateOptions) -> UpdateOptionsDto { - UpdateOptionsDto { - AllowVersionDowngrade: bool_to_bridge(&dto.AllowVersionDowngrade), - ExplicitChannel: StringOption { data: string_to_bridge(&dto.ExplicitChannel.clone().unwrap_or_default()), has_data: dto.ExplicitChannel.is_some() }, - } -} - -pub fn updateoptions_to_core_option(dto: &UpdateOptionsDtoOption) -> Option { - if dto.has_data { Some(updateoptions_to_core(&dto.data)) } else { None } -} - -pub fn updateoptions_to_bridge_option(dto: &Option) -> UpdateOptionsDtoOption { - match dto { - Some(dto) => UpdateOptionsDtoOption { data: updateoptions_to_bridge(dto), has_data: true }, - None => UpdateOptionsDtoOption { data: Default::default(), has_data: false }, - } -} -// !! AUTO-GENERATED-END CORE_MAPPING \ No newline at end of file diff --git a/src/lib-cpp/src/statics.rs b/src/lib-cpp/src/statics.rs new file mode 100644 index 00000000..23ee8bc3 --- /dev/null +++ b/src/lib-cpp/src/statics.rs @@ -0,0 +1,119 @@ +use anyhow::Result; +use log::{Level, Log, Metadata, Record}; +use std::ffi::{c_void, CString}; +use std::sync::{Mutex, RwLock}; +use velopack::locator::VelopackLocatorConfig; + +use crate::types::*; + +#[derive(Debug, Default, Clone)] +pub struct AppOptions { + pub install_hook: Option, + pub update_hook: Option, + pub obsolete_hook: Option, + pub uninstall_hook: Option, + pub firstrun_hook: Option, + pub restarted_hook: Option, + pub auto_apply: Option, + pub args: Option>, + pub locator: Option, +} + +lazy_static::lazy_static! { + static ref LAST_ERROR: RwLock = RwLock::new(String::new()); + static ref LOG_CALLBACK: Mutex> = Mutex::new(None); + pub static ref VELOPACK_APP: RwLock = RwLock::new(Default::default()); +} + +pub fn update_app_options(op: F) +where + F: FnOnce(&mut AppOptions), +{ + let mut app_options = VELOPACK_APP.write().unwrap(); + op(&mut app_options); +} + +pub fn clear_last_error() { + let mut last_error = LAST_ERROR.write().unwrap(); + last_error.clear(); +} + +pub fn get_last_error() -> String { + let last_error = LAST_ERROR.read().unwrap(); + last_error.clone() +} + +pub fn set_last_error(message: &str) { + let mut last_error = LAST_ERROR.write().unwrap(); + *last_error = message.to_string(); +} + +pub fn wrap_error(op: F) -> bool +where + F: FnOnce() -> Result<()>, +{ + let mut last_error = LAST_ERROR.write().unwrap(); + last_error.clear(); + + match op() { + Ok(_) => true, + Err(e) => { + *last_error = format!("{:?}", e); + false + } + } +} + +pub fn set_log_callback(callback: vpkc_log_callback_t, user_data: *mut c_void) { + // Initialize the logger if it hasn't been set yet + let _ = log::set_logger(&LOGGER); + log::set_max_level(log::LevelFilter::Trace); + + let mut log_callback = LOG_CALLBACK.lock().unwrap(); + *log_callback = Some((callback, user_data as usize)); +} + +pub fn clear_log_callback() { + let mut log_callback = LOG_CALLBACK.lock().unwrap(); + *log_callback = None; +} + +pub fn log_message(level: &str, message: &str) { + let log_callback = LOG_CALLBACK.lock().unwrap(); + if let Some((callback, user_data)) = *log_callback { + let c_level = CString::new(level).unwrap(); + let c_message = CString::new(message).unwrap(); + callback(user_data as *mut c_void, c_level.as_ptr(), c_message.as_ptr()); + } +} + +struct LoggerImpl {} + +static LOGGER: LoggerImpl = LoggerImpl {}; + +impl Log for LoggerImpl { + fn enabled(&self, metadata: &Metadata) -> bool { + metadata.level() <= log::max_level() + } + + fn log(&self, record: &Record) { + if !self.enabled(record.metadata()) { + return; + } + + let text = format!("{}", record.args()); + + let level = match record.level() { + Level::Error => "error", + Level::Warn => "warn", + Level::Info => "info", + Level::Debug => "debug", + Level::Trace => "trace", + } + .to_string(); + + log_message(&level, &text); + } + + fn flush(&self) {} +} diff --git a/src/lib-cpp/src/types.rs b/src/lib-cpp/src/types.rs new file mode 100644 index 00000000..5849d973 --- /dev/null +++ b/src/lib-cpp/src/types.rs @@ -0,0 +1,274 @@ +use std::ffi::{c_char, c_void, CStr, CString}; +use std::path::PathBuf; +use velopack::{locator::VelopackLocatorConfig, UpdateInfo, UpdateOptions, VelopackAsset}; + +pub fn c_to_string_opt(psz: *const c_char) -> Option { + if psz.is_null() { + return None; + } + let cstr = unsafe { CStr::from_ptr(psz) }; + Some(String::from_utf8_lossy(cstr.to_bytes()).to_string()) +} + +pub fn c_to_string(psz: *const c_char) -> String { + c_to_string_opt(psz).unwrap_or_default() +} + +pub fn c_to_pathbuf(psz: *const c_char) -> PathBuf { + PathBuf::from(c_to_string(psz)) +} + +pub fn string_to_cstr(s: &str) -> *mut c_char { + let cstr = CString::new(s).unwrap(); + cstr.into_raw() +} + +pub fn free_cstr(psz: *mut c_char) { + if !psz.is_null() { + let _ = unsafe { CString::from_raw(psz) }; + } +} + +pub fn allocate_string(s: String, psz: *mut *mut c_char) { + if psz.is_null() { + return; + } + unsafe { *psz = string_to_cstr(&s) }; +} + +pub fn allocate_string_opt(s: Option, psz: *mut *mut c_char) { + if let Some(s) = s { + allocate_string(s, psz); + } +} + +pub unsafe fn free_string(psz: *mut *mut c_char) { + if !psz.is_null() { + free_cstr(*psz); + } +} + +pub fn allocate_pathbuf(p: PathBuf, psz: *mut *mut c_char) { + allocate_string(p.to_string_lossy().to_string(), psz); +} + +pub unsafe fn free_pathbuf(psz: *mut *mut c_char) { + free_string(psz); +} + +pub fn c_to_string_array_opt(p_args: *mut *mut c_char, c_args: usize) -> Option> { + if p_args.is_null() || c_args == 0 { + return None; + } + + let mut args = Vec::with_capacity(c_args); + for i in 0..c_args { + if let Some(arg) = c_to_string_opt(unsafe { *p_args.add(i) }) { + args.push(arg); + } + } + + Some(args) +} + +pub fn return_cstr(psz: *mut c_char, c: usize, s: &str) -> usize { + if !psz.is_null() && c > 0 { + let cstr = CString::new(s).unwrap(); + let bytes = cstr.as_bytes_with_nul(); + let len = bytes.len().min(c); + unsafe { + std::ptr::copy_nonoverlapping(bytes.as_ptr(), psz as *mut u8, len); + *psz.add(len) = 0; + } + } + + return s.len(); +} + +pub type vpkc_progress_callback_t = extern "C" fn(p_user_data: *mut c_void, progress: usize); + +pub type vpkc_log_callback_t = extern "C" fn(p_user_data: *mut c_void, psz_level: *const c_char, psz_message: *const c_char); + +pub type vpkc_hook_callback_t = extern "C" fn(p_user_data: *mut c_void, psz_app_version: *const c_char); + +// !! AUTO-GENERATED-START RUST_TYPES +#[rustfmt::skip] +#[repr(C)] +pub struct vpkc_locator_config_t { + pub RootAppDir: *mut c_char, + pub UpdateExePath: *mut c_char, + pub PackagesDir: *mut c_char, + pub ManifestPath: *mut c_char, + pub CurrentBinaryDir: *mut c_char, + pub IsPortable: bool, +} + +#[rustfmt::skip] +pub fn c_to_velopacklocatorconfig(obj: &vpkc_locator_config_t) -> VelopackLocatorConfig { + VelopackLocatorConfig { + RootAppDir: c_to_pathbuf(obj.RootAppDir), + UpdateExePath: c_to_pathbuf(obj.UpdateExePath), + PackagesDir: c_to_pathbuf(obj.PackagesDir), + ManifestPath: c_to_pathbuf(obj.ManifestPath), + CurrentBinaryDir: c_to_pathbuf(obj.CurrentBinaryDir), + IsPortable: obj.IsPortable, + } +} + +#[rustfmt::skip] +pub fn c_to_velopacklocatorconfig_opt(obj: *mut vpkc_locator_config_t) -> Option { + if obj.is_null() { return None; } + Some(c_to_velopacklocatorconfig(unsafe { &*obj })) +} + +#[rustfmt::skip] +pub unsafe fn allocate_velopacklocatorconfig(dto: VelopackLocatorConfig, obj: *mut vpkc_locator_config_t) { + if obj.is_null() { return; } + allocate_pathbuf(dto.RootAppDir, &mut (*obj).RootAppDir); + allocate_pathbuf(dto.UpdateExePath, &mut (*obj).UpdateExePath); + allocate_pathbuf(dto.PackagesDir, &mut (*obj).PackagesDir); + allocate_pathbuf(dto.ManifestPath, &mut (*obj).ManifestPath); + allocate_pathbuf(dto.CurrentBinaryDir, &mut (*obj).CurrentBinaryDir); + (*obj).IsPortable = dto.IsPortable; +} + +#[rustfmt::skip] +pub unsafe fn free_velopacklocatorconfig(obj: *mut vpkc_locator_config_t) { + if obj.is_null() { return; } + free_pathbuf(&mut (*obj).RootAppDir); + free_pathbuf(&mut (*obj).UpdateExePath); + free_pathbuf(&mut (*obj).PackagesDir); + free_pathbuf(&mut (*obj).ManifestPath); + free_pathbuf(&mut (*obj).CurrentBinaryDir); +} + +#[rustfmt::skip] +#[repr(C)] +pub struct vpkc_asset_t { + pub PackageId: *mut c_char, + pub Version: *mut c_char, + pub Type: *mut c_char, + pub FileName: *mut c_char, + pub SHA1: *mut c_char, + pub SHA256: *mut c_char, + pub Size: u64, + pub NotesMarkdown: *mut c_char, + pub NotesHtml: *mut c_char, +} + +#[rustfmt::skip] +pub fn c_to_velopackasset(obj: &vpkc_asset_t) -> VelopackAsset { + VelopackAsset { + PackageId: c_to_string(obj.PackageId), + Version: c_to_string(obj.Version), + Type: c_to_string(obj.Type), + FileName: c_to_string(obj.FileName), + SHA1: c_to_string(obj.SHA1), + SHA256: c_to_string(obj.SHA256), + Size: obj.Size, + NotesMarkdown: c_to_string(obj.NotesMarkdown), + NotesHtml: c_to_string(obj.NotesHtml), + } +} + +#[rustfmt::skip] +pub fn c_to_velopackasset_opt(obj: *mut vpkc_asset_t) -> Option { + if obj.is_null() { return None; } + Some(c_to_velopackasset(unsafe { &*obj })) +} + +#[rustfmt::skip] +pub unsafe fn allocate_velopackasset(dto: VelopackAsset, obj: *mut vpkc_asset_t) { + if obj.is_null() { return; } + allocate_string(dto.PackageId, &mut (*obj).PackageId); + allocate_string(dto.Version, &mut (*obj).Version); + allocate_string(dto.Type, &mut (*obj).Type); + allocate_string(dto.FileName, &mut (*obj).FileName); + allocate_string(dto.SHA1, &mut (*obj).SHA1); + allocate_string(dto.SHA256, &mut (*obj).SHA256); + (*obj).Size = dto.Size; + allocate_string(dto.NotesMarkdown, &mut (*obj).NotesMarkdown); + allocate_string(dto.NotesHtml, &mut (*obj).NotesHtml); +} + +#[rustfmt::skip] +pub unsafe fn free_velopackasset(obj: *mut vpkc_asset_t) { + if obj.is_null() { return; } + free_string(&mut (*obj).PackageId); + free_string(&mut (*obj).Version); + free_string(&mut (*obj).Type); + free_string(&mut (*obj).FileName); + free_string(&mut (*obj).SHA1); + free_string(&mut (*obj).SHA256); + free_string(&mut (*obj).NotesMarkdown); + free_string(&mut (*obj).NotesHtml); +} + +#[rustfmt::skip] +#[repr(C)] +pub struct vpkc_update_info_t { + pub TargetFullRelease: vpkc_asset_t, + pub IsDowngrade: bool, +} + +#[rustfmt::skip] +pub fn c_to_updateinfo(obj: &vpkc_update_info_t) -> UpdateInfo { + UpdateInfo { + TargetFullRelease: c_to_velopackasset(&obj.TargetFullRelease), + IsDowngrade: obj.IsDowngrade, + } +} + +#[rustfmt::skip] +pub fn c_to_updateinfo_opt(obj: *mut vpkc_update_info_t) -> Option { + if obj.is_null() { return None; } + Some(c_to_updateinfo(unsafe { &*obj })) +} + +#[rustfmt::skip] +pub unsafe fn allocate_updateinfo(dto: UpdateInfo, obj: *mut vpkc_update_info_t) { + if obj.is_null() { return; } + allocate_velopackasset(dto.TargetFullRelease, &mut (*obj).TargetFullRelease); + (*obj).IsDowngrade = dto.IsDowngrade; +} + +#[rustfmt::skip] +pub unsafe fn free_updateinfo(obj: *mut vpkc_update_info_t) { + if obj.is_null() { return; } + free_velopackasset(&mut (*obj).TargetFullRelease); +} + +#[rustfmt::skip] +#[repr(C)] +pub struct vpkc_update_options_t { + pub AllowVersionDowngrade: bool, + pub ExplicitChannel: *mut c_char, +} + +#[rustfmt::skip] +pub fn c_to_updateoptions(obj: &vpkc_update_options_t) -> UpdateOptions { + UpdateOptions { + AllowVersionDowngrade: obj.AllowVersionDowngrade, + ExplicitChannel: c_to_string_opt(obj.ExplicitChannel), + } +} + +#[rustfmt::skip] +pub fn c_to_updateoptions_opt(obj: *mut vpkc_update_options_t) -> Option { + if obj.is_null() { return None; } + Some(c_to_updateoptions(unsafe { &*obj })) +} + +#[rustfmt::skip] +pub unsafe fn allocate_updateoptions(dto: UpdateOptions, obj: *mut vpkc_update_options_t) { + if obj.is_null() { return; } + (*obj).AllowVersionDowngrade = dto.AllowVersionDowngrade; + allocate_string_opt(dto.ExplicitChannel, &mut (*obj).ExplicitChannel); +} + +#[rustfmt::skip] +pub unsafe fn free_updateoptions(obj: *mut vpkc_update_options_t) { + if obj.is_null() { return; } + free_string(&mut (*obj).ExplicitChannel); +} +// !! AUTO-GENERATED-END RUST_TYPES diff --git a/src/lib-cpp/type-generator/Program.cs b/src/lib-cpp/type-generator/Program.cs index 5771c0e4..96ce8b53 100644 --- a/src/lib-cpp/type-generator/Program.cs +++ b/src/lib-cpp/type-generator/Program.cs @@ -47,51 +47,59 @@ if (desiredStructs.Length != availableStructs.Count) { } // rust bridge code -string rustCppLib = Path.Combine(libcppDir, "src", "lib.rs"); -string rustCppMap = Path.Combine(libcppDir, "src", "map.rs"); +// string rustCppLib = Path.Combine(libcppDir, "src", "lib.rs"); +string rustTypes = Path.Combine(libcppDir, "src", "types.rs"); +//string rustCppMap = Path.Combine(libcppDir, "src", "map.rs"); string rustCppInclude = Path.Combine(libcppDir, "include", "Velopack.h"); -string rustBridgeC = Path.Combine(libcppDir, "src", "bridge.cc"); +//string rustBridgeC = Path.Combine(libcppDir, "src", "bridge.cc"); -Console.WriteLine("Generating bridge dtos"); -var sbBridgeDto = new IndentStringBuilder(); -foreach(var rs in availableStructs) { - Templates.WriteBridgeDto(desiredStructs, sbBridgeDto, rs); -} +//Console.WriteLine("Generating bridge dtos"); +//var sbBridgeDto = new IndentStringBuilder(); +//foreach(var rs in availableStructs) { +// Templates.WriteBridgeDto(desiredStructs, sbBridgeDto, rs); +//} -Console.WriteLine("Generating bridge to core mappings"); -var sbBridgeMapping = new IndentStringBuilder(); -foreach(var rs in availableStructs) { - Templates.WriteBridgeToCoreMapping(desiredStructs, sbBridgeMapping, rs); -} +//Console.WriteLine("Generating bridge to core mappings"); +//var sbBridgeMapping = new IndentStringBuilder(); +//foreach(var rs in availableStructs) { +// Templates.WriteBridgeToCoreMapping(desiredStructs, sbBridgeMapping, rs); +//} Console.WriteLine("Generating C types"); var cTypes = new IndentStringBuilder(); cTypes.AppendLine(); -foreach(var rs in availableStructs) { +foreach (var rs in availableStructs) { Templates.WriteBasicC(basic_libc_names, cTypes, rs); } Console.WriteLine("Generating C++ types"); var cppTypes = new IndentStringBuilder(); cppTypes.AppendLine(); -foreach(var rs in availableStructs) { +foreach (var rs in availableStructs) { Templates.WriteCPlusPlus(basic_libc_names, cppTypes, rs); } foreach (var rs in availableStructs) { Templates.WriteC2CPPMapping(basic_libc_names, cppTypes, rs); } -Console.WriteLine("Generating C to bridge mappings"); -var cToBridgeMapping = new IndentStringBuilder(); -foreach(var rs in availableStructs) { - Templates.WriteCBridgeMapping(basic_libc_names, cToBridgeMapping, rs); +Console.WriteLine("Generating Rust-C types"); +var rustCTypes = new IndentStringBuilder(); +foreach (var rs in availableStructs) { + Templates.WriteRustCRepr(basic_libc_names, rustCTypes, rs); } +//Console.WriteLine("Generating C to bridge mappings"); +//var cToBridgeMapping = new IndentStringBuilder(); +//foreach (var rs in availableStructs) { +// Templates.WriteCBridgeMapping(basic_libc_names, cToBridgeMapping, rs); +//} + Console.WriteLine("Writing all to file"); -Util.ReplaceTextInFile(rustCppLib, "BRIDGE_DTOS", sbBridgeDto.ToString()); -Util.ReplaceTextInFile(rustCppMap, "CORE_MAPPING", sbBridgeMapping.ToString()); +//Util.ReplaceTextInFile(rustCppLib, "BRIDGE_DTOS", sbBridgeDto.ToString()); +//Util.ReplaceTextInFile(rustCppMap, "CORE_MAPPING", sbBridgeMapping.ToString()); +Util.ReplaceTextInFile(rustTypes, "RUST_TYPES", rustCTypes.ToString()); Util.ReplaceTextInFile(rustCppInclude, "C_TYPES", cTypes.ToString()); Util.ReplaceTextInFile(rustCppInclude, "CPP_TYPES", cppTypes.ToString()); -Util.ReplaceTextInFile(rustBridgeC, "BRIDGE_MAPPING", cToBridgeMapping.ToString()); +//Util.ReplaceTextInFile(rustBridgeC, "BRIDGE_MAPPING", cToBridgeMapping.ToString()); return 0; \ No newline at end of file diff --git a/src/lib-cpp/type-generator/Templates.cs b/src/lib-cpp/type-generator/Templates.cs index 148b2da9..0e6e60d6 100644 --- a/src/lib-cpp/type-generator/Templates.cs +++ b/src/lib-cpp/type-generator/Templates.cs @@ -25,6 +25,103 @@ } } + private static string GetBasicCTypeInRust(Dictionary nameMap, string rustType) + { + switch (rustType) { + case "PathBuf": + case "String": + return "*mut c_char"; + case "bool": + return "bool"; + case "i32": + return "i32"; + case "i64": + return "i64"; + case "u32": + return "u32"; + case "u64": + return "u64"; + default: + if (nameMap.TryGetValue(rustType, out var type)) { + return type; + } + + throw new NotSupportedException("Unsupported type for rust-c: " + rustType); + } + } + + public static void WriteRustCRepr(Dictionary nameMap, IndentStringBuilder sb, RustStruct rs) + { + var cName = nameMap[rs.Name]; + sb.AppendLine("#[rustfmt::skip]"); + sb.AppendLine($"#[repr(C)]"); + sb.AppendLine($"pub struct {cName} {{"); + using (sb.Indent()) { + foreach (var field in rs.Fields) { + sb.AppendLine($"pub {field.Name}: {GetBasicCTypeInRust(nameMap, field.Type)},"); + } + } + + sb.AppendLine("}"); + sb.AppendLine(); + + sb.AppendLine("#[rustfmt::skip]"); + sb.AppendLine($"pub fn c_to_{rs.Name.ToLower()}(obj: &{cName}) -> {rs.Name} {{"); + using (sb.Indent()) { + // sb.AppendLine($"let obj = unsafe {{ &*obj }};"); + sb.AppendLine($"{rs.Name} {{"); + using (sb.Indent()) { + foreach (var field in rs.Fields) { + if (field.Optional || field.Type == "PathBuf" || field.Type == "String" || nameMap.ContainsKey(field.Type)) { + sb.AppendLine($"{field.Name}: c_to_{field.Type.ToLower()}{(field.Optional ? "_opt": "")}({(nameMap.ContainsKey(field.Type) ? "&" : "")}obj.{field.Name}),"); + } else { + sb.AppendLine($"{field.Name}: obj.{field.Name},"); + } + } + } + sb.AppendLine("}"); + } + sb.AppendLine("}"); + sb.AppendLine(); + + sb.AppendLine("#[rustfmt::skip]"); + sb.AppendLine($"pub fn c_to_{rs.Name.ToLower()}_opt(obj: *mut {cName}) -> Option<{rs.Name}> {{"); + using (sb.Indent()) { + sb.AppendLine("if obj.is_null() { return None; }"); + sb.AppendLine($"Some(c_to_{rs.Name.ToLower()}(unsafe {{ &*obj }}))"); + } + sb.AppendLine("}"); + sb.AppendLine(); + + sb.AppendLine("#[rustfmt::skip]"); + sb.AppendLine($"pub unsafe fn allocate_{rs.Name.ToLower()}(dto: {rs.Name}, obj: *mut {cName}) {{"); + using (sb.Indent()) { + sb.AppendLine("if obj.is_null() { return; }"); + foreach (var field in rs.Fields) { + if (field.Optional || field.Type == "PathBuf" || field.Type == "String" || nameMap.ContainsKey(field.Type)) { + sb.AppendLine($"allocate_{field.Type.ToLower()}{(field.Optional ? "_opt": "")}(dto.{field.Name}, &mut (*obj).{field.Name});"); + } else { + sb.AppendLine($"(*obj).{field.Name} = dto.{field.Name};"); + } + } + } + sb.AppendLine("}"); + sb.AppendLine(); + + sb.AppendLine("#[rustfmt::skip]"); + sb.AppendLine($"pub unsafe fn free_{rs.Name.ToLower()}(obj: *mut {cName}) {{"); + using (sb.Indent()) { + sb.AppendLine("if obj.is_null() { return; }"); + foreach (var field in rs.Fields) { + if (field.Optional || field.Type == "PathBuf" || field.Type == "String" || nameMap.ContainsKey(field.Type)) { + sb.AppendLine($"free_{field.Type.ToLower()}(&mut (*obj).{field.Name});"); + } + } + } + sb.AppendLine("}"); + sb.AppendLine(); + } + private static string GetCPlusPlusType(string[] coreTypes, string rustType, bool optional) { string type = rustType switch { @@ -100,6 +197,7 @@ : $"pDto->{field.Name} = bridgeDto.{field.Name};"); } } + sb.AppendLine($"}}"); sb.AppendLine(); @@ -115,6 +213,7 @@ } } } + sb.AppendLine($"}}"); sb.AppendLine(); } diff --git a/src/lib-rust/src/app.rs b/src/lib-rust/src/app.rs index 61d433b8..4db1e565 100644 --- a/src/lib-rust/src/app.rs +++ b/src/lib-rust/src/app.rs @@ -3,7 +3,7 @@ use std::env; use std::process::exit; use crate::{ - locator::{VelopackLocatorConfig}, + locator::VelopackLocatorConfig, constants::*, manager, sources,