diff --git a/native/craft-core/src/error.rs b/native/craft-core/src/error.rs new file mode 100644 index 0000000..69a72fc --- /dev/null +++ b/native/craft-core/src/error.rs @@ -0,0 +1,103 @@ +use crate::CraftResult; + +/// BitAnswer BIT_STATUS 错误码到结构化错误的精简映射。 +/// 完整 200+ 码请参考 bitanswer.h,此处映射文档中明确列出的高频码。 +#[derive(Debug, Clone, PartialEq)] +pub enum LicenseError { + Success, + NetworkError, + WrongHandle, + InvalidParameter, + ApplicationDataError, + LicenseExpired, + LicenseNotFound, + LicenseDisabled, + FeatureNotFound(u32), + FeatureExpired(u32), + FeatureTypeNotMatch(u32), + SnInvalid, + SnNotFound, + SnDisabled, + SnRevoked, + SnExpired, + CapacityExhausted, + ServerBusy, + ServerDown, + Timeout, + Unknown(u32), +} + +impl LicenseError { + /// 将 BitAnswer BIT_STATUS (u32) 映射为 LicenseError + pub fn from_bit_status(status: u32) -> Self { + match status { + 0x0000 => LicenseError::Success, + 0x0101 => LicenseError::NetworkError, + 0x0102 => LicenseError::WrongHandle, + 0x0103 => LicenseError::InvalidParameter, + 0x0105 => LicenseError::ApplicationDataError, + 0x0701 => LicenseError::LicenseExpired, + 0x0114 => LicenseError::LicenseNotFound, + 0x0705 => LicenseError::LicenseDisabled, + 0x0503 => LicenseError::FeatureNotFound(0), + 0x0509 => LicenseError::FeatureExpired(0), + 0x0504 => LicenseError::FeatureTypeNotMatch(0), + 0x011C => LicenseError::SnInvalid, + 0x0706 => LicenseError::SnNotFound, + // 继续保留对相关码的映射 + 0x0123 => LicenseError::SnRevoked, + 0x0107 => LicenseError::ServerBusy, + 0x0108 => LicenseError::ServerDown, + 0x0141 => LicenseError::Timeout, + 0x0712 => LicenseError::CapacityExhausted, + _ => LicenseError::Unknown(status), + } + } + + pub fn message(&self) -> &'static str { + match self { + LicenseError::Success => "ok", + LicenseError::NetworkError => "network error", + LicenseError::WrongHandle => "wrong handle", + LicenseError::InvalidParameter => "invalid parameter", + LicenseError::ApplicationDataError => "application data error", + LicenseError::LicenseExpired => "license expired", + LicenseError::LicenseNotFound => "license not found", + LicenseError::LicenseDisabled => "license disabled", + LicenseError::FeatureNotFound(_) => "feature not found", + LicenseError::FeatureExpired(_) => "feature expired", + LicenseError::FeatureTypeNotMatch(_) => "feature type not match", + LicenseError::SnInvalid => "sn invalid", + LicenseError::SnNotFound => "sn not found", + LicenseError::SnDisabled => "sn disabled", + LicenseError::SnRevoked => "sn revoked", + LicenseError::SnExpired => "sn expired", + LicenseError::CapacityExhausted => "capacity exhausted", + LicenseError::ServerBusy => "server busy", + LicenseError::ServerDown => "server down", + LicenseError::Timeout => "timeout", + LicenseError::Unknown(_) => "unknown error", + } + } + + pub fn is_success(&self) -> bool { + matches!(self, LicenseError::Success) + } +} + +/// 将 LicenseError 转为 C ABI 兼容的 CraftResult +pub fn to_craft_result(error: LicenseError) -> CraftResult { + if error.is_success() { + // 对于成功场景,返回一个最小的 CraftResult(message 指针为 NULL,调用方通过成功状态判断) + CraftResult { success: 1, message: std::ptr::null() } + } else { + // 使用堆分配的消息指针(调用方通过 craft_free_license_info 类似方式释放) + let msg = format!("{}\0", error.message()); + let msg_ptr = msg.as_ptr() as *const std::os::raw::c_char; + std::mem::forget(msg); // 内存由调用方管理 + CraftResult { + success: 0, + message: msg_ptr, + } + } +} diff --git a/native/craft-core/src/lib.rs b/native/craft-core/src/lib.rs index 7ba166f..6364877 100644 --- a/native/craft-core/src/lib.rs +++ b/native/craft-core/src/lib.rs @@ -10,6 +10,7 @@ mod activate; mod heartbeat; mod license; mod security; +mod error; pub struct CraftContext { dummy: i32,