### Example Search Queries Source: https://docs.rs/keylight/latest/keylight/error/type.Result.html?search= Common search patterns for finding types and functions in the documentation. ```text std::vec u32 -> bool Option, (T -> U) -> Option ``` -------------------------------- ### Setting Application Version Source: https://docs.rs/keylight/latest/src/keylight/config.rs.html?search= Example of how to set the application version using the builder pattern. ```rust # use keylight::KeylightConfig; let cfg = KeylightConfig::builder("tenant", "product", "sdk_live_…") .app_version(env!("CARGO_PKG_VERSION")) .build(); ``` -------------------------------- ### Manage Trial Periods and Device State Source: https://docs.rs/keylight/latest/src/keylight/client.rs.html?search=std%3A%3Avec Methods for starting and checking trial status, as well as managing free tier instance IDs. ```rust pub fn start_trial(&self) -> Result<()> { if self.store.get_string(account::TRIAL_START).is_none() { self.store .set_string(account::TRIAL_START, &Self::now().to_string())?; } if self .store .get_string(account::FREE_TIER_INSTANCE_ID) .is_none() { self.store.set_string( account::FREE_TIER_INSTANCE_ID, &crate::store::device::uuid_v4_pub(), )?; } Ok(()) } pub fn check_trial(&self) -> TrialStatus { let start = match self.store.get_i64(account::TRIAL_START) { Some(v) => v, None => return TrialStatus::NotStarted, }; let days_elapsed = (Self::now() - start) / 86400; let days_left = self.config.trial_duration_days as i64 - days_elapsed; if days_left > 0 { TrialStatus::Active { days_left } } else { TrialStatus::Expired } } pub fn free_tier_instance_id(&self) -> Result { if let Some(id) = self.store.get_string(account::FREE_TIER_INSTANCE_ID) { return Ok(id); } let id = crate::store::device::uuid_v4_pub(); self.store.set_string(account::FREE_TIER_INSTANCE_ID, &id)?; Ok(id) } ``` -------------------------------- ### Define TRIAL_START constant Source: https://docs.rs/keylight/latest/keylight/store/account/constant.TRIAL_START.html Represents the trial start identifier as a string slice constant. ```rust pub const TRIAL_START: &str = "trial_start"; ``` -------------------------------- ### Manage Trial Period Source: https://docs.rs/keylight/latest/src/keylight/client.rs.html Methods to initialize and check the status of a trial period based on stored start times. ```rust pub fn start_trial(&self) -> Result<()> { if self.store.get_string(account::TRIAL_START).is_none() { self.store .set_string(account::TRIAL_START, &Self::now().to_string())?; } if self .store .get_string(account::FREE_TIER_INSTANCE_ID) .is_none() { self.store.set_string( account::FREE_TIER_INSTANCE_ID, &crate::store::device::uuid_v4_pub(), )?; } Ok(()) } pub fn check_trial(&self) -> TrialStatus { let start = match self.store.get_i64(account::TRIAL_START) { Some(v) => v, None => return TrialStatus::NotStarted, }; let days_elapsed = (Self::now() - start) / 86400; let days_left = self.config.trial_duration_days as i64 - days_elapsed; if days_left > 0 { TrialStatus::Active { days_left } } else { TrialStatus::Expired } } ``` -------------------------------- ### Keylight::start_trial Source: https://docs.rs/keylight/latest/keylight/client/struct.Keylight.html?search=std%3A%3Avec Initiates a trial period. ```APIDOC ## pub fn start_trial(&self) -> Result<()> ### Description Starts a trial period for the application. ``` -------------------------------- ### get Source: https://docs.rs/keylight/latest/keylight/http/trait.Transport.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Sends a GET request to the specified URL. ```APIDOC ## fn get(&self, url: &str, headers: &[(String, String)]) -> TransportOutcome ### Description Sends a GET request to the specified URL with provided headers. ### Parameters - **url** (&str) - Required - The target URL. - **headers** (&[(String, String)]) - Required - A slice of key-value pairs representing HTTP headers. ``` -------------------------------- ### Keylight Client Configuration Methods Source: https://docs.rs/keylight/latest/src/keylight/client.rs.html Fluent methods for configuring event handlers and device identity. ```rust /// Register a handler invoked when the resolved license state crosses a lifecycle transition. pub fn with_event_handler( mut self, handler: impl Fn(crate::state::LicenseLifecycleEvent) + Send + Sync + 'static, ) -> Self { self.on_event = Some(Box::new(handler)); self } /// Override the device identity used for `machine_hash` on the keyless heartbeat /// (tests, alternate platforms). Defaults to [`SystemDeviceIdentity`]. pub fn with_device(mut self, device: Arc) -> Self { self.device = device; self } ``` -------------------------------- ### get Source: https://docs.rs/keylight/latest/keylight/http/ureq_transport/struct.UreqTransport.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Sends a GET request to the specified URL. ```APIDOC ## fn get(&self, url: &str, headers: &[(String, String)]) -> TransportOutcome ### Description Sends a GET request to the provided URL with custom headers. ### Parameters - **url** (&str) - The target URL for the GET request. - **headers** (&[(String, String)]) - A slice of key-value pairs representing HTTP headers. ### Returns - **TransportOutcome** - The result of the transport operation. ``` -------------------------------- ### Keylight Client Initialization and Configuration Source: https://docs.rs/keylight/latest/src/keylight/client.rs.html?search=u32+-%3E+bool Methods for constructing the Keylight client and configuring event handlers or device identities. ```rust impl Keylight { /// Construct with the default encrypted-file store + ureq transport. pub fn new(config: KeylightConfig) -> Result { let ns = format!("{}-{}", config.tenant_id, config.product_id); Ok(Self { store: Arc::new(EncryptedFileStore::new(&ns)?), transport: Arc::new(UreqTransport::default()), device: Arc::new(SystemDeviceIdentity), config, on_event: None, }) } /// Construct with custom store + transport (tests, alternate backends). pub fn with_parts( config: KeylightConfig, store: Arc, transport: Arc, ) -> Self { Self { config, store, transport, device: Arc::new(SystemDeviceIdentity), on_event: None, } } /// Register a handler invoked when the resolved license state crosses a lifecycle transition. pub fn with_event_handler( mut self, handler: impl Fn(crate::state::LicenseLifecycleEvent) + Send + Sync + 'static, ) -> Self { self.on_event = Some(Box::new(handler)); self } /// Override the device identity used for `machine_hash` on the keyless heartbeat /// (tests, alternate platforms). Defaults to [`SystemDeviceIdentity`]. pub fn with_device(mut self, device: Arc) -> Self { self.device = device; self } ``` -------------------------------- ### get Source: https://docs.rs/keylight/latest/keylight/http/trait.Transport.html?search=std%3A%3Avec Performs a blocking HTTP GET request. ```APIDOC ## fn get(&self, url: &str, headers: &[(String, String)]) -> TransportOutcome ### Description Sends a blocking HTTP GET request to the specified URL with the provided headers. ### Parameters - **url** (&str) - The target URL. - **headers** (&[(String, String)]) - A slice of key-value pairs representing HTTP headers. ### Returns - **TransportOutcome** - The result of the transport operation. ``` -------------------------------- ### Transport::get Source: https://docs.rs/keylight/latest/src/keylight/http/mod.rs.html?search= Executes a blocking GET request. ```APIDOC ## GET ### Description Sends a blocking HTTP GET request to the specified URL. ### Method GET ### Parameters - **url** (&str) - Required - The target URL. - **headers** (&[(String, String)]) - Required - A slice of header key-value pairs. ### Returns - **TransportOutcome** - The result of the transport attempt, which can be a successful response, a transient failure, a terminal failure, or a timeout. ``` -------------------------------- ### KeylightConfig Implementation Methods Source: https://docs.rs/keylight/latest/keylight/config/struct.KeylightConfig.html?search=std%3A%3Avec Methods for initializing the configuration via a builder pattern and performing client-side key validation. ```rust pub fn builder( tenant_id: impl Into, product_id: impl Into, sdk_key: impl Into, ) -> KeylightConfigBuilder ``` ```rust pub fn validate_key_format(&self, key: &str) -> bool ``` -------------------------------- ### Keylight Client Initialization Source: https://docs.rs/keylight/latest/src/keylight/client.rs.html Constructors for the Keylight client, including default and custom configurations. ```rust /// Construct with the default encrypted-file store + ureq transport. pub fn new(config: KeylightConfig) -> Result { let ns = format!("{}-{}", config.tenant_id, config.product_id); Ok(Self { store: Arc::new(EncryptedFileStore::new(&ns)?), transport: Arc::new(UreqTransport::default()), device: Arc::new(SystemDeviceIdentity), config, on_event: None, }) } /// Construct with custom store + transport (tests, alternate backends). pub fn with_parts( config: KeylightConfig, store: Arc, transport: Arc, ) -> Self { Self { config, store, transport, device: Arc::new(SystemDeviceIdentity), on_event: None, } } ``` -------------------------------- ### UreqTransport::get Source: https://docs.rs/keylight/latest/keylight/http/ureq_transport/struct.UreqTransport.html Sends an HTTP GET request to the specified URL. ```APIDOC ## fn get(&self, url: &str, headers: &[(String, String)]) -> TransportOutcome ### Description Sends an HTTP GET request to the provided URL with custom headers. ### Parameters - **url** (&str) - The target URL. - **headers** (&[(String, String)]) - A slice of key-value pairs representing HTTP headers. ### Returns - **TransportOutcome** - The result of the transport operation. ``` -------------------------------- ### Keylight::new Source: https://docs.rs/keylight/latest/keylight/client/struct.Keylight.html?search=u32+-%3E+bool Constructs a new Keylight instance with the default encrypted-file store and ureq transport. ```APIDOC ## pub fn new(config: KeylightConfig) -> Result ### Description Constructs a new Keylight instance using the default encrypted-file store and ureq transport for network communication. ### Parameters - **config** (KeylightConfig) - Required - The configuration object for the Keylight client. ``` -------------------------------- ### Keylight Client Implementation Source: https://docs.rs/keylight/latest/src/keylight/client.rs.html?search= The core Keylight client structure and its associated methods for initialization and configuration. ```rust 1//! The [`Keylight`] client: activation, validation, deactivation, offline state 2//! resolution, trials, the keyless beacon, refresh timing, and lifecycle events. 3 4use crate::clock::{clock_manipulated, clock_rolled_back}; 5use crate::http::retry::{MAX_ATTEMPTS, RetryDecision, backoff_ms, clamp_sleep_ms, decide}; 6use crate::http::{Transport, TransportOutcome, ureq_transport::UreqTransport}; 7use crate::state::{KeylessState, LicenseState, TrialStatus, resolve_state}; 8use crate::store::device::{DeviceIdentity, SystemDeviceIdentity}; 9use crate::store::{LicenseStore, account, encrypted_file::EncryptedFileStore}; 10use crate::{KeylightConfig, KeylightError, Lease, Result, telemetry, verify_lease}; 11use serde::Deserialize; 12use std::sync::Arc; 13 14#[derive(Debug, Clone)] 15pub struct ActivationResult { 16 pub activated: bool, 17 pub instance_id: Option, 18 pub lease: Option, 19 pub license_expires_at: Option, 20 pub error: Option, 21} 22#[derive(Debug, Clone)] 23pub struct ValidationResult { 24 pub valid: bool, 25 pub lease: Option, 26 pub license_expires_at: Option, 27 pub error: Option, 28} 29 30#[derive(Deserialize)] 31struct ActivateResp { 32 activated: bool, 33 instance_id: Option, 34 license_expires_at: Option, 35 lease: Option, 36 error: Option, 37} 38#[derive(Deserialize)] 39struct ValidateResp { 40 /// Defaults to `false` when absent: the real worker's revoked / 41 /// instance-not-active response is `{"error": "..."}` with no `valid` 42 /// field at all, and that must be treated as a definitive rejection, 43 /// not fail to deserialize. 44 #[serde(default)] 45 valid: bool, 46 license_expires_at: Option, 47 lease: Option, 48 error: Option, 49} 50#[derive(Deserialize)] 51struct ErrorResp { 52 error: Option, 53} 54 55pub struct Keylight { 56 config: KeylightConfig, 57 store: Arc, 58 transport: Arc, 59 device: Arc, 60 on_event: Option>, 61} 62 63impl Keylight { 64 /// Construct with the default encrypted-file store + ureq transport. 65 pub fn new(config: KeylightConfig) -> Result { 66 let ns = format!("{}-{}", config.tenant_id, config.product_id); 67 Ok(Self { 68 store: Arc::new(EncryptedFileStore::new(&ns)?), 69 transport: Arc::new(UreqTransport::default()), 70 device: Arc::new(SystemDeviceIdentity), 71 config, 72 on_event: None, 73 }) 74 } 75 /// Construct with custom store + transport (tests, alternate backends). 76 pub fn with_parts( 77 config: KeylightConfig, 78 store: Arc, 79 transport: Arc, 80 ) -> Self { 81 Self { 82 config, 83 store, 84 transport, 85 device: Arc::new(SystemDeviceIdentity), 86 on_event: None, 87 } 88 } 89 /// Register a handler invoked when the resolved license state crosses a lifecycle transition. 90 pub fn with_event_handler( 91 mut self, 92 handler: impl Fn(crate::state::LicenseLifecycleEvent) + Send + Sync + 'static, 93 ) -> Self { 94 self.on_event = Some(Box::new(handler)); 95 self 96 } 97 /// Override the device identity used for `machine_hash` on the keyless heartbeat 98 /// (tests, alternate platforms). Defaults to [`SystemDeviceIdentity`]. 99 pub fn with_device(mut self, device: Arc) -> Self { 100 self.device = device; 101 self 102 } 103 104 fn request_id() -> String { 105 use rand::Rng; 106 let n: u32 = rand::thread_rng().r#gen(); 107 format!("{n:08x}") 108 } 109 fn headers(&self) -> Vec<(String, String)> { 110 let mut h = vec![ 111 ("Content-Type".into(), "application/json".into()), 112 ("X-Keylight-Request-Id".into(), Self::request_id()), 113 ]; 114 if !self.config.sdk_key.is_empty() { 115 h.push(("X-Keylight-SDK-Key".into(), self.config.sdk_key.clone())); 116 } 117 h 118 } 119 fn body_with_telemetry(&self, mut map: serde_json::Map) -> String { 120 telemetry::apply(&mut map, self.config.app_version.as_deref()); 121 serde_json::Value::Object(map).to_string() 122 } 123 124 /// POST with retry/backoff. `decodable_4xx` lets a caller opt a 4xx body in (validate's 422). 125 fn post(&self, path: &str, body: &str, decodable_4xx: &[u16]) -> Result<(u16, String)> { 126 let url = self.api_url(path); 127 let headers = self.headers(); 128 let mut attempt = 0u32; ``` -------------------------------- ### KeylightConfig::builder Source: https://docs.rs/keylight/latest/keylight/config/struct.KeylightConfig.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Initializes a new KeylightConfigBuilder instance with the required authentication parameters. ```APIDOC ## pub fn builder(tenant_id: impl Into, product_id: impl Into, sdk_key: impl Into) -> KeylightConfigBuilder ### Description Creates a new builder instance for constructing a KeylightConfig object. This is the primary entry point for configuring the SDK. ### Parameters - **tenant_id** (impl Into) - Required - The tenant identifier. - **product_id** (impl Into) - Required - The product identifier. - **sdk_key** (impl Into) - Required - The SDK key used for authentication. ``` -------------------------------- ### Define the Transport trait Source: https://docs.rs/keylight/latest/keylight/http/trait.Transport.html The trait requires implementations for post_json and get methods, and must be Send and Sync. ```rust pub trait Transport: Send + Sync { // Required methods fn post_json( &self, url: &str, headers: &[(String, String)], body: &str, ) -> TransportOutcome; fn get(&self, url: &str, headers: &[(String, String)]) -> TransportOutcome; } ``` -------------------------------- ### Initialize and Activate Keylight Source: https://docs.rs/keylight/latest/index.html Configures the Keylight client, fetches the trusted keyset for offline verification, and performs license activation. ```rust use keylight::{Keylight, KeylightConfig}; // Build a config and fetch the tenant's trusted Ed25519 keyset so leases can be // verified offline (or pin keys with `.trusted_key(kid, pub_b64)`). let mut cfg = KeylightConfig::builder("your-tenant", "your-product", "sdk_live_…") .max_offline_days(7) .build(); if let Some((_, keys)) = keylight::keyset::fetch_keyset( &keylight::http::ureq_transport::UreqTransport::default(), &cfg.base_url, &cfg.tenant_id, ) { cfg.trusted_keys.extend(keys); } let kl = Keylight::new(cfg)?; let result = kl.activate("USER-LICENSE-KEY")?; if result.activated && kl.has_entitlement("pro") { println!("Pro features unlocked"); } ``` -------------------------------- ### Keylight::activate Source: https://docs.rs/keylight/latest/src/keylight/lib.rs.html Exchanges a license key for a signed lease and performs initial activation. ```APIDOC ## Keylight::activate ### Description Exchanges a provided license key for a signed `v3` Lease. The lease is verified against the trusted keyset before being persisted. ### Signature `pub fn activate(&self, key: &str) -> Result` ### Parameters - **key** (&str) - Required - The license key string to activate. ``` -------------------------------- ### Chain fallible operations with and_then Source: https://docs.rs/keylight/latest/keylight/error/type.Result.html?search=std%3A%3Avec Use and_then to chain operations that return a Result. The second example demonstrates file system metadata retrieval. ```rust assert_eq!(Ok(2).and_then(sq_then_to_string), Ok(4.to_string())); assert_eq!(Ok(1_000_000).and_then(sq_then_to_string), Err("overflowed")); assert_eq!(Err("not a number").and_then(sq_then_to_string), Err("not a number")); ``` ```rust use std::{io::ErrorKind, path::Path}; // Note: on Windows "/" maps to "C:\" let root_modified_time = Path::new("/").metadata().and_then(|md| md.modified()); assert!(root_modified_time.is_ok()); let should_fail = Path::new("/bad/path").metadata().and_then(|md| md.modified()); assert!(should_fail.is_err()); assert_eq!(should_fail.unwrap_err().kind(), ErrorKind::NotFound); ``` -------------------------------- ### Verify KeylightConfig Builder Defaults Source: https://docs.rs/keylight/latest/src/keylight/config.rs.html?search= Tests that the builder initializes with correct default values for base URL, trial duration, and free tier status. ```rust #[test] fn builder_defaults() { let c = KeylightConfig::builder("t", "p", "sdk_live_test").build(); assert_eq!(c.base_url, "https://api.keylight.dev"); assert_eq!(c.trial_duration_days, 14); assert!(!c.free_tier_enabled); assert_eq!(c.sdk_key, "sdk_live_test"); } ``` -------------------------------- ### KeylightConfig::builder Source: https://docs.rs/keylight/latest/keylight/config/struct.KeylightConfig.html?search=std%3A%3Avec Creates a new KeylightConfigBuilder instance to initialize the configuration. ```APIDOC ## pub fn builder(tenant_id: impl Into, product_id: impl Into, sdk_key: impl Into) -> KeylightConfigBuilder ### Description Initializes a new builder for the KeylightConfig struct using the required tenant, product, and SDK identifiers. ### Parameters - **tenant_id** (impl Into) - Required - The tenant-issued identifier. - **product_id** (impl Into) - Required - The product-specific identifier. - **sdk_key** (impl Into) - Required - The SDK key used for authentication. ``` -------------------------------- ### Keylight::with_parts Source: https://docs.rs/keylight/latest/src/keylight/client.rs.html?search=u32+-%3E+bool Constructs a Keylight client with custom storage and transport implementations, useful for testing or alternate backends. ```APIDOC ## Keylight::with_parts ### Description Constructs a Keylight client with custom storage and transport implementations, useful for testing or alternate backends. ### Parameters - **config** (KeylightConfig) - Required - The configuration object. - **store** (Arc) - Required - Custom license storage implementation. - **transport** (Arc) - Required - Custom transport implementation. ``` -------------------------------- ### KeylightConfig Builder Method Source: https://docs.rs/keylight/latest/keylight/config/struct.KeylightConfig.html?search=u32+-%3E+bool Constructs a new KeylightConfigBuilder instance. ```rust pub fn builder( tenant_id: impl Into, product_id: impl Into, sdk_key: impl Into, ) -> KeylightConfigBuilder ``` -------------------------------- ### Keylight::activate Source: https://docs.rs/keylight Exchanges a license key for a signed v3 Lease, which is then verified against a trusted keyset. ```APIDOC ## Keylight::activate(license_key: &str) -> Result ### Description Activates a license by exchanging the provided license key for a signed v3 Lease. The lease is verified using the trusted keyset before being persisted. ### Parameters - **license_key** (&str) - Required - The license key string to activate. ### Returns - **ActivationResult** - Contains the activation status and entitlement information. ``` -------------------------------- ### KeylightConfigBuilder Methods Source: https://docs.rs/keylight/latest/keylight/config/struct.KeylightConfigBuilder.html?search=std%3A%3Avec Methods available on the KeylightConfigBuilder to configure the SDK instance. ```APIDOC ## KeylightConfigBuilder Methods ### trusted_key(kid: impl Into, pub_b64: impl Into) -> Self Sets the trusted key for the configuration. ### max_offline_days(d: u32) -> Self Sets the maximum number of days the SDK can operate offline. ### trial_duration_days(d: u32) -> Self Sets the duration of the trial period in days. ### free_tier_enabled(v: bool) -> Self Enables or disables the free tier. ### app_version(v: impl Into) -> Self Sets the application version. This is required to report the app version in the dashboard. ### base_url(v: impl Into) -> Self Sets the base URL for the Keylight service. ### key_prefix(v: impl Into) -> Self Sets the key prefix for the configuration. ### build() -> KeylightConfig Consumes the builder and returns a configured KeylightConfig instance. ``` -------------------------------- ### KeylightConfigBuilder Methods Source: https://docs.rs/keylight/latest/keylight/config/struct.KeylightConfigBuilder.html?search= Methods available on the KeylightConfigBuilder to configure the SDK instance. ```APIDOC ## pub fn app_version(self, v: impl Into) -> Self ### Description Sets the application's version to be reported alongside every request. This is required to see the app version in the dashboard. ### Parameters - **v** (impl Into) - Required - The version string of the application. ## pub fn trusted_key(self, kid: impl Into, pub_b64: impl Into) -> Self ### Description Configures a trusted key for the SDK. ### Parameters - **kid** (impl Into) - Required - The key ID. - **pub_b64** (impl Into) - Required - The public key in base64 format. ## pub fn max_offline_days(self, d: u32) -> Self ### Description Sets the maximum number of days the SDK can operate offline. ### Parameters - **d** (u32) - Required - Number of days. ## pub fn trial_duration_days(self, d: u32) -> Self ### Description Sets the duration of the trial period in days. ### Parameters - **d** (u32) - Required - Number of days. ## pub fn free_tier_enabled(self, v: bool) -> Self ### Description Enables or disables the free tier functionality. ### Parameters - **v** (bool) - Required - Boolean flag. ## pub fn base_url(self, v: impl Into) -> Self ### Description Sets the base URL for the Keylight service. ### Parameters - **v** (impl Into) - Required - The base URL string. ## pub fn key_prefix(self, v: impl Into) -> Self ### Description Sets the prefix for keys used by the SDK. ### Parameters - **v** (impl Into) - Required - The prefix string. ## pub fn build(self) -> KeylightConfig ### Description Finalizes the configuration and returns a KeylightConfig instance. ``` -------------------------------- ### KeylightConfigBuilder Methods Source: https://docs.rs/keylight/latest/keylight/config/struct.KeylightConfigBuilder.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Methods available on the KeylightConfigBuilder to configure the SDK instance. ```APIDOC ## KeylightConfigBuilder Methods ### pub fn trusted_key(self, kid: impl Into, pub_b64: impl Into) -> Self Sets a trusted key for the configuration. ### pub fn max_offline_days(self, d: u32) -> Self Sets the maximum number of days the SDK can operate offline. ### pub fn trial_duration_days(self, d: u32) -> Self Sets the duration of the trial period in days. ### pub fn free_tier_enabled(self, v: bool) -> Self Enables or disables the free tier functionality. ### pub fn app_version(self, v: impl Into) -> Self Sets the application version. This is required to report the version in the dashboard. ### pub fn base_url(self, v: impl Into) -> Self Sets the base URL for the Keylight service. ### pub fn key_prefix(self, v: impl Into) -> Self Sets the key prefix for the configuration. ### pub fn build(self) -> KeylightConfig Consumes the builder and returns a configured KeylightConfig instance. ``` -------------------------------- ### KeylightConfigBuilder Methods Source: https://docs.rs/keylight/latest/keylight/config/struct.KeylightConfigBuilder.html Methods available on the KeylightConfigBuilder to configure the SDK instance. ```APIDOC ## pub fn trusted_key(self, kid: impl Into, pub_b64: impl Into) -> Self ### Description Configures a trusted key for the SDK. ### Parameters - **kid** (impl Into) - The key identifier. - **pub_b64** (impl Into) - The public key in base64 format. ## pub fn max_offline_days(self, d: u32) -> Self ### Description Sets the maximum number of days the SDK can operate offline. ### Parameters - **d** (u32) - Number of days. ## pub fn trial_duration_days(self, d: u32) -> Self ### Description Sets the duration of the trial period in days. ### Parameters - **d** (u32) - Number of days. ## pub fn free_tier_enabled(self, v: bool) -> Self ### Description Enables or disables the free tier functionality. ### Parameters - **v** (bool) - Boolean flag. ## pub fn app_version(self, v: impl Into) -> Self ### Description Sets the application version reported by the SDK. This is required to see the app version in the dashboard. ### Parameters - **v** (impl Into) - The version string. ## pub fn base_url(self, v: impl Into) -> Self ### Description Sets the base URL for the Keylight service. ### Parameters - **v** (impl Into) - The base URL string. ## pub fn key_prefix(self, v: impl Into) -> Self ### Description Sets the key prefix for the configuration. ### Parameters - **v** (impl Into) - The prefix string. ## pub fn build(self) -> KeylightConfig ### Description Consumes the builder and returns a configured KeylightConfig instance. ``` -------------------------------- ### fetch_keyset Source: https://docs.rs/keylight/latest/keylight/keyset/fn.fetch_keyset.html Fetches and parses the tenant keyset from the endpoint {base}/{tenant}/.well-known/keylight-keys. ```APIDOC ## fetch_keyset ### Description Fetches and parses the tenant keyset from the location defined by the base URL and tenant ID. ### Signature `pub fn fetch_keyset(transport: &dyn Transport, base_url: &str, tenant_id: &str) -> Option<(String, HashMap)>` ### Parameters - **transport** (&dyn Transport) - The transport mechanism used to perform the request. - **base_url** (&str) - The base URL for the keylight service. - **tenant_id** (&str) - The unique identifier for the tenant. ### Returns - **Option<(String, HashMap)>** - Returns an Option containing the keyset data if successful, or None if the fetch or parsing fails. ``` -------------------------------- ### KeylightConfigBuilder Methods Source: https://docs.rs/keylight/latest/keylight/config/struct.KeylightConfigBuilder.html?search=u32+-%3E+bool Methods available on the KeylightConfigBuilder for configuring the SDK instance. ```APIDOC ## KeylightConfigBuilder Methods ### trusted_key(kid: impl Into, pub_b64: impl Into) -> Self Sets the trusted key for the configuration. ### max_offline_days(d: u32) -> Self Sets the maximum number of days the SDK can operate offline. ### trial_duration_days(d: u32) -> Self Sets the duration of the trial period in days. ### free_tier_enabled(v: bool) -> Self Enables or disables the free tier. ### app_version(v: impl Into) -> Self Sets the application version. This is required to see the app version in the dashboard. ### base_url(v: impl Into) -> Self Sets the base URL for the Keylight service. ### key_prefix(v: impl Into) -> Self Sets the key prefix for the configuration. ### build() -> KeylightConfig Consumes the builder and returns a configured KeylightConfig instance. ``` -------------------------------- ### KeylightConfigBuilder Source: https://docs.rs/keylight/latest/src/keylight/config.rs.html?search=u32+-%3E+bool A builder pattern implementation for constructing a KeylightConfig instance. ```APIDOC ## KeylightConfig::builder(tenant_id, product_id, sdk_key) ### Description Initializes a new KeylightConfigBuilder with the required identification fields. ### Methods - **trusted_key(kid, pub_b64)**: Adds a trusted key for signature verification. - **max_offline_days(d)**: Sets the maximum number of days the license can run offline. - **trial_duration_days(d)**: Sets the duration of the trial period in days. - **free_tier_enabled(v)**: Enables or disables the free tier. - **app_version(v)**: Sets the application version string to be reported with requests. - **base_url(v)**: Sets the base URL for the Keylight API. - **key_prefix(v)**: Sets a required prefix for validated keys. - **build()**: Consumes the builder and returns a KeylightConfig instance. ``` -------------------------------- ### Keylight::activate Source: https://docs.rs/keylight/latest/index.html Exchanges a license key for a signed v3 Lease. The lease is verified against the trusted keyset before being persisted. ```APIDOC ## Keylight::activate ### Description Exchanges a license key for a signed v3 Lease. The lease is Ed25519-verified against the trusted keyset before being persisted. ### Signature `pub fn activate(&self, key: &str) -> Result` ``` -------------------------------- ### Define KeylightConfig and Builder Source: https://docs.rs/keylight/latest/src/keylight/config.rs.html The core configuration structure and its builder implementation for initializing the Keylight SDK. ```rust //! [`KeylightConfig`] and its builder, including client-side key-format validation. use std::collections::HashMap; #[derive(Debug, Clone)] pub struct KeylightConfig { pub tenant_id: String, pub product_id: String, /// Tenant-issued SDK key (`sdk_live_…`) sent as `X-Keylight-SDK-Key` on every /// network call. The server requires it, so it is a required construction /// argument rather than an optional setter. pub sdk_key: String, pub trusted_keys: HashMap, // kid -> raw ed25519 pub (base64) /// Hard cap, in days, on how long a validated license may run without a /// successful server re-validation before `state()` denies it — enforced /// even against an otherwise signature-valid, unexpired cached lease. /// Defaults to `Some(15)`; set to `None` (via this field directly, or a /// literal `KeylightConfig { .. }`) to disable the cap entirely, e.g. for /// air-gapped consumers. pub max_offline_days: Option, pub trial_duration_days: u32, pub free_tier_enabled: bool, pub app_version: Option, pub base_url: String, // default https://api.keylight.dev pub key_prefix: Option, } impl KeylightConfig { pub fn builder( tenant_id: impl Into, product_id: impl Into, sdk_key: impl Into, ) -> KeylightConfigBuilder { KeylightConfigBuilder { tenant_id: tenant_id.into(), product_id: product_id.into(), sdk_key: sdk_key.into(), trusted_keys: HashMap::new(), max_offline_days: Some(15), trial_duration_days: 14, free_tier_enabled: false, app_version: None, base_url: "https://api.keylight.dev".into(), key_prefix: None, } } /// Client-side key format check (parity with Swift validateKeyFormat). pub fn validate_key_format(&self, key: &str) -> bool { let k = key.trim(); if k.is_empty() { return false; } if let Some(prefix) = &self.key_prefix { if !k.to_uppercase().starts_with(&prefix.to_uppercase()) { return false; } } k.chars().all(|c| c.is_ascii_alphanumeric() || c == '-') } } pub struct KeylightConfigBuilder { tenant_id: String, product_id: String, sdk_key: String, trusted_keys: HashMap, max_offline_days: Option, trial_duration_days: u32, free_tier_enabled: bool, app_version: Option, base_url: String, key_prefix: Option, } impl KeylightConfigBuilder { pub fn trusted_key(mut self, kid: impl Into, pub_b64: impl Into) -> Self { self.trusted_keys.insert(kid.into(), pub_b64.into()); self } pub fn max_offline_days(mut self, d: u32) -> Self { self.max_offline_days = Some(d); self } pub fn trial_duration_days(mut self, d: u32) -> Self { self.trial_duration_days = d; self } pub fn free_tier_enabled(mut self, v: bool) -> Self { self.free_tier_enabled = v; self } /// Report your application's version alongside every request, including the /// anonymous keyless/free-tier beacon. /// /// **You must call this to get an app version in the dashboard.** Unlike /// `sdk_version` and `platform` — which the SDK attaches automatically — the /// app version is unknown to the SDK and is omitted entirely unless you set /// it here. A typical value is your crate version: /// /// ```rust /// # use keylight::KeylightConfig; /// let cfg = KeylightConfig::builder("tenant", "product", "sdk_live_…") /// .app_version(env!("CARGO_PKG_VERSION")) /// .build(); /// ``` pub fn app_version(mut self, v: impl Into) -> Self { self.app_version = Some(v.into()); self } pub fn base_url(mut self, v: impl Into) -> Self { self.base_url = v.into(); self } pub fn key_prefix(mut self, v: impl Into) -> Self { self.key_prefix = Some(v.into()); self } pub fn build(self) -> KeylightConfig { KeylightConfig { tenant_id: self.tenant_id, product_id: self.product_id, sdk_key: self.sdk_key, trusted_keys: self.trusted_keys, max_offline_days: self.max_offline_days, trial_duration_days: self.trial_duration_days, ``` -------------------------------- ### pub fn platform() -> &'static str Source: https://docs.rs/keylight/latest/keylight/telemetry/fn.platform.html?search= Retrieves the compile-time platform string. ```APIDOC ## Function: platform ### Description Returns a static string representing the current platform, providing parity with the Swift currentPlatform() method. ### Signature `pub fn platform() -> &'static str` ``` -------------------------------- ### pub fn platform() -> &'static str Source: https://docs.rs/keylight/latest/keylight/telemetry/fn.platform.html?search=std%3A%3Avec Retrieves the compile-time platform string. ```APIDOC ## Function: platform ### Description Returns a compile-time platform string, maintaining parity with the Swift currentPlatform() function. ### Signature `pub fn platform() -> &'static str` ### Returns - **&'static str**: A static string slice representing the current platform. ``` -------------------------------- ### pub fn platform() -> &'static str Source: https://docs.rs/keylight/latest/keylight/telemetry/fn.platform.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Retrieves the compile-time platform string. ```APIDOC ## Function: platform ### Description Returns a compile-time platform string, maintaining parity with the Swift currentPlatform() function. ### Signature `pub fn platform() -> &'static str` ``` -------------------------------- ### fetch_keyset(transport: &dyn Transport, base_url: &str, tenant_id: &str) -> Option<(String, HashMap)> Source: https://docs.rs/keylight/latest/src/keylight/keyset.rs.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Fetches and parses a tenant's keyset from the remote service using the provided transport layer. ```APIDOC ## fetch_keyset ### Description Fetches the keyset from `{base_url}/{tenant_id}/.well-known/keylight-keys` and parses the response. ### Parameters - **transport** (&dyn Transport) - The transport implementation used to perform the HTTP GET request. - **base_url** (&str) - The base URL of the keylight service. - **tenant_id** (&str) - The identifier for the tenant. ### Returns - **Option<(String, HashMap)>** - Returns `Some` with the parsed keyset if the request is successful (HTTP 200), otherwise `None`. ``` -------------------------------- ### Keylight::activate Source: https://docs.rs/keylight/latest/keylight/client/struct.Keylight.html?search=u32+-%3E+bool Activates a license key. ```APIDOC ## pub fn activate(&self, key: &str) -> Result ### Description Activates the provided license key against the Keylight service. ### Parameters - **key** (str) - Required - The license key string to activate. ``` -------------------------------- ### Generate hosted upgrade URL Source: https://docs.rs/keylight/latest/src/keylight/client.rs.html?search= Constructs a formatted URL for the upgrade portal using the cached license key and tenant/product configuration. ```rust pub fn upgrade_url(&self) -> Option { let key = self.cached_license_key()?; Some(format!( "https://portal.keylight.dev/p/{}/upgrade/{}?key={}", self.config.tenant_id, self.config.product_id, urlencode(&key) )) } ``` -------------------------------- ### platform() Source: https://docs.rs/keylight/latest/keylight/telemetry/fn.platform.html Returns the compile-time platform string. ```APIDOC ## Function: platform() ### Description Returns a static string representing the current compile-time platform. This function maintains parity with the Swift currentPlatform() implementation. ### Signature `pub fn platform() -> &'static str` ``` -------------------------------- ### Keylight Client Data Structures Source: https://docs.rs/keylight/latest/src/keylight/client.rs.html Result structures for activation and validation operations. ```rust #[derive(Debug, Clone)] pub struct ActivationResult { pub activated: bool, pub instance_id: Option, pub lease: Option, pub license_expires_at: Option, pub error: Option, } #[derive(Debug, Clone)] pub struct ValidationResult { pub valid: bool, pub lease: Option, pub license_expires_at: Option, pub error: Option, } ``` -------------------------------- ### Keylight Internal Request Helpers Source: https://docs.rs/keylight/latest/src/keylight/client.rs.html?search=u32+-%3E+bool Utility methods for generating request IDs, headers, and handling HTTP communication. ```rust fn request_id() -> String { use rand::Rng; let n: u32 = rand::thread_rng().r#gen(); format!("{n:08x}") } fn headers(&self) -> Vec<(String, String)> { let mut h = vec![ ("Content-Type".into(), "application/json".into()), ("X-Keylight-Request-Id".into(), Self::request_id()), ]; if !self.config.sdk_key.is_empty() { h.push(("X-Keylight-SDK-Key".into(), self.config.sdk_key.clone())); } h } fn body_with_telemetry(&self, mut map: serde_json::Map) -> String { telemetry::apply(&mut map, self.config.app_version.as_deref()); serde_json::Value::Object(map).to_string() } /// POST with retry/backoff. `decodable_4xx` lets a caller opt a 4xx body in (validate's 422). fn post(&self, path: &str, body: &str, decodable_4xx: &[u16]) -> Result<(u16, String)> { let url = self.api_url(path); let headers = self.headers(); let mut attempt = 0u32; ``` -------------------------------- ### keylight::telemetry::platform Source: https://docs.rs/keylight/latest/keylight/telemetry/fn.platform.html?search=u32+-%3E+bool Returns the compile-time platform string. ```APIDOC ## Function: platform ### Description Returns a static string representing the current platform at compile-time. This provides parity with the Swift `currentPlatform()` method. ### Signature `pub fn platform() -> &'static str` ``` -------------------------------- ### Retrieve platform string Source: https://docs.rs/keylight/latest/keylight/telemetry/fn.platform.html Returns a static string indicating the current platform. This is determined at compile-time. ```rust pub fn platform() -> &'static str ``` -------------------------------- ### License Validation and Lifecycle Management Source: https://docs.rs/keylight/latest/src/keylight/client.rs.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Methods for checking license status on launch, generating upgrade URLs, and emitting lifecycle events based on state transitions. ```rust pub fn check_on_launch(&self) -> Result<()> { if self.has_stored_license() { let _ = self.validate()?; } Ok(()) } ``` ```rust pub fn upgrade_url(&self) -> Option { let key = self.cached_license_key()?; Some(format!( "https://portal.keylight.dev/p/{}/upgrade/{}?key={}", self.config.tenant_id, self.config.product_id, urlencode(&key) )) } ``` ```rust fn emit_lifecycle(&self, prev_state: &LicenseState, prev_expiry: Option) { let next_state = self.state(); // Option ordering: None < Some(_), so this is true exactly when a new // expiry exists and is later than the previous one (or there was none). let expiry_moved_later = self.store.get_i64(account::LICENSE_EXPIRES_AT) > prev_expiry; if let Some(ev) = crate::state::lifecycle_event(prev_state, &next_state, expiry_moved_later) { if let Some(h) = &self.on_event { h(ev); } } } ``` -------------------------------- ### EncryptedFileStore::new Source: https://docs.rs/keylight/latest/keylight/store/encrypted_file/struct.EncryptedFileStore.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Creates a new EncryptedFileStore instance using the default OS configuration directory, keyed to the current device. ```APIDOC ## pub fn new(namespace: &str) -> Result ### Description Initializes a new EncryptedFileStore using the default OS configuration directory, keyed to the current device. ### Parameters - **namespace** (&str) - Required - The namespace for the store. ``` -------------------------------- ### EncryptedFileStore::new Source: https://docs.rs/keylight/latest/keylight/store/encrypted_file/struct.EncryptedFileStore.html?search=u32+-%3E+bool Creates a new EncryptedFileStore instance using the default OS configuration directory, keyed to the current device. ```APIDOC ## pub fn new(namespace: &str) -> Result ### Description Creates a new EncryptedFileStore instance using the default OS configuration directory, keyed to the current device. ### Parameters - **namespace** (&str) - Required - The namespace for the store. ``` -------------------------------- ### platform() Source: https://docs.rs/keylight/latest/src/keylight/telemetry.rs.html?search=std%3A%3Avec Retrieves the current operating system platform string. ```APIDOC ## fn platform() ### Description Returns a string representing the current operating system platform (e.g., "macos", "linux", "windows"). ### Returns - **&'static str** - The platform identifier. ``` -------------------------------- ### Retrieve SDK version Source: https://docs.rs/keylight/latest/keylight/telemetry/fn.sdk_version.html Returns the static string representing the SDK version. ```rust pub fn sdk_version() -> &'static str ```