Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: allow closure as license callback #21

Merged
merged 1 commit into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@
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 @@ -96,14 +97,14 @@
#[repr(u32)]
pub enum PermissionFlags {
/// This flag indicates that the application does not require admin or root permissions to run
LA_USER = 1,

Check warning on line 100 in src/lib.rs

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

variant `LA_USER` should have an upper camel case name

Check warning on line 100 in src/lib.rs

View workflow job for this annotation

GitHub Actions / test (macos-latest)

variant `LA_USER` should have an upper camel case name

Check warning on line 100 in src/lib.rs

View workflow job for this annotation

GitHub Actions / test (macos-latest)

variant `LA_USER` should have an upper camel case name

Check warning on line 100 in src/lib.rs

View workflow job for this annotation

GitHub Actions / test (windows-latest)

variant `LA_USER` should have an upper camel case name
/// This flag indicates that the application must be run with admin or root permissions.
LA_SYSTEM = 2,

Check warning on line 102 in src/lib.rs

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

variant `LA_SYSTEM` should have an upper camel case name

Check warning on line 102 in src/lib.rs

View workflow job for this annotation

GitHub Actions / test (macos-latest)

variant `LA_SYSTEM` should have an upper camel case name

Check warning on line 102 in src/lib.rs

View workflow job for this annotation

GitHub Actions / test (macos-latest)

variant `LA_SYSTEM` should have an upper camel case name

Check warning on line 102 in src/lib.rs

View workflow job for this annotation

GitHub Actions / test (windows-latest)

variant `LA_SYSTEM` should have an upper camel case name
/// This flag is specifically designed for Windows and should be used for system-wide activations.
LA_ALL_USERS = 3,

Check warning on line 104 in src/lib.rs

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

variant `LA_ALL_USERS` should have an upper camel case name

Check warning on line 104 in src/lib.rs

View workflow job for this annotation

GitHub Actions / test (macos-latest)

variant `LA_ALL_USERS` should have an upper camel case name

Check warning on line 104 in src/lib.rs

View workflow job for this annotation

GitHub Actions / test (windows-latest)

variant `LA_ALL_USERS` should have an upper camel case name
/// This flag will store activation data in memory. Thus, requires re-activation on every start of
/// the application and should only be used in floating licenses.
LA_IN_MEMORY = 4,

Check warning on line 107 in src/lib.rs

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

variant `LA_IN_MEMORY` should have an upper camel case name

Check warning on line 107 in src/lib.rs

View workflow job for this annotation

GitHub Actions / test (macos-latest)

variant `LA_IN_MEMORY` should have an upper camel case name

Check warning on line 107 in src/lib.rs

View workflow job for this annotation

GitHub Actions / test (windows-latest)

variant `LA_IN_MEMORY` should have an upper camel case name
}

// --------------- Setter functions ------------------------
Expand Down Expand Up @@ -334,26 +335,28 @@
}
}

/// 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 @@
}
}

/// 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
Loading