feat: update wfassoc c/c++ bindings

This commit is contained in:
2026-08-15 18:06:09 +08:00
parent a595d7e6e7
commit 36330437de
2 changed files with 144 additions and 171 deletions
+43 -48
View File
@@ -24,8 +24,16 @@
*/
namespace wfassocpp {
/** @brief Type representing a null-terminated UTF-8 C-style string */
using CString = wfassoc::WFCString;
/** @brief Type representing a pointer to a null-terminated UTF-8 C-style string */
using StrPtr = wfassoc::WFStrPtr;
/**
* @brief Type representing an error code returned by FFI functions
*
* WFERROR_OK is the only value representing absolute success.
* Any other value's meaning is decided by this library,
* currently WFERROR_ERR represents a generic failure.
*/
using Error = wfassoc::WFError;
/**
* @brief Type representing a handle/token for managed objects
*
@@ -39,10 +47,12 @@ using Token = wfassoc::WFToken;
* This type is equivalent to the Win32 HICON type.
*/
using HICON = wfassoc::WFHICON;
/** @brief Invalid token value used as a sentinel for no object */
constexpr Token INVALID_TOKEN = wfassoc::WF_INVALID_TOKEN;
/** @brief Invalid icon handle value */
using INVALID_HICON = wfassoc::WF_INVALID_HICON;
constexpr HICON INVALID_HICON = wfassoc::WF_INVALID_HICON;
/** @brief Invalid index value used for error conditions */
using INVALID_INDEX = wfassoc::WF_INVALID_INDEX;
constexpr size_t INVALID_INDEX = wfassoc::WF_INVALID_INDEX;
/**
* @brief Registration scope for file associations
*
@@ -60,30 +70,15 @@ using View = wfassoc::WFView;
* @private
* @brief Check the result of a C API call and throw on failure
*
* @param[in] result Boolean result from a C API call
* @throws std::runtime_error if result is false, with the error message from WFGetLastError()
* @param[in] result Error code returned from a C API call
* @throws std::runtime_error if result is not WFERROR_OK, with the error message from WFGetLastError()
*/
inline void _Check(bool result) {
if (!result) {
inline void _Check(wfassoc::WFError result) {
if (result != wfassoc::WFERROR_OK) {
throw std::runtime_error(wfassoc::WFGetLastError());
}
}
/**
* @private
* @brief Get the invalid token value
*
* In theory, invalid token value should be a constant value.
* However, due to the library used in Rust side, this value can only be fetched at runtime.
* This function caches the value on first call for subsequent use.
*
* @return An invalid token value
*/
inline Token _INVALID_TOKEN() {
static Token v = wfassoc::WFInvalidToken();
return v;
}
/**
* @brief Schema object for defining a program's file association configuration
*
@@ -106,7 +101,7 @@ public:
* Releases resources associated with the Schema object.
*/
~Schema() {
if (_token != _INVALID_TOKEN()) {
if (_token != INVALID_TOKEN) {
wfassoc::WFSchemaDestroy(_token);
}
}
@@ -117,15 +112,15 @@ public:
Schema& operator=(const Schema&) = delete;
/** @brief Move constructor */
Schema(Schema&& other) noexcept : _token(other._token) { other._token = _INVALID_TOKEN(); }
Schema(Schema&& other) noexcept : _token(other._token) { other._token = INVALID_TOKEN; }
/** @brief Move assignment operator */
Schema& operator=(Schema&& other) noexcept {
if (this != &other) {
if (_token != _INVALID_TOKEN()) {
if (_token != INVALID_TOKEN) {
wfassoc::WFSchemaDestroy(_token);
}
_token = other._token;
other._token = _INVALID_TOKEN();
other._token = INVALID_TOKEN;
}
return *this;
}
@@ -240,7 +235,7 @@ private:
*/
Token Release() noexcept {
Token t = _token;
_token = _INVALID_TOKEN();
_token = INVALID_TOKEN;
return t;
}
@@ -270,7 +265,7 @@ public:
* Releases resources associated with the icon resource.
*/
~IconRc() {
if (_token != _INVALID_TOKEN()) {
if (_token != INVALID_TOKEN) {
wfassoc::WFIconRcDestroy(_token);
}
}
@@ -281,15 +276,15 @@ public:
IconRc& operator=(const IconRc&) = delete;
/** @brief Move constructor */
IconRc(IconRc&& other) noexcept : _token(other._token) { other._token = _INVALID_TOKEN(); }
IconRc(IconRc&& other) noexcept : _token(other._token) { other._token = INVALID_TOKEN; }
/** @brief Move assignment operator */
IconRc& operator=(IconRc&& other) noexcept {
if (this != &other) {
if (_token != _INVALID_TOKEN()) {
if (_token != INVALID_TOKEN) {
wfassoc::WFIconRcDestroy(_token);
}
_token = other._token;
other._token = _INVALID_TOKEN();
other._token = INVALID_TOKEN;
}
return *this;
}
@@ -334,7 +329,7 @@ public:
* Releases resources associated with the extension status.
*/
~ExtStatus() {
if (_token != _INVALID_TOKEN()) {
if (_token != INVALID_TOKEN) {
wfassoc::WFExtStatusDestroy(_token);
}
}
@@ -345,15 +340,15 @@ public:
ExtStatus& operator=(const ExtStatus&) = delete;
/** @brief Move constructor */
ExtStatus(ExtStatus&& other) noexcept : _token(other._token) { other._token = _INVALID_TOKEN(); }
ExtStatus(ExtStatus&& other) noexcept : _token(other._token) { other._token = INVALID_TOKEN; }
/** @brief Move assignment operator */
ExtStatus& operator=(ExtStatus&& other) noexcept {
if (this != &other) {
if (_token != _INVALID_TOKEN()) {
if (_token != INVALID_TOKEN) {
wfassoc::WFExtStatusDestroy(_token);
}
_token = other._token;
other._token = _INVALID_TOKEN();
other._token = INVALID_TOKEN;
}
return *this;
}
@@ -415,7 +410,7 @@ public:
* Releases resources associated with the self extension status.
*/
~SelfExtStatus() {
if (_token != _INVALID_TOKEN()) {
if (_token != INVALID_TOKEN) {
wfassoc::WFSelfExtStatusDestroy(_token);
}
}
@@ -426,15 +421,15 @@ public:
SelfExtStatus& operator=(const SelfExtStatus&) = delete;
/** @brief Move constructor */
SelfExtStatus(SelfExtStatus&& other) noexcept : _token(other._token) { other._token = _INVALID_TOKEN(); }
SelfExtStatus(SelfExtStatus&& other) noexcept : _token(other._token) { other._token = INVALID_TOKEN; }
/** @brief Move assignment operator */
SelfExtStatus& operator=(SelfExtStatus&& other) noexcept {
if (this != &other) {
if (_token != _INVALID_TOKEN()) {
if (_token != INVALID_TOKEN) {
wfassoc::WFSelfExtStatusDestroy(_token);
}
_token = other._token;
other._token = _INVALID_TOKEN();
other._token = INVALID_TOKEN;
}
return *this;
}
@@ -525,7 +520,7 @@ public:
* Releases resources associated with the Program.
*/
~Program() {
if (_token != _INVALID_TOKEN()) {
if (_token != INVALID_TOKEN) {
wfassoc::WFProgramDestroy(_token);
}
}
@@ -536,15 +531,15 @@ public:
Program& operator=(const Program&) = delete;
/** @brief Move constructor */
Program(Program&& other) noexcept : _token(other._token) { other._token = _INVALID_TOKEN(); }
Program(Program&& other) noexcept : _token(other._token) { other._token = INVALID_TOKEN; }
/** @brief Move assignment operator */
Program& operator=(Program&& other) noexcept {
if (this != &other) {
if (_token != _INVALID_TOKEN()) {
if (_token != INVALID_TOKEN) {
wfassoc::WFProgramDestroy(_token);
}
_token = other._token;
other._token = _INVALID_TOKEN();
other._token = INVALID_TOKEN;
}
return *this;
}
@@ -576,7 +571,7 @@ public:
* @throws std::runtime_error if the operation fails
*/
IconRc ResolveIcon() {
Token token = _INVALID_TOKEN();
Token token = INVALID_TOKEN;
_Check(wfassoc::WFProgramResolveIcon(_token, &token));
return IconRc(token);
}
@@ -614,7 +609,7 @@ public:
* @throws std::runtime_error if the operation fails
*/
SelfExtStatus ResolveExt(size_t index) {
Token token = _INVALID_TOKEN();
Token token = INVALID_TOKEN;
_Check(wfassoc::WFProgramResolveExt(_token, index, &token));
return SelfExtStatus(token);
}
@@ -676,9 +671,9 @@ public:
* @throws std::runtime_error if the operation fails
*/
std::optional<ExtStatus> QueryExt(View view, size_t index) {
Token token = _INVALID_TOKEN();
Token token = INVALID_TOKEN;
_Check(wfassoc::WFProgramQueryExt(_token, view, index, &token));
if (token == _INVALID_TOKEN()) {
if (token == INVALID_TOKEN) {
return std::nullopt;
}
return ExtStatus(token);