mirror of
https://github.com/velopack/velopack.git
synced 2025-10-25 15:19:22 +00:00
Remove cxx bridge & export functions from rust
This commit is contained in:
65
Cargo.lock
generated
65
Cargo.lock
generated
@@ -422,16 +422,6 @@ dependencies = [
|
|||||||
"objc",
|
"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]]
|
[[package]]
|
||||||
name = "color_quant"
|
name = "color_quant"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
@@ -536,50 +526,6 @@ dependencies = [
|
|||||||
"cfg-if 1.0.0",
|
"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]]
|
[[package]]
|
||||||
name = "deranged"
|
name = "deranged"
|
||||||
version = "0.3.11"
|
version = "0.3.11"
|
||||||
@@ -1238,15 +1184,6 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "link-cplusplus"
|
|
||||||
version = "1.0.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9d240c6f7e1ba3a28b0249f774e6a9dd0175054b52dfbb61b16eb8505c3785c9"
|
|
||||||
dependencies = [
|
|
||||||
"cc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linux-raw-sys"
|
name = "linux-raw-sys"
|
||||||
version = "0.4.14"
|
version = "0.4.14"
|
||||||
@@ -2342,8 +2279,6 @@ name = "velopack_libc"
|
|||||||
version = "0.0.0-local"
|
version = "0.0.0-local"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"cxx",
|
|
||||||
"cxx-build",
|
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
"velopack",
|
"velopack",
|
||||||
|
|||||||
@@ -23,8 +23,6 @@ edition = "2021"
|
|||||||
rust-version = "1.75"
|
rust-version = "1.75"
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
cxx = "1.0"
|
|
||||||
cxx-build = "1.0"
|
|
||||||
velopack = { path = "src/lib-rust" }
|
velopack = { path = "src/lib-rust" }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
ureq = "2.10"
|
ureq = "2.10"
|
||||||
|
|||||||
@@ -18,11 +18,7 @@ path = "src/lib.rs"
|
|||||||
crate-type = ["cdylib"]
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cxx.workspace = true
|
|
||||||
velopack.workspace = true
|
velopack.workspace = true
|
||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
lazy_static.workspace = true
|
lazy_static.workspace = true
|
||||||
log.workspace = true
|
log.workspace = true
|
||||||
|
|
||||||
[build-dependencies]
|
|
||||||
cxx-build.workspace = true
|
|
||||||
@@ -1,19 +1,21 @@
|
|||||||
fn main() {
|
fn main() {
|
||||||
cxx_build::bridge("src/lib.rs")
|
// cc::Build::new()
|
||||||
.file("src/bridge.cc")
|
// .cpp(true)
|
||||||
.warnings_into_errors(true)
|
// .static_crt(true)
|
||||||
.flag_if_supported("/std:c++17")
|
// .file("src/bridge.cc")
|
||||||
.flag_if_supported("/EHsc") // exception unwind handling
|
// .warnings_into_errors(true)
|
||||||
.flag_if_supported("-Wno-unused-function") // allow unused functions
|
// .flag_if_supported("/std:c++17")
|
||||||
.define("VELOPACK_LIBC_EXPORTS", Some("1"))
|
// .flag_if_supported("/EHsc") // exception unwind handling
|
||||||
.std("c++17")
|
// .flag_if_supported("-Wno-unused-function") // allow unused functions
|
||||||
.compile("velopack_libc");
|
// .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=include/Velopack.h");
|
||||||
println!("cargo:rerun-if-changed=src/lib.rs");
|
// println!("cargo:rerun-if-changed=src/lib.rs");
|
||||||
println!("cargo:rerun-if-changed=src/bridge.hpp");
|
// println!("cargo:rerun-if-changed=src/bridge.hpp");
|
||||||
println!("cargo:rerun-if-changed=src/bridge.cc");
|
// println!("cargo:rerun-if-changed=src/bridge.cc");
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
// #[cfg(target_os = "windows")]
|
||||||
println!("cargo:rustc-link-arg=/WHOLEARCHIVE:velopack_libc.lib");
|
// println!("cargo:rustc-link-arg=/WHOLEARCHIVE:velopack_libc.lib");
|
||||||
}
|
}
|
||||||
@@ -20,39 +20,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#endif
|
#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
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#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 void (*vpkc_hook_callback_t)(void* pUserData, const char* pszAppVersion);
|
||||||
|
|
||||||
typedef enum vpkc_update_check_t {
|
typedef enum vpkc_update_check_t {
|
||||||
|
UPDATE_ERROR = -1,
|
||||||
UPDATE_AVAILABLE = 0,
|
UPDATE_AVAILABLE = 0,
|
||||||
NO_UPDATE_AVAILABLE = 1,
|
NO_UPDATE_AVAILABLE = 1,
|
||||||
UPDATE_ERROR = 2,
|
REMOTE_IS_EMPTY = 2,
|
||||||
} vpkc_update_check_t;
|
} vpkc_update_check_t;
|
||||||
|
|
||||||
// !! AUTO-GENERATED-START C_TYPES
|
// !! 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.
|
/// Creates a new vpkc_update_manager_t. Free with vpkc_free_update_manager.
|
||||||
/// \group UpdateManager
|
/// \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
|
/// \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
|
/// \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
|
/// \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
|
/// \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
|
/// \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
|
/// \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
|
/// \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
|
/// \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
|
/// \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
|
/// \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.
|
/// Should be run at the beginning of your application to handle Velopack events.
|
||||||
/// \group VelopackApp
|
/// \group VelopackApp
|
||||||
VPKC_EXPORT void VPKC_CALL vpkc_app_run(void* pUserData = 0);
|
void vpkc_app_run(void* pUserData = 0);
|
||||||
/// \group VelopackApp
|
/// \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
|
/// \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
|
/// \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
|
/// \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
|
/// \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
|
/// \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
|
/// \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
|
/// \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
|
/// \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.
|
/// 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.
|
/// 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"
|
#ifdef __cplusplus // end of extern "C"
|
||||||
}
|
}
|
||||||
@@ -594,6 +562,7 @@ public:
|
|||||||
throw_last_error();
|
throw_last_error();
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
case vpkc_update_check_t::NO_UPDATE_AVAILABLE:
|
case vpkc_update_check_t::NO_UPDATE_AVAILABLE:
|
||||||
|
case vpkc_update_check_t::REMOTE_IS_EMPTY:
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
case vpkc_update_check_t::UPDATE_AVAILABLE:
|
case vpkc_update_check_t::UPDATE_AVAILABLE:
|
||||||
UpdateInfo cpp_info = to_cpp(update);
|
UpdateInfo cpp_info = to_cpp(update);
|
||||||
|
|||||||
@@ -1,408 +1,408 @@
|
|||||||
// Uncomment to enable debug type checking
|
// // 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/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/include/Velopack.h", "../include/Velopack.h" )
|
||||||
// #pragma include_alias( "velopack_libc/src/bridge.hpp", "bridge.hpp" )
|
// // #pragma include_alias( "velopack_libc/src/bridge.hpp", "bridge.hpp" )
|
||||||
// #pragma include_alias( "rust/cxx.h", "../../../target/cxxbridge/rust/cxx.h" )
|
// // #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) {
|
// static inline std::string to_bridgestring(const char* psz) {
|
||||||
return psz == nullptr ? "" : psz;
|
// return psz == nullptr ? "" : psz;
|
||||||
}
|
// }
|
||||||
|
|
||||||
static inline char* to_cstring(const std::string& str) {
|
// static inline char* to_cstring(const std::string& str) {
|
||||||
return const_cast<char*>(str.c_str());
|
// return const_cast<char*>(str.c_str());
|
||||||
}
|
// }
|
||||||
|
|
||||||
static inline char* to_cstring_opt(const std::optional<std::string>& str) {
|
// static inline char* to_cstring_opt(const std::optional<std::string>& str) {
|
||||||
return str.has_value() ? to_cstring(str.value()) : nullptr;
|
// return str.has_value() ? to_cstring(str.value()) : nullptr;
|
||||||
}
|
// }
|
||||||
|
|
||||||
static inline StringOption to_bridgestring_opt(const char* psz) {
|
// static inline StringOption to_bridgestring_opt(const char* psz) {
|
||||||
StringOption opt;
|
// StringOption opt;
|
||||||
if (psz == nullptr) {
|
// if (psz == nullptr) {
|
||||||
opt.has_data = false;
|
// opt.has_data = false;
|
||||||
return opt;
|
// return opt;
|
||||||
}
|
// }
|
||||||
opt.has_data = true;
|
// opt.has_data = true;
|
||||||
opt.data = psz;
|
// opt.data = psz;
|
||||||
return opt;
|
// return opt;
|
||||||
}
|
// }
|
||||||
|
|
||||||
static inline void allocate_string(::rust::String& str, char** ppsz) {
|
// static inline void allocate_string(::rust::String& str, char** ppsz) {
|
||||||
#ifdef _WIN32
|
// #ifdef _WIN32
|
||||||
*ppsz = _strdup(str.c_str());
|
// *ppsz = _strdup(str.c_str());
|
||||||
#else
|
// #else
|
||||||
*ppsz = strdup(str.c_str());
|
// *ppsz = strdup(str.c_str());
|
||||||
#endif
|
// #endif
|
||||||
}
|
// }
|
||||||
|
|
||||||
static inline void allocate_string_opt(StringOption str, char** ppsz) {
|
// static inline void allocate_string_opt(StringOption str, char** ppsz) {
|
||||||
if (str.has_data) {
|
// if (str.has_data) {
|
||||||
allocate_string(str.data, ppsz);
|
// allocate_string(str.data, ppsz);
|
||||||
} else {
|
// } else {
|
||||||
*ppsz = nullptr;
|
// *ppsz = nullptr;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// !! AUTO-GENERATED-START BRIDGE_MAPPING
|
// // !! AUTO-GENERATED-START BRIDGE_MAPPING
|
||||||
static inline VelopackLocatorConfigDto to_bridge(vpkc_locator_config_t* pDto) {
|
// static inline VelopackLocatorConfigDto to_bridge(vpkc_locator_config_t* pDto) {
|
||||||
if (pDto == nullptr) { return {}; }
|
// if (pDto == nullptr) { return {}; }
|
||||||
return {
|
// return {
|
||||||
to_bridgestring(pDto->RootAppDir),
|
// to_bridgestring(pDto->RootAppDir),
|
||||||
to_bridgestring(pDto->UpdateExePath),
|
// to_bridgestring(pDto->UpdateExePath),
|
||||||
to_bridgestring(pDto->PackagesDir),
|
// to_bridgestring(pDto->PackagesDir),
|
||||||
to_bridgestring(pDto->ManifestPath),
|
// to_bridgestring(pDto->ManifestPath),
|
||||||
to_bridgestring(pDto->CurrentBinaryDir),
|
// to_bridgestring(pDto->CurrentBinaryDir),
|
||||||
pDto->IsPortable,
|
// pDto->IsPortable,
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
|
|
||||||
static inline VelopackLocatorConfigDtoOption to_bridge_opt(vpkc_locator_config_t* pDto) {
|
// static inline VelopackLocatorConfigDtoOption to_bridge_opt(vpkc_locator_config_t* pDto) {
|
||||||
VelopackLocatorConfigDtoOption opt;
|
// VelopackLocatorConfigDtoOption opt;
|
||||||
if (pDto == nullptr) {
|
// if (pDto == nullptr) {
|
||||||
opt.has_data = false;
|
// opt.has_data = false;
|
||||||
return opt;
|
// return opt;
|
||||||
}
|
// }
|
||||||
|
|
||||||
opt.has_data = true;
|
// opt.has_data = true;
|
||||||
opt.data = to_bridge(pDto);
|
// opt.data = to_bridge(pDto);
|
||||||
return opt;
|
// return opt;
|
||||||
}
|
// }
|
||||||
|
|
||||||
static inline void allocate_velopacklocatorconfig(VelopackLocatorConfigDto bridgeDto, vpkc_locator_config_t* pDto) {
|
// static inline void allocate_velopacklocatorconfig(VelopackLocatorConfigDto bridgeDto, vpkc_locator_config_t* pDto) {
|
||||||
if (pDto == nullptr) { return; }
|
// if (pDto == nullptr) { return; }
|
||||||
allocate_string(bridgeDto.RootAppDir, &pDto->RootAppDir);
|
// allocate_string(bridgeDto.RootAppDir, &pDto->RootAppDir);
|
||||||
allocate_string(bridgeDto.UpdateExePath, &pDto->UpdateExePath);
|
// allocate_string(bridgeDto.UpdateExePath, &pDto->UpdateExePath);
|
||||||
allocate_string(bridgeDto.PackagesDir, &pDto->PackagesDir);
|
// allocate_string(bridgeDto.PackagesDir, &pDto->PackagesDir);
|
||||||
allocate_string(bridgeDto.ManifestPath, &pDto->ManifestPath);
|
// allocate_string(bridgeDto.ManifestPath, &pDto->ManifestPath);
|
||||||
allocate_string(bridgeDto.CurrentBinaryDir, &pDto->CurrentBinaryDir);
|
// allocate_string(bridgeDto.CurrentBinaryDir, &pDto->CurrentBinaryDir);
|
||||||
pDto->IsPortable = bridgeDto.IsPortable;
|
// pDto->IsPortable = bridgeDto.IsPortable;
|
||||||
}
|
// }
|
||||||
|
|
||||||
static inline void free_velopacklocatorconfig(vpkc_locator_config_t* pDto) {
|
// static inline void free_velopacklocatorconfig(vpkc_locator_config_t* pDto) {
|
||||||
if (pDto == nullptr) { return; }
|
// if (pDto == nullptr) { return; }
|
||||||
free(pDto->RootAppDir);
|
// free(pDto->RootAppDir);
|
||||||
free(pDto->UpdateExePath);
|
// free(pDto->UpdateExePath);
|
||||||
free(pDto->PackagesDir);
|
// free(pDto->PackagesDir);
|
||||||
free(pDto->ManifestPath);
|
// free(pDto->ManifestPath);
|
||||||
free(pDto->CurrentBinaryDir);
|
// free(pDto->CurrentBinaryDir);
|
||||||
}
|
// }
|
||||||
|
|
||||||
static inline VelopackAssetDto to_bridge(vpkc_asset_t* pDto) {
|
// static inline VelopackAssetDto to_bridge(vpkc_asset_t* pDto) {
|
||||||
if (pDto == nullptr) { return {}; }
|
// if (pDto == nullptr) { return {}; }
|
||||||
return {
|
// return {
|
||||||
to_bridgestring(pDto->PackageId),
|
// to_bridgestring(pDto->PackageId),
|
||||||
to_bridgestring(pDto->Version),
|
// to_bridgestring(pDto->Version),
|
||||||
to_bridgestring(pDto->Type),
|
// to_bridgestring(pDto->Type),
|
||||||
to_bridgestring(pDto->FileName),
|
// to_bridgestring(pDto->FileName),
|
||||||
to_bridgestring(pDto->SHA1),
|
// to_bridgestring(pDto->SHA1),
|
||||||
to_bridgestring(pDto->SHA256),
|
// to_bridgestring(pDto->SHA256),
|
||||||
pDto->Size,
|
// pDto->Size,
|
||||||
to_bridgestring(pDto->NotesMarkdown),
|
// to_bridgestring(pDto->NotesMarkdown),
|
||||||
to_bridgestring(pDto->NotesHtml),
|
// to_bridgestring(pDto->NotesHtml),
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
|
|
||||||
static inline VelopackAssetDtoOption to_bridge_opt(vpkc_asset_t* pDto) {
|
// static inline VelopackAssetDtoOption to_bridge_opt(vpkc_asset_t* pDto) {
|
||||||
VelopackAssetDtoOption opt;
|
// VelopackAssetDtoOption opt;
|
||||||
if (pDto == nullptr) {
|
// if (pDto == nullptr) {
|
||||||
opt.has_data = false;
|
// opt.has_data = false;
|
||||||
return opt;
|
// return opt;
|
||||||
}
|
// }
|
||||||
|
|
||||||
opt.has_data = true;
|
// opt.has_data = true;
|
||||||
opt.data = to_bridge(pDto);
|
// opt.data = to_bridge(pDto);
|
||||||
return opt;
|
// return opt;
|
||||||
}
|
// }
|
||||||
|
|
||||||
static inline void allocate_velopackasset(VelopackAssetDto bridgeDto, vpkc_asset_t* pDto) {
|
// static inline void allocate_velopackasset(VelopackAssetDto bridgeDto, vpkc_asset_t* pDto) {
|
||||||
if (pDto == nullptr) { return; }
|
// if (pDto == nullptr) { return; }
|
||||||
allocate_string(bridgeDto.PackageId, &pDto->PackageId);
|
// allocate_string(bridgeDto.PackageId, &pDto->PackageId);
|
||||||
allocate_string(bridgeDto.Version, &pDto->Version);
|
// allocate_string(bridgeDto.Version, &pDto->Version);
|
||||||
allocate_string(bridgeDto.Type, &pDto->Type);
|
// allocate_string(bridgeDto.Type, &pDto->Type);
|
||||||
allocate_string(bridgeDto.FileName, &pDto->FileName);
|
// allocate_string(bridgeDto.FileName, &pDto->FileName);
|
||||||
allocate_string(bridgeDto.SHA1, &pDto->SHA1);
|
// allocate_string(bridgeDto.SHA1, &pDto->SHA1);
|
||||||
allocate_string(bridgeDto.SHA256, &pDto->SHA256);
|
// allocate_string(bridgeDto.SHA256, &pDto->SHA256);
|
||||||
pDto->Size = bridgeDto.Size;
|
// pDto->Size = bridgeDto.Size;
|
||||||
allocate_string(bridgeDto.NotesMarkdown, &pDto->NotesMarkdown);
|
// allocate_string(bridgeDto.NotesMarkdown, &pDto->NotesMarkdown);
|
||||||
allocate_string(bridgeDto.NotesHtml, &pDto->NotesHtml);
|
// allocate_string(bridgeDto.NotesHtml, &pDto->NotesHtml);
|
||||||
}
|
// }
|
||||||
|
|
||||||
static inline void free_velopackasset(vpkc_asset_t* pDto) {
|
// static inline void free_velopackasset(vpkc_asset_t* pDto) {
|
||||||
if (pDto == nullptr) { return; }
|
// if (pDto == nullptr) { return; }
|
||||||
free(pDto->PackageId);
|
// free(pDto->PackageId);
|
||||||
free(pDto->Version);
|
// free(pDto->Version);
|
||||||
free(pDto->Type);
|
// free(pDto->Type);
|
||||||
free(pDto->FileName);
|
// free(pDto->FileName);
|
||||||
free(pDto->SHA1);
|
// free(pDto->SHA1);
|
||||||
free(pDto->SHA256);
|
// free(pDto->SHA256);
|
||||||
free(pDto->NotesMarkdown);
|
// free(pDto->NotesMarkdown);
|
||||||
free(pDto->NotesHtml);
|
// free(pDto->NotesHtml);
|
||||||
}
|
// }
|
||||||
|
|
||||||
static inline UpdateInfoDto to_bridge(vpkc_update_info_t* pDto) {
|
// static inline UpdateInfoDto to_bridge(vpkc_update_info_t* pDto) {
|
||||||
if (pDto == nullptr) { return {}; }
|
// if (pDto == nullptr) { return {}; }
|
||||||
return {
|
// return {
|
||||||
to_bridge(&pDto->TargetFullRelease),
|
// to_bridge(&pDto->TargetFullRelease),
|
||||||
pDto->IsDowngrade,
|
// pDto->IsDowngrade,
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
|
|
||||||
static inline UpdateInfoDtoOption to_bridge_opt(vpkc_update_info_t* pDto) {
|
// static inline UpdateInfoDtoOption to_bridge_opt(vpkc_update_info_t* pDto) {
|
||||||
UpdateInfoDtoOption opt;
|
// UpdateInfoDtoOption opt;
|
||||||
if (pDto == nullptr) {
|
// if (pDto == nullptr) {
|
||||||
opt.has_data = false;
|
// opt.has_data = false;
|
||||||
return opt;
|
// return opt;
|
||||||
}
|
// }
|
||||||
|
|
||||||
opt.has_data = true;
|
// opt.has_data = true;
|
||||||
opt.data = to_bridge(pDto);
|
// opt.data = to_bridge(pDto);
|
||||||
return opt;
|
// return opt;
|
||||||
}
|
// }
|
||||||
|
|
||||||
static inline void allocate_updateinfo(UpdateInfoDto bridgeDto, vpkc_update_info_t* pDto) {
|
// static inline void allocate_updateinfo(UpdateInfoDto bridgeDto, vpkc_update_info_t* pDto) {
|
||||||
if (pDto == nullptr) { return; }
|
// if (pDto == nullptr) { return; }
|
||||||
allocate_velopackasset(bridgeDto.TargetFullRelease, &pDto->TargetFullRelease);
|
// allocate_velopackasset(bridgeDto.TargetFullRelease, &pDto->TargetFullRelease);
|
||||||
pDto->IsDowngrade = bridgeDto.IsDowngrade;
|
// pDto->IsDowngrade = bridgeDto.IsDowngrade;
|
||||||
}
|
// }
|
||||||
|
|
||||||
static inline void free_updateinfo(vpkc_update_info_t* pDto) {
|
// static inline void free_updateinfo(vpkc_update_info_t* pDto) {
|
||||||
if (pDto == nullptr) { return; }
|
// if (pDto == nullptr) { return; }
|
||||||
free_velopackasset(&pDto->TargetFullRelease);
|
// free_velopackasset(&pDto->TargetFullRelease);
|
||||||
}
|
// }
|
||||||
|
|
||||||
static inline UpdateOptionsDto to_bridge(vpkc_update_options_t* pDto) {
|
// static inline UpdateOptionsDto to_bridge(vpkc_update_options_t* pDto) {
|
||||||
if (pDto == nullptr) { return {}; }
|
// if (pDto == nullptr) { return {}; }
|
||||||
return {
|
// return {
|
||||||
pDto->AllowVersionDowngrade,
|
// pDto->AllowVersionDowngrade,
|
||||||
to_bridgestring_opt(pDto->ExplicitChannel),
|
// to_bridgestring_opt(pDto->ExplicitChannel),
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
|
|
||||||
static inline UpdateOptionsDtoOption to_bridge_opt(vpkc_update_options_t* pDto) {
|
// static inline UpdateOptionsDtoOption to_bridge_opt(vpkc_update_options_t* pDto) {
|
||||||
UpdateOptionsDtoOption opt;
|
// UpdateOptionsDtoOption opt;
|
||||||
if (pDto == nullptr) {
|
// if (pDto == nullptr) {
|
||||||
opt.has_data = false;
|
// opt.has_data = false;
|
||||||
return opt;
|
// return opt;
|
||||||
}
|
// }
|
||||||
|
|
||||||
opt.has_data = true;
|
// opt.has_data = true;
|
||||||
opt.data = to_bridge(pDto);
|
// opt.data = to_bridge(pDto);
|
||||||
return opt;
|
// return opt;
|
||||||
}
|
// }
|
||||||
|
|
||||||
static inline void allocate_updateoptions(UpdateOptionsDto bridgeDto, vpkc_update_options_t* pDto) {
|
// static inline void allocate_updateoptions(UpdateOptionsDto bridgeDto, vpkc_update_options_t* pDto) {
|
||||||
if (pDto == nullptr) { return; }
|
// if (pDto == nullptr) { return; }
|
||||||
pDto->AllowVersionDowngrade = bridgeDto.AllowVersionDowngrade;
|
// pDto->AllowVersionDowngrade = bridgeDto.AllowVersionDowngrade;
|
||||||
allocate_string_opt(bridgeDto.ExplicitChannel, &pDto->ExplicitChannel);
|
// allocate_string_opt(bridgeDto.ExplicitChannel, &pDto->ExplicitChannel);
|
||||||
}
|
// }
|
||||||
|
|
||||||
static inline void free_updateoptions(vpkc_update_options_t* pDto) {
|
// static inline void free_updateoptions(vpkc_update_options_t* pDto) {
|
||||||
if (pDto == nullptr) { return; }
|
// if (pDto == nullptr) { return; }
|
||||||
free(pDto->ExplicitChannel);
|
// free(pDto->ExplicitChannel);
|
||||||
}
|
// }
|
||||||
// !! AUTO-GENERATED-END BRIDGE_MAPPING
|
// // !! AUTO-GENERATED-END BRIDGE_MAPPING
|
||||||
|
|
||||||
static inline size_t return_c_string(std::string& value, char* psz, size_t csz) {
|
// static inline size_t return_c_string(std::string& value, char* psz, size_t csz) {
|
||||||
if (value.empty()) {
|
// if (value.empty()) {
|
||||||
return 0;
|
// return 0;
|
||||||
}
|
// }
|
||||||
|
|
||||||
const char* c_str = value.c_str();
|
// const char* c_str = value.c_str();
|
||||||
size_t len = strlen(c_str);
|
// size_t len = strlen(c_str);
|
||||||
if (psz == nullptr || csz == 0 || len == 0) {
|
// if (psz == nullptr || csz == 0 || len == 0) {
|
||||||
// no buffer has been provided, return the length
|
// // no buffer has been provided, return the length
|
||||||
return len;
|
// return len;
|
||||||
}
|
// }
|
||||||
|
|
||||||
// shorten the length if it's longer than the buffer
|
// // shorten the length if it's longer than the buffer
|
||||||
if (len > csz) {
|
// if (len > csz) {
|
||||||
len = csz;
|
// len = csz;
|
||||||
}
|
// }
|
||||||
|
|
||||||
// copy the string to the buffer
|
// // copy the string to the buffer
|
||||||
memcpy(psz, c_str, len);
|
// memcpy(psz, c_str, len);
|
||||||
return len;
|
// return len;
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Error handling
|
// // Error handling
|
||||||
std::string lastError;
|
// std::string lastError;
|
||||||
VPKC_EXPORT size_t VPKC_CALL vpkc_get_last_error(char* pszError, size_t cError) {
|
// VPKC_EXPORT size_t VPKC_CALL vpkc_get_last_error(char* pszError, size_t cError) {
|
||||||
return return_c_string(lastError, pszError, cError);
|
// return return_c_string(lastError, pszError, cError);
|
||||||
}
|
// }
|
||||||
static inline void set_last_error(const char* pszError) {
|
// static inline void set_last_error(const char* pszError) {
|
||||||
lastError = pszError;
|
// lastError = pszError;
|
||||||
}
|
// }
|
||||||
static inline void clear_last_error() {
|
// static inline void clear_last_error() {
|
||||||
lastError.clear();
|
// lastError.clear();
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Update Manager
|
// // 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) {
|
// 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();
|
// clear_last_error();
|
||||||
try {
|
// try {
|
||||||
if (pManager == nullptr) {
|
// if (pManager == nullptr) {
|
||||||
set_last_error("pManager cannot be null");
|
// set_last_error("pManager cannot be null");
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
|
|
||||||
VelopackLocatorConfigDtoOption locator = to_bridge_opt(pLocator);
|
// VelopackLocatorConfigDtoOption locator = to_bridge_opt(pLocator);
|
||||||
UpdateOptionsDtoOption options = to_bridge_opt(pOptions);
|
// UpdateOptionsDtoOption options = to_bridge_opt(pOptions);
|
||||||
|
|
||||||
::rust::Box<::UpdateManagerOpaque> manager = bridge_new_update_manager(pszUrlOrString, options, locator);
|
// ::rust::Box<::UpdateManagerOpaque> manager = bridge_new_update_manager(pszUrlOrString, options, locator);
|
||||||
UpdateManagerOpaque* pOpaque = manager.into_raw();
|
// UpdateManagerOpaque* pOpaque = manager.into_raw();
|
||||||
*pManager = reinterpret_cast<vpkc_update_manager_t*>(pOpaque);
|
// *pManager = reinterpret_cast<vpkc_update_manager_t*>(pOpaque);
|
||||||
return true;
|
// return true;
|
||||||
} catch (const std::exception& e) {
|
// } catch (const std::exception& e) {
|
||||||
set_last_error(e.what());
|
// set_last_error(e.what());
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
VPKC_EXPORT size_t VPKC_CALL vpkc_get_current_version(vpkc_update_manager_t* pManager, char* pszVersion, size_t cVersion) {
|
// VPKC_EXPORT size_t VPKC_CALL vpkc_get_current_version(vpkc_update_manager_t* pManager, char* pszVersion, size_t cVersion) {
|
||||||
UpdateManagerOpaque* pOpaque = reinterpret_cast<UpdateManagerOpaque*>(pManager);
|
// UpdateManagerOpaque* pOpaque = reinterpret_cast<UpdateManagerOpaque*>(pManager);
|
||||||
std::string version = (std::string)bridge_get_current_version(*pOpaque);
|
// std::string version = (std::string)bridge_get_current_version(*pOpaque);
|
||||||
return return_c_string(version, pszVersion, cVersion);
|
// 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) {
|
// VPKC_EXPORT size_t VPKC_CALL vpkc_get_app_id(vpkc_update_manager_t* pManager, char* pszId, size_t cId) {
|
||||||
UpdateManagerOpaque* pOpaque = reinterpret_cast<UpdateManagerOpaque*>(pManager);
|
// UpdateManagerOpaque* pOpaque = reinterpret_cast<UpdateManagerOpaque*>(pManager);
|
||||||
std::string id = (std::string)bridge_get_app_id(*pOpaque);
|
// std::string id = (std::string)bridge_get_app_id(*pOpaque);
|
||||||
return return_c_string(id, pszId, cId);
|
// return return_c_string(id, pszId, cId);
|
||||||
|
|
||||||
}
|
// }
|
||||||
VPKC_EXPORT bool VPKC_CALL vpkc_is_portable(vpkc_update_manager_t* pManager) {
|
// VPKC_EXPORT bool VPKC_CALL vpkc_is_portable(vpkc_update_manager_t* pManager) {
|
||||||
UpdateManagerOpaque* pOpaque = reinterpret_cast<UpdateManagerOpaque*>(pManager);
|
// UpdateManagerOpaque* pOpaque = reinterpret_cast<UpdateManagerOpaque*>(pManager);
|
||||||
return bridge_is_portable(*pOpaque);
|
// return bridge_is_portable(*pOpaque);
|
||||||
}
|
// }
|
||||||
VPKC_EXPORT bool VPKC_CALL vpkc_update_pending_restart(vpkc_update_manager_t* pManager, vpkc_asset_t* pAsset) {
|
// VPKC_EXPORT bool VPKC_CALL vpkc_update_pending_restart(vpkc_update_manager_t* pManager, vpkc_asset_t* pAsset) {
|
||||||
UpdateManagerOpaque* pOpaque = reinterpret_cast<UpdateManagerOpaque*>(pManager);
|
// UpdateManagerOpaque* pOpaque = reinterpret_cast<UpdateManagerOpaque*>(pManager);
|
||||||
VelopackAssetDtoOption asset = bridge_update_pending_restart(*pOpaque);
|
// VelopackAssetDtoOption asset = bridge_update_pending_restart(*pOpaque);
|
||||||
if (asset.has_data) {
|
// if (asset.has_data) {
|
||||||
allocate_velopackasset(asset.data, pAsset);
|
// allocate_velopackasset(asset.data, pAsset);
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
VPKC_EXPORT vpkc_update_check_t VPKC_CALL vpkc_check_for_updates(vpkc_update_manager_t* pManager, vpkc_update_info_t* pUpdate) {
|
// 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();
|
// clear_last_error();
|
||||||
try {
|
// try {
|
||||||
UpdateManagerOpaque* pOpaque = reinterpret_cast<UpdateManagerOpaque*>(pManager);
|
// UpdateManagerOpaque* pOpaque = reinterpret_cast<UpdateManagerOpaque*>(pManager);
|
||||||
UpdateInfoDtoOption update = bridge_check_for_updates(*pOpaque);
|
// UpdateInfoDtoOption update = bridge_check_for_updates(*pOpaque);
|
||||||
if (update.has_data) {
|
// if (update.has_data) {
|
||||||
allocate_updateinfo(update.data, pUpdate);
|
// allocate_updateinfo(update.data, pUpdate);
|
||||||
return vpkc_update_check_t::UPDATE_AVAILABLE;
|
// return vpkc_update_check_t::UPDATE_AVAILABLE;
|
||||||
}
|
// }
|
||||||
return vpkc_update_check_t::NO_UPDATE_AVAILABLE;
|
// return vpkc_update_check_t::NO_UPDATE_AVAILABLE;
|
||||||
}
|
// }
|
||||||
catch (const std::exception& e) {
|
// catch (const std::exception& e) {
|
||||||
set_last_error(e.what());
|
// set_last_error(e.what());
|
||||||
return vpkc_update_check_t::UPDATE_ERROR;
|
// 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) {
|
// 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();
|
// clear_last_error();
|
||||||
try {
|
// try {
|
||||||
if (!pUpdate) {
|
// if (!pUpdate) {
|
||||||
set_last_error("pUpdate is a required parameter");
|
// set_last_error("pUpdate is a required parameter");
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
|
|
||||||
UpdateManagerOpaque* pOpaque = reinterpret_cast<UpdateManagerOpaque*>(pManager);
|
// UpdateManagerOpaque* pOpaque = reinterpret_cast<UpdateManagerOpaque*>(pManager);
|
||||||
UpdateInfoDto update = to_bridge(pUpdate);
|
// UpdateInfoDto update = to_bridge(pUpdate);
|
||||||
|
|
||||||
DownloadCallbackManager download{};
|
// DownloadCallbackManager download{};
|
||||||
download.progress_cb = cbProgress;
|
// download.progress_cb = cbProgress;
|
||||||
download.user_data = pUserData;
|
// download.user_data = pUserData;
|
||||||
bridge_download_updates(*pOpaque, update, download);
|
// bridge_download_updates(*pOpaque, update, download);
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
catch (const std::exception& e) {
|
// catch (const std::exception& e) {
|
||||||
set_last_error(e.what());
|
// set_last_error(e.what());
|
||||||
return false;
|
// 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) {
|
// 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();
|
// clear_last_error();
|
||||||
try {
|
// try {
|
||||||
if (!pAsset) {
|
// if (!pAsset) {
|
||||||
set_last_error("pAsset is a required parameter");
|
// set_last_error("pAsset is a required parameter");
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
|
|
||||||
UpdateManagerOpaque* pOpaque = reinterpret_cast<UpdateManagerOpaque*>(pManager);
|
// UpdateManagerOpaque* pOpaque = reinterpret_cast<UpdateManagerOpaque*>(pManager);
|
||||||
VelopackAssetDto asset = to_bridge(pAsset);
|
// VelopackAssetDto asset = to_bridge(pAsset);
|
||||||
|
|
||||||
::rust::Vec<::rust::String> restartArgs{};
|
// ::rust::Vec<::rust::String> restartArgs{};
|
||||||
for (size_t i = 0; i < cRestartArgs; i++) {
|
// for (size_t i = 0; i < cRestartArgs; i++) {
|
||||||
restartArgs.push_back(pRestartArgs[i]);
|
// restartArgs.push_back(pRestartArgs[i]);
|
||||||
}
|
// }
|
||||||
|
|
||||||
bridge_wait_exit_then_apply_update(*pOpaque, asset, bSilent, bRestart, restartArgs);
|
// bridge_wait_exit_then_apply_update(*pOpaque, asset, bSilent, bRestart, restartArgs);
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
catch (const std::exception& e) {
|
// catch (const std::exception& e) {
|
||||||
set_last_error(e.what());
|
// set_last_error(e.what());
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// VelopackApp
|
// // VelopackApp
|
||||||
bool autoApply = true;
|
// bool autoApply = true;
|
||||||
StringArrayOption args{};
|
// StringArrayOption args{};
|
||||||
VelopackLocatorConfigDtoOption locator{};
|
// VelopackLocatorConfigDtoOption locator{};
|
||||||
HookCallbackManager hooks{};
|
// HookCallbackManager hooks{};
|
||||||
|
|
||||||
VPKC_EXPORT void VPKC_CALL vpkc_app_set_auto_apply_on_startup(bool bAutoApply) {
|
// VPKC_EXPORT void VPKC_CALL vpkc_app_set_auto_apply_on_startup(bool bAutoApply) {
|
||||||
autoApply = bAutoApply;
|
// autoApply = bAutoApply;
|
||||||
}
|
// }
|
||||||
VPKC_EXPORT void VPKC_CALL vpkc_app_set_args(char** pArgs, size_t cArgs) {
|
// VPKC_EXPORT void VPKC_CALL vpkc_app_set_args(char** pArgs, size_t cArgs) {
|
||||||
args.has_data = true;
|
// args.has_data = true;
|
||||||
args.data.clear();
|
// args.data.clear();
|
||||||
for (size_t i = 0; i < cArgs; i++) {
|
// for (size_t i = 0; i < cArgs; i++) {
|
||||||
args.data.push_back(pArgs[i]);
|
// args.data.push_back(pArgs[i]);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
VPKC_EXPORT void VPKC_CALL vpkc_app_set_locator(vpkc_locator_config_t* pLocator) {
|
// VPKC_EXPORT void VPKC_CALL vpkc_app_set_locator(vpkc_locator_config_t* pLocator) {
|
||||||
locator = to_bridge_opt(pLocator);
|
// locator = to_bridge_opt(pLocator);
|
||||||
}
|
// }
|
||||||
VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_after_install(vpkc_hook_callback_t cbAfterInstall) {
|
// VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_after_install(vpkc_hook_callback_t cbAfterInstall) {
|
||||||
hooks.after_install = cbAfterInstall;
|
// hooks.after_install = cbAfterInstall;
|
||||||
}
|
// }
|
||||||
VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_before_uninstall(vpkc_hook_callback_t cbBeforeUninstall) {
|
// VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_before_uninstall(vpkc_hook_callback_t cbBeforeUninstall) {
|
||||||
hooks.before_uninstall = cbBeforeUninstall;
|
// hooks.before_uninstall = cbBeforeUninstall;
|
||||||
}
|
// }
|
||||||
VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_before_update(vpkc_hook_callback_t cbBeforeUpdate) {
|
// VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_before_update(vpkc_hook_callback_t cbBeforeUpdate) {
|
||||||
hooks.before_update = cbBeforeUpdate;
|
// hooks.before_update = cbBeforeUpdate;
|
||||||
}
|
// }
|
||||||
VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_after_update(vpkc_hook_callback_t cbAfterUpdate) {
|
// VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_after_update(vpkc_hook_callback_t cbAfterUpdate) {
|
||||||
hooks.after_update = cbAfterUpdate;
|
// hooks.after_update = cbAfterUpdate;
|
||||||
}
|
// }
|
||||||
VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_first_run(vpkc_hook_callback_t cbFirstRun) {
|
// VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_first_run(vpkc_hook_callback_t cbFirstRun) {
|
||||||
hooks.first_run = cbFirstRun;
|
// hooks.first_run = cbFirstRun;
|
||||||
}
|
// }
|
||||||
VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_restarted(vpkc_hook_callback_t cbRestarted) {
|
// VPKC_EXPORT void VPKC_CALL vpkc_app_set_hook_restarted(vpkc_hook_callback_t cbRestarted) {
|
||||||
hooks.restarted = cbRestarted;
|
// hooks.restarted = cbRestarted;
|
||||||
}
|
// }
|
||||||
VPKC_EXPORT void VPKC_CALL vpkc_app_run(void* pUserData) {
|
// VPKC_EXPORT void VPKC_CALL vpkc_app_run(void* pUserData) {
|
||||||
hooks.user_data = pUserData;
|
// hooks.user_data = pUserData;
|
||||||
bridge_appbuilder_run(hooks, args, locator, autoApply);
|
// bridge_appbuilder_run(hooks, args, locator, autoApply);
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Misc functions
|
// // Misc functions
|
||||||
LoggerCallbackManager logMgr{};
|
// LoggerCallbackManager logMgr{};
|
||||||
VPKC_EXPORT void VPKC_CALL vpkc_set_logger(vpkc_log_callback_t cbLog, void* pUserData) {
|
// VPKC_EXPORT void VPKC_CALL vpkc_set_logger(vpkc_log_callback_t cbLog, void* pUserData) {
|
||||||
logMgr.lob_cb = cbLog;
|
// logMgr.lob_cb = cbLog;
|
||||||
logMgr.user_data = pUserData;
|
// logMgr.user_data = pUserData;
|
||||||
bridge_set_logger_callback(&logMgr);
|
// bridge_set_logger_callback(&logMgr);
|
||||||
}
|
// }
|
||||||
VPKC_EXPORT void VPKC_CALL vpkc_free_update_manager(vpkc_update_manager_t* pManager) {
|
// VPKC_EXPORT void VPKC_CALL vpkc_free_update_manager(vpkc_update_manager_t* pManager) {
|
||||||
UpdateManagerOpaque* pOpaque = reinterpret_cast<UpdateManagerOpaque*>(pManager);
|
// UpdateManagerOpaque* pOpaque = reinterpret_cast<UpdateManagerOpaque*>(pManager);
|
||||||
auto box = ::rust::Box<::UpdateManagerOpaque>::from_raw(pOpaque);
|
// auto box = ::rust::Box<::UpdateManagerOpaque>::from_raw(pOpaque);
|
||||||
// this will free when the box goes out of scope
|
// // this will free when the box goes out of scope
|
||||||
}
|
// }
|
||||||
VPKC_EXPORT void VPKC_CALL vpkc_free_update_info(vpkc_update_info_t* pUpdateInfo) {
|
// VPKC_EXPORT void VPKC_CALL vpkc_free_update_info(vpkc_update_info_t* pUpdateInfo) {
|
||||||
free_updateinfo(pUpdateInfo);
|
// free_updateinfo(pUpdateInfo);
|
||||||
}
|
// }
|
||||||
VPKC_EXPORT void VPKC_CALL vpkc_free_asset(vpkc_asset_t* pAsset) {
|
// VPKC_EXPORT void VPKC_CALL vpkc_free_asset(vpkc_asset_t* pAsset) {
|
||||||
free_velopackasset(pAsset);
|
// free_velopackasset(pAsset);
|
||||||
}
|
// }
|
||||||
@@ -1,69 +1,69 @@
|
|||||||
#pragma once
|
// #pragma once
|
||||||
#include "rust/cxx.h"
|
// #include "rust/cxx.h"
|
||||||
#include "velopack_libc/include/Velopack.h"
|
// #include "velopack_libc/include/Velopack.h"
|
||||||
|
|
||||||
struct HookCallbackManager {
|
// struct HookCallbackManager {
|
||||||
vpkc_hook_callback_t after_install = nullptr;
|
// vpkc_hook_callback_t after_install = nullptr;
|
||||||
vpkc_hook_callback_t before_uninstall = nullptr;
|
// vpkc_hook_callback_t before_uninstall = nullptr;
|
||||||
vpkc_hook_callback_t before_update = nullptr;
|
// vpkc_hook_callback_t before_update = nullptr;
|
||||||
vpkc_hook_callback_t after_update = nullptr;
|
// vpkc_hook_callback_t after_update = nullptr;
|
||||||
vpkc_hook_callback_t first_run = nullptr;
|
// vpkc_hook_callback_t first_run = nullptr;
|
||||||
vpkc_hook_callback_t restarted = nullptr;
|
// vpkc_hook_callback_t restarted = nullptr;
|
||||||
void* user_data = nullptr;
|
// void* user_data = nullptr;
|
||||||
|
|
||||||
void install_hook(::rust::String app_version) const {
|
// void install_hook(::rust::String app_version) const {
|
||||||
if (after_install) {
|
// if (after_install) {
|
||||||
after_install(user_data, app_version.c_str());
|
// after_install(user_data, app_version.c_str());
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
|
|
||||||
void update_hook(::rust::String app_version) const {
|
// void update_hook(::rust::String app_version) const {
|
||||||
if (after_update) {
|
// if (after_update) {
|
||||||
after_update(user_data, app_version.c_str());
|
// after_update(user_data, app_version.c_str());
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
|
|
||||||
void obsolete_hook(::rust::String app_version) const {
|
// void obsolete_hook(::rust::String app_version) const {
|
||||||
if (before_update) {
|
// if (before_update) {
|
||||||
before_update(user_data, app_version.c_str());
|
// before_update(user_data, app_version.c_str());
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
|
|
||||||
void uninstall_hook(::rust::String app_version) const {
|
// void uninstall_hook(::rust::String app_version) const {
|
||||||
if (before_uninstall) {
|
// if (before_uninstall) {
|
||||||
before_uninstall(user_data, app_version.c_str());
|
// before_uninstall(user_data, app_version.c_str());
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
|
|
||||||
void firstrun_hook(::rust::String app_version) const {
|
// void firstrun_hook(::rust::String app_version) const {
|
||||||
if (first_run) {
|
// if (first_run) {
|
||||||
first_run(user_data, app_version.c_str());
|
// first_run(user_data, app_version.c_str());
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
|
|
||||||
void restarted_hook(::rust::String app_version) const {
|
// void restarted_hook(::rust::String app_version) const {
|
||||||
if (restarted) {
|
// if (restarted) {
|
||||||
restarted(user_data, app_version.c_str());
|
// restarted(user_data, app_version.c_str());
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
};
|
// };
|
||||||
|
|
||||||
struct DownloadCallbackManager {
|
// struct DownloadCallbackManager {
|
||||||
vpkc_progress_callback_t progress_cb = nullptr;
|
// vpkc_progress_callback_t progress_cb = nullptr;
|
||||||
void* user_data = nullptr;
|
// void* user_data = nullptr;
|
||||||
void download_progress(int16_t progress) const {
|
// void download_progress(int16_t progress) const {
|
||||||
if (progress_cb) {
|
// if (progress_cb) {
|
||||||
progress_cb(user_data, progress);
|
// progress_cb(user_data, progress);
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
};
|
// };
|
||||||
|
|
||||||
struct LoggerCallbackManager {
|
// struct LoggerCallbackManager {
|
||||||
vpkc_log_callback_t lob_cb = nullptr;
|
// vpkc_log_callback_t lob_cb = nullptr;
|
||||||
void* user_data = nullptr;
|
// void* user_data = nullptr;
|
||||||
void log(::rust::String level, ::rust::String message) const {
|
// void log(::rust::String level, ::rust::String message) const {
|
||||||
if (lob_cb) {
|
// if (lob_cb) {
|
||||||
lob_cb(user_data, level.c_str(), message.c_str());
|
// lob_cb(user_data, level.c_str(), message.c_str());
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
};
|
// };
|
||||||
@@ -1,210 +1,140 @@
|
|||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
|
#![allow(non_camel_case_types)]
|
||||||
|
|
||||||
mod map;
|
mod statics;
|
||||||
use map::*;
|
use statics::*;
|
||||||
|
|
||||||
use anyhow::{bail, Result};
|
mod types;
|
||||||
use log::{Level, Log, Metadata, Record};
|
use types::*;
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
|
||||||
|
use anyhow::{anyhow, bail};
|
||||||
|
use std::ffi::{c_char, c_void, CString};
|
||||||
use velopack::{sources, Error as VelopackError, UpdateCheck, UpdateManager, VelopackApp};
|
use velopack::{sources, Error as VelopackError, UpdateCheck, UpdateManager, VelopackApp};
|
||||||
|
|
||||||
#[cxx::bridge]
|
#[repr(C)]
|
||||||
mod ffi {
|
pub enum vpkc_update_check_t {
|
||||||
// Shared structs with fields visible to both languages.
|
UPDATE_ERROR = -1,
|
||||||
#[derive(Default)]
|
UPDATE_AVAILABLE = 0,
|
||||||
pub struct StringOption {
|
NO_UPDATE_AVAILABLE = 1,
|
||||||
pub data: String,
|
REMOTE_IS_EMPTY = 2,
|
||||||
pub has_data: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[no_mangle]
|
||||||
pub struct StringArrayOption {
|
pub extern "C" fn vpkc_new_update_manager(
|
||||||
pub data: Vec<String>,
|
psz_url_or_string: *const c_char,
|
||||||
pub has_data: bool,
|
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(())
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// !! AUTO-GENERATED-START BRIDGE_DTOS
|
#[no_mangle]
|
||||||
#[derive(Default)]
|
pub extern "C" fn vpkc_get_current_version(p_manager: *mut c_void, psz_version: *mut c_char, c_version: usize) -> usize {
|
||||||
pub struct VelopackLocatorConfigDto {
|
if p_manager.is_null() {
|
||||||
pub RootAppDir: String,
|
return 0;
|
||||||
pub UpdateExePath: String,
|
|
||||||
pub PackagesDir: String,
|
|
||||||
pub ManifestPath: String,
|
|
||||||
pub CurrentBinaryDir: String,
|
|
||||||
pub IsPortable: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
let manager = unsafe { &*(p_manager as *mut UpdateManagerOpaque) };
|
||||||
pub struct VelopackLocatorConfigDtoOption {
|
let version = manager.obj.get_current_version_as_string();
|
||||||
pub data: VelopackLocatorConfigDto,
|
return_cstr(psz_version, c_version, &version)
|
||||||
pub has_data: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[no_mangle]
|
||||||
pub struct VelopackAssetDto {
|
pub extern "C" fn vpkc_get_app_id(p_manager: *mut c_void, psz_id: *mut c_char, c_id: usize) -> usize {
|
||||||
pub PackageId: String,
|
if p_manager.is_null() {
|
||||||
pub Version: String,
|
return 0;
|
||||||
pub Type: String,
|
|
||||||
pub FileName: String,
|
|
||||||
pub SHA1: String,
|
|
||||||
pub SHA256: String,
|
|
||||||
pub Size: u64,
|
|
||||||
pub NotesMarkdown: String,
|
|
||||||
pub NotesHtml: String,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
let manager = unsafe { &*(p_manager as *mut UpdateManagerOpaque) };
|
||||||
pub struct VelopackAssetDtoOption {
|
let app_id = manager.obj.get_app_id();
|
||||||
pub data: VelopackAssetDto,
|
return_cstr(psz_id, c_id, &app_id)
|
||||||
pub has_data: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[no_mangle]
|
||||||
pub struct UpdateInfoDto {
|
pub extern "C" fn vpkc_is_portable(p_manager: *mut c_void) -> bool {
|
||||||
pub TargetFullRelease: VelopackAssetDto,
|
if p_manager.is_null() {
|
||||||
pub IsDowngrade: bool,
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
let manager = unsafe { &*(p_manager as *mut UpdateManagerOpaque) };
|
||||||
pub struct UpdateInfoDtoOption {
|
|
||||||
pub data: UpdateInfoDto,
|
|
||||||
pub has_data: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct UpdateOptionsDto {
|
|
||||||
pub AllowVersionDowngrade: bool,
|
|
||||||
pub ExplicitChannel: StringOption,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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<Box<UpdateManagerOpaque>>;
|
|
||||||
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<UpdateInfoDtoOption>;
|
|
||||||
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<String>,
|
|
||||||
) -> Result<()>;
|
|
||||||
fn bridge_appbuilder_run(
|
|
||||||
cb: &HookCallbackManager,
|
|
||||||
custom_args: &StringArrayOption,
|
|
||||||
locator: &VelopackLocatorConfigDtoOption,
|
|
||||||
auto_apply: bool,
|
|
||||||
);
|
|
||||||
unsafe fn bridge_set_logger_callback(cb: *mut LoggerCallbackManager);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
struct UpdateManagerOpaque {
|
|
||||||
obj: UpdateManager,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UpdateManagerOpaque {
|
|
||||||
fn new(obj: UpdateManager) -> Self {
|
|
||||||
log::debug!("UpdateManagerOpaque allocated");
|
|
||||||
UpdateManagerOpaque { obj }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for UpdateManagerOpaque {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
log::debug!("UpdateManagerOpaque dropped");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn bridge_new_update_manager(
|
|
||||||
url_or_path: &String,
|
|
||||||
options: &ffi::UpdateOptionsDtoOption,
|
|
||||||
locator: &ffi::VelopackLocatorConfigDtoOption,
|
|
||||||
) -> Result<Box<UpdateManagerOpaque>> {
|
|
||||||
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()
|
manager.obj.get_is_portable()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bridge_update_pending_restart(manager: &UpdateManagerOpaque) -> ffi::VelopackAssetDtoOption {
|
#[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;
|
||||||
|
}
|
||||||
|
|
||||||
|
let manager = unsafe { &*(p_manager as *mut UpdateManagerOpaque) };
|
||||||
let asset_opt = manager.obj.get_update_pending_restart();
|
let asset_opt = manager.obj.get_update_pending_restart();
|
||||||
velopackasset_to_bridge_option(&asset_opt)
|
|
||||||
|
if let Some(asset) = asset_opt {
|
||||||
|
unsafe { allocate_velopackasset(asset, p_asset) };
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bridge_check_for_updates(manager: &UpdateManagerOpaque) -> Result<ffi::UpdateInfoDtoOption> {
|
#[no_mangle]
|
||||||
let info_opt = if let UpdateCheck::UpdateAvailable(info) = manager.obj.check_for_updates()? { Some(info) } else { None };
|
pub extern "C" fn vpkc_check_for_updates(p_manager: *mut c_void, p_update: *mut vpkc_update_info_t) -> vpkc_update_check_t {
|
||||||
Ok(updateinfo_to_bridge_option(&info_opt))
|
if p_manager.is_null() {
|
||||||
|
set_last_error("pManager must not be null");
|
||||||
|
return vpkc_update_check_t::UPDATE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bridge_download_updates(
|
let manager = unsafe { &*(p_manager as *mut UpdateManagerOpaque) };
|
||||||
manager: &UpdateManagerOpaque,
|
|
||||||
to_download: &ffi::UpdateInfoDto,
|
match manager.obj.check_for_updates() {
|
||||||
cb: &ffi::DownloadCallbackManager,
|
Ok(UpdateCheck::UpdateAvailable(info)) => {
|
||||||
) -> Result<()> {
|
unsafe {
|
||||||
let info = updateinfo_to_core(&to_download);
|
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::<i16>();
|
let (progress_sender, progress_receiver) = std::sync::mpsc::channel::<i16>();
|
||||||
let (completion_sender, completion_receiver) = std::sync::mpsc::channel::<std::result::Result<(), VelopackError>>();
|
let (completion_sender, completion_receiver) = std::sync::mpsc::channel::<std::result::Result<(), VelopackError>>();
|
||||||
|
|
||||||
// Move the download_updates call into a new thread
|
// Move the download_updates call into a new thread
|
||||||
let manager = manager.clone();
|
let manager = manager.clone();
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
let result = manager.obj.download_updates(&info, Some(progress_sender));
|
let result = manager.obj.download_updates(&update, Some(progress_sender));
|
||||||
let _ = completion_sender.send(result);
|
let _ = completion_sender.send(result);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -213,7 +143,7 @@ fn bridge_download_updates(
|
|||||||
// Try to receive progress updates without blocking
|
// Try to receive progress updates without blocking
|
||||||
match progress_receiver.try_recv() {
|
match progress_receiver.try_recv() {
|
||||||
Ok(progress) => {
|
Ok(progress) => {
|
||||||
cb.download_progress(progress);
|
cb_progress(p_user_data, progress as usize);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// No progress updates available, sleep for a short time to avoid busy-waiting
|
// No progress updates available, sleep for a short time to avoid busy-waiting
|
||||||
@@ -236,106 +166,203 @@ fn bridge_download_updates(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bridge_wait_exit_then_apply_update(
|
#[no_mangle]
|
||||||
manager: &UpdateManagerOpaque,
|
pub extern "C" fn vpkc_wait_exit_then_apply_update(
|
||||||
to_apply: &ffi::VelopackAssetDto,
|
p_manager: *mut c_void,
|
||||||
silent: bool,
|
p_asset: *mut vpkc_asset_t,
|
||||||
restart: bool,
|
b_silent: bool,
|
||||||
restart_args: &Vec<String>,
|
b_restart: bool,
|
||||||
) -> Result<()> {
|
p_restart_args: *mut *mut c_char,
|
||||||
let asset = velopackasset_to_core(&to_apply);
|
c_restart_args: usize,
|
||||||
manager.obj.wait_exit_then_apply_updates(&asset, silent, restart, restart_args)?;
|
) -> 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(())
|
Ok(())
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bridge_appbuilder_run(
|
#[no_mangle]
|
||||||
cb: &ffi::HookCallbackManager,
|
pub extern "C" fn vpkc_free_update_manager(p_manager: *mut c_void) {
|
||||||
custom_args: &ffi::StringArrayOption,
|
if !p_manager.is_null() {
|
||||||
locator: &ffi::VelopackLocatorConfigDtoOption,
|
// Convert the raw pointer back into a Box to deallocate it properly
|
||||||
auto_apply: bool,
|
let _ = unsafe { Box::from_raw(p_manager as *mut UpdateManagerOpaque) };
|
||||||
) {
|
}
|
||||||
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 {
|
#[no_mangle]
|
||||||
let locator = velopacklocatorconfig_to_core(&locator.data);
|
pub extern "C" fn vpkc_free_update_info(p_update_info: *mut vpkc_update_info_t) {
|
||||||
app = app.set_locator(locator);
|
if !p_update_info.is_null() {
|
||||||
|
unsafe { free_updateinfo(p_update_info) };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if custom_args.has_data {
|
#[no_mangle]
|
||||||
app = app.set_args(custom_args.data.clone());
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(args) = &app_options.args {
|
||||||
|
app = app.set_args(args.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(locator) = &app_options.locator {
|
||||||
|
app = app.set_locator(locator.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
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());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
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());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
app.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LoggerImpl {}
|
#[no_mangle]
|
||||||
|
pub extern "C" fn vpkc_app_set_auto_apply_on_startup(b_auto_apply: bool) {
|
||||||
static LOGGER: LoggerImpl = LoggerImpl {};
|
update_app_options(|opt| {
|
||||||
|
opt.auto_apply = Some(b_auto_apply);
|
||||||
impl Log for LoggerImpl {
|
});
|
||||||
fn enabled(&self, metadata: &Metadata) -> bool {
|
|
||||||
metadata.level() <= log::max_level()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn log(&self, record: &Record) {
|
#[no_mangle]
|
||||||
if !self.enabled(record.metadata()) {
|
pub extern "C" fn vpkc_app_set_args(p_args: *mut *mut c_char, c_args: usize) {
|
||||||
return;
|
update_app_options(|opt| {
|
||||||
|
opt.args = c_to_string_array_opt(p_args, c_args);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let text = format!("{}", record.args());
|
#[no_mangle]
|
||||||
|
pub extern "C" fn vpkc_app_set_locator(p_locator: *mut vpkc_locator_config_t) {
|
||||||
let level = match record.level() {
|
update_app_options(|opt| {
|
||||||
Level::Error => "error",
|
opt.locator = c_to_velopacklocatorconfig_opt(p_locator);
|
||||||
Level::Warn => "warn",
|
});
|
||||||
Level::Info => "info",
|
|
||||||
Level::Debug => "debug",
|
|
||||||
Level::Trace => "trace",
|
|
||||||
}
|
}
|
||||||
.to_string();
|
|
||||||
|
|
||||||
if let Some(cb) = get_logger() {
|
#[no_mangle]
|
||||||
if let Some(cb) = unsafe { cb.as_mut() } {
|
pub extern "C" fn vpkc_app_set_hook_after_install(cb_after_install: vpkc_hook_callback_t) {
|
||||||
cb.log(level, text);
|
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)]
|
||||||
|
struct UpdateManagerOpaque {
|
||||||
|
obj: UpdateManager,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UpdateManagerOpaque {
|
||||||
|
fn new(obj: UpdateManager) -> Self {
|
||||||
|
log::debug!("UpdateManagerOpaque allocated");
|
||||||
|
UpdateManagerOpaque { obj }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flush(&self) {}
|
impl Drop for UpdateManagerOpaque {
|
||||||
}
|
fn drop(&mut self) {
|
||||||
|
log::debug!("UpdateManagerOpaque dropped");
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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<VelopackLocatorConfig> {
|
|
||||||
if dto.has_data { Some(velopacklocatorconfig_to_core(&dto.data)) } else { None }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn velopacklocatorconfig_to_bridge_option(dto: &Option<VelopackLocatorConfig>) -> 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<VelopackAsset> {
|
|
||||||
if dto.has_data { Some(velopackasset_to_core(&dto.data)) } else { None }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn velopackasset_to_bridge_option(dto: &Option<VelopackAsset>) -> 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<UpdateInfo> {
|
|
||||||
if dto.has_data { Some(updateinfo_to_core(&dto.data)) } else { None }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn updateinfo_to_bridge_option(dto: &Option<UpdateInfo>) -> 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<UpdateOptions> {
|
|
||||||
if dto.has_data { Some(updateoptions_to_core(&dto.data)) } else { None }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn updateoptions_to_bridge_option(dto: &Option<UpdateOptions>) -> 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
|
|
||||||
119
src/lib-cpp/src/statics.rs
Normal file
119
src/lib-cpp/src/statics.rs
Normal file
@@ -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<vpkc_hook_callback_t>,
|
||||||
|
pub update_hook: Option<vpkc_hook_callback_t>,
|
||||||
|
pub obsolete_hook: Option<vpkc_hook_callback_t>,
|
||||||
|
pub uninstall_hook: Option<vpkc_hook_callback_t>,
|
||||||
|
pub firstrun_hook: Option<vpkc_hook_callback_t>,
|
||||||
|
pub restarted_hook: Option<vpkc_hook_callback_t>,
|
||||||
|
pub auto_apply: Option<bool>,
|
||||||
|
pub args: Option<Vec<String>>,
|
||||||
|
pub locator: Option<VelopackLocatorConfig>,
|
||||||
|
}
|
||||||
|
|
||||||
|
lazy_static::lazy_static! {
|
||||||
|
static ref LAST_ERROR: RwLock<String> = RwLock::new(String::new());
|
||||||
|
static ref LOG_CALLBACK: Mutex<Option<(vpkc_log_callback_t, usize)>> = Mutex::new(None);
|
||||||
|
pub static ref VELOPACK_APP: RwLock<AppOptions> = RwLock::new(Default::default());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_app_options<F>(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<F>(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) {}
|
||||||
|
}
|
||||||
274
src/lib-cpp/src/types.rs
Normal file
274
src/lib-cpp/src/types.rs
Normal file
@@ -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<String> {
|
||||||
|
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<String>, 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<Vec<String>> {
|
||||||
|
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<VelopackLocatorConfig> {
|
||||||
|
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<VelopackAsset> {
|
||||||
|
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<UpdateInfo> {
|
||||||
|
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<UpdateOptions> {
|
||||||
|
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
|
||||||
@@ -47,22 +47,23 @@ if (desiredStructs.Length != availableStructs.Count) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// rust bridge code
|
// rust bridge code
|
||||||
string rustCppLib = Path.Combine(libcppDir, "src", "lib.rs");
|
// string rustCppLib = Path.Combine(libcppDir, "src", "lib.rs");
|
||||||
string rustCppMap = Path.Combine(libcppDir, "src", "map.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 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");
|
//Console.WriteLine("Generating bridge dtos");
|
||||||
var sbBridgeDto = new IndentStringBuilder();
|
//var sbBridgeDto = new IndentStringBuilder();
|
||||||
foreach(var rs in availableStructs) {
|
//foreach(var rs in availableStructs) {
|
||||||
Templates.WriteBridgeDto(desiredStructs, sbBridgeDto, rs);
|
// Templates.WriteBridgeDto(desiredStructs, sbBridgeDto, rs);
|
||||||
}
|
//}
|
||||||
|
|
||||||
Console.WriteLine("Generating bridge to core mappings");
|
//Console.WriteLine("Generating bridge to core mappings");
|
||||||
var sbBridgeMapping = new IndentStringBuilder();
|
//var sbBridgeMapping = new IndentStringBuilder();
|
||||||
foreach(var rs in availableStructs) {
|
//foreach(var rs in availableStructs) {
|
||||||
Templates.WriteBridgeToCoreMapping(desiredStructs, sbBridgeMapping, rs);
|
// Templates.WriteBridgeToCoreMapping(desiredStructs, sbBridgeMapping, rs);
|
||||||
}
|
//}
|
||||||
|
|
||||||
Console.WriteLine("Generating C types");
|
Console.WriteLine("Generating C types");
|
||||||
var cTypes = new IndentStringBuilder();
|
var cTypes = new IndentStringBuilder();
|
||||||
@@ -81,17 +82,24 @@ foreach (var rs in availableStructs) {
|
|||||||
Templates.WriteC2CPPMapping(basic_libc_names, cppTypes, rs);
|
Templates.WriteC2CPPMapping(basic_libc_names, cppTypes, rs);
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine("Generating C to bridge mappings");
|
Console.WriteLine("Generating Rust-C types");
|
||||||
var cToBridgeMapping = new IndentStringBuilder();
|
var rustCTypes = new IndentStringBuilder();
|
||||||
foreach (var rs in availableStructs) {
|
foreach (var rs in availableStructs) {
|
||||||
Templates.WriteCBridgeMapping(basic_libc_names, cToBridgeMapping, rs);
|
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");
|
Console.WriteLine("Writing all to file");
|
||||||
Util.ReplaceTextInFile(rustCppLib, "BRIDGE_DTOS", sbBridgeDto.ToString());
|
//Util.ReplaceTextInFile(rustCppLib, "BRIDGE_DTOS", sbBridgeDto.ToString());
|
||||||
Util.ReplaceTextInFile(rustCppMap, "CORE_MAPPING", sbBridgeMapping.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, "C_TYPES", cTypes.ToString());
|
||||||
Util.ReplaceTextInFile(rustCppInclude, "CPP_TYPES", cppTypes.ToString());
|
Util.ReplaceTextInFile(rustCppInclude, "CPP_TYPES", cppTypes.ToString());
|
||||||
Util.ReplaceTextInFile(rustBridgeC, "BRIDGE_MAPPING", cToBridgeMapping.ToString());
|
//Util.ReplaceTextInFile(rustBridgeC, "BRIDGE_MAPPING", cToBridgeMapping.ToString());
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -25,6 +25,103 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string GetBasicCTypeInRust(Dictionary<string, string> 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<string, string> 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)
|
private static string GetCPlusPlusType(string[] coreTypes, string rustType, bool optional)
|
||||||
{
|
{
|
||||||
string type = rustType switch {
|
string type = rustType switch {
|
||||||
@@ -100,6 +197,7 @@
|
|||||||
: $"pDto->{field.Name} = bridgeDto.{field.Name};");
|
: $"pDto->{field.Name} = bridgeDto.{field.Name};");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.AppendLine($"}}");
|
sb.AppendLine($"}}");
|
||||||
sb.AppendLine();
|
sb.AppendLine();
|
||||||
|
|
||||||
@@ -115,6 +213,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.AppendLine($"}}");
|
sb.AppendLine($"}}");
|
||||||
sb.AppendLine();
|
sb.AppendLine();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use std::env;
|
|||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
locator::{VelopackLocatorConfig},
|
locator::VelopackLocatorConfig,
|
||||||
constants::*,
|
constants::*,
|
||||||
manager,
|
manager,
|
||||||
sources,
|
sources,
|
||||||
|
|||||||
Reference in New Issue
Block a user