Skip to content

Commit

Permalink
Merge pull request #21 from marcbull/improve-callback
Browse files Browse the repository at this point in the history
chore: allow closure as license callback
  • Loading branch information
ahmad-kemsan authored Sep 19, 2024
2 parents 1da08a4 + 6a737e9 commit 121176e
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 40 deletions.
40 changes: 17 additions & 23 deletions examples/license-activation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,6 @@ use std::io::{self, BufRead}; // for user input (pause)

use lexactivator::*;

pub type CallbackType = extern "C" fn(LexActivatorCode);

extern "C" fn license_callback(code: LexActivatorCode) {
match code {
LexActivatorCode::Status(status) => {
match status {
LexActivatorStatus::LA_OK => println!("License is active!"),
LexActivatorStatus::LA_EXPIRED => println!("License has expired!"),
LexActivatorStatus::LA_SUSPENDED => println!("License has been suspended!"),
LexActivatorStatus::LA_GRACE_PERIOD_OVER => println!("License grace period is over!"),
_ => println!("Unknown license status"),
}
}
LexActivatorCode::Error(error) => {
match error {
LexActivatorError::LA_E_ACTIVATION_NOT_FOUND => println!("The license activation was deleted on the server."),
_ => println!("Unknown error"),
}
}
}
}

fn main() {
let product_data: String = "Product.dat_content".to_string();
let product_id: String = "Product_id".to_string();
Expand Down Expand Up @@ -53,7 +31,23 @@ fn main() {
}
}
let callback_result: Result<(), LexActivatorError> =
lexactivator::set_license_callback(license_callback);
lexactivator::set_license_callback(|code| match code {
LexActivatorCode::Status(status) => match status {
LexActivatorStatus::LA_OK => println!("License is active!"),
LexActivatorStatus::LA_EXPIRED => println!("License has expired!"),
LexActivatorStatus::LA_SUSPENDED => println!("License has been suspended!"),
LexActivatorStatus::LA_GRACE_PERIOD_OVER => {
println!("License grace period is over!")
}
_ => println!("Unknown license status"),
},
LexActivatorCode::Error(error) => match error {
LexActivatorError::LA_E_ACTIVATION_NOT_FOUND => {
println!("The license activation was deleted on the server.")
}
_ => println!("Error: {}", error),
},
});
println!("SetLicenseCallback: {:?}", callback_result);

let validation_result: Result<LexActivatorStatus, LexActivatorError> =
Expand Down
44 changes: 27 additions & 17 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::ffi::*;
use serde::Deserialize;
use std::sync::{LazyLock, Mutex};

mod extern_functions;
use extern_functions::*;
Expand All @@ -10,16 +11,16 @@ pub use error_codes::*;
mod string_utils;
use string_utils::*;

static mut CALLBACK_FUNCTION: Option<CallbackType> = None;
type LicenseCallback = dyn Fn(LexActivatorCode) + Send + 'static;

pub type CallbackType = extern "C" fn(LexActivatorCode);
static CALLBACK_FUNCTION: LazyLock<Mutex<Option<Box<LicenseCallback>>>> =
LazyLock::new(|| Mutex::new(None));

extern "C" fn wrapper(code: i32) {
let callback_status = LexActivatorCode::from_i32(code);
unsafe {
if let Some(callback) = CALLBACK_FUNCTION {
callback(callback_status);
}
let callback = CALLBACK_FUNCTION.lock().unwrap();
if let Some(callback) = callback.as_ref() {
callback(callback_status);
}
}

Expand Down Expand Up @@ -334,26 +335,28 @@ pub fn set_license_user_credential(email: String, password: String) -> Result<()
}
}

/// Sets the license callback function.
///
/// Whenever the server sync occurs in a separate thread, and server returns the response,
/// license callback function gets invoked with the following status codes:
/// Sets the license closure callback.
///
/// Whenever the server sync occurs in a separate thread, and server returns the response,
/// license closure callback gets invoked with the following status codes:
/// LA_OK, LA_EXPIRED, LA_SUSPENDED, LA_E_REVOKED, LA_E_ACTIVATION_NOT_FOUND, LA_E_MACHINE_FINGERPRINT
/// LA_E_AUTHENTICATION_FAILED, LA_E_COUNTRY, LA_E_INET, LA_E_SERVER,LA_E_RATE_LIMIT, LA_E_IP,
/// LA_E_AUTHENTICATION_FAILED, LA_E_COUNTRY, LA_E_INET, LA_E_SERVER,LA_E_RATE_LIMIT, LA_E_IP,
/// LA_E_RELEASE_VERSION_NOT_ALLOWED, LA_E_RELEASE_VERSION_FORMAT
///
/// # Arguments
///
/// * `callback` - The callback function to be set.
/// * `closure` - The closure callback to be set e.g. |code| { println!("{:?}", code) }
///
/// # Returns
///
/// Returns `Ok(())` if the license callback is set successfully, If an error occurs, an `Err` containing the `LexActivatorError`is returned.
/// Returns `Ok(())` if the license closure callback is set successfully, If an error occurs, an `Err` containing the `LexActivatorError`is returned.
pub fn set_license_callback(callback: CallbackType) -> Result<(), LexActivatorError> {
unsafe {
CALLBACK_FUNCTION = Some(callback);
}
pub fn set_license_callback<F>(closure: F) -> Result<(), LexActivatorError>
where
F: Fn(LexActivatorCode) + Clone + Send + 'static,
{
let mut callback_function = CALLBACK_FUNCTION.lock().unwrap();
callback_function.replace(Box::new(closure));
let status: i32 = unsafe { SetLicenseCallback(wrapper) };

if status == 0 {
Expand All @@ -363,6 +366,13 @@ pub fn set_license_callback(callback: CallbackType) -> Result<(), LexActivatorEr
}
}

/// Unset the current license closure callback.
pub fn unset_license_callback() {
let mut callback_function = CALLBACK_FUNCTION.lock().unwrap();
*callback_function = None;
}

/// Sets the activation lease duration.
///
/// # Arguments
Expand Down

0 comments on commit 121176e

Please sign in to comment.