Skip to main content

tapsdk_pc/
error.rs

1//! Error types for TapTap PC SDK
2
3use thiserror::Error;
4
5/// Result type alias for TapSDK operations
6pub type Result<T> = std::result::Result<T, TapSdkError>;
7
8/// SDK initialization result
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum InitResult {
11    /// Initialization successful
12    Ok,
13    /// Generic failure
14    FailedGeneric,
15    /// TapTap platform not found
16    NoPlatform,
17    /// Not launched by TapTap platform
18    NotLaunchedByPlatform,
19    /// Platform version mismatch
20    PlatformVersionMismatch,
21    /// Unknown result code
22    Unknown(u32),
23}
24
25impl From<u32> for InitResult {
26    fn from(code: u32) -> Self {
27        match code {
28            0 => InitResult::Ok,
29            1 => InitResult::FailedGeneric,
30            2 => InitResult::NoPlatform,
31            3 => InitResult::NotLaunchedByPlatform,
32            4 => InitResult::PlatformVersionMismatch,
33            _ => InitResult::Unknown(code),
34        }
35    }
36}
37
38/// Authorization request result
39#[derive(Debug, Clone, Copy, PartialEq, Eq)]
40pub enum AuthorizeResult {
41    /// Unknown error
42    Unknown,
43    /// Authorization flow started successfully
44    Ok,
45    /// Failed to start authorization
46    Failed,
47    /// Authorization already in progress
48    InFlight,
49}
50
51impl From<u32> for AuthorizeResult {
52    fn from(code: u32) -> Self {
53        match code {
54            0 => AuthorizeResult::Unknown,
55            1 => AuthorizeResult::Ok,
56            2 => AuthorizeResult::Failed,
57            3 => AuthorizeResult::InFlight,
58            _ => AuthorizeResult::Unknown,
59        }
60    }
61}
62
63/// Cloud save operation result
64#[derive(Debug, Clone, Copy, PartialEq, Eq)]
65pub enum CloudSaveResult {
66    /// Request initiated successfully
67    Ok,
68    /// SDK not initialized
69    Uninitialized,
70    /// TapTap client not running
71    NoTapTapClient,
72    /// TapTap client outdated
73    TapTapClientOutdated,
74    /// Invalid argument
75    InvalidArgument,
76    /// SDK internal failure
77    SdkFailed,
78    /// Failed to read save file
79    FailedToReadSaveFile,
80    /// Save file too large (>10MB)
81    SaveFileTooLarge,
82    /// Failed to read cover file
83    FailedToReadCoverFile,
84    /// Cover file too large (>512KB)
85    CoverFileTooLarge,
86    /// Unknown result code
87    Unknown(u32),
88}
89
90impl From<u32> for CloudSaveResult {
91    fn from(code: u32) -> Self {
92        match code {
93            0 => CloudSaveResult::Ok,
94            1 => CloudSaveResult::Uninitialized,
95            2 => CloudSaveResult::NoTapTapClient,
96            3 => CloudSaveResult::TapTapClientOutdated,
97            4 => CloudSaveResult::InvalidArgument,
98            5 => CloudSaveResult::SdkFailed,
99            6 => CloudSaveResult::FailedToReadSaveFile,
100            7 => CloudSaveResult::SaveFileTooLarge,
101            8 => CloudSaveResult::FailedToReadCoverFile,
102            9 => CloudSaveResult::CoverFileTooLarge,
103            _ => CloudSaveResult::Unknown(code),
104        }
105    }
106}
107
108/// System state
109#[derive(Debug, Clone, Copy, PartialEq, Eq)]
110pub enum SystemState {
111    /// Unknown state
112    Unknown,
113    /// Platform is online
114    PlatformOnline,
115    /// Platform is offline
116    PlatformOffline,
117    /// Platform is shutting down
118    PlatformShutdown,
119}
120
121impl From<u32> for SystemState {
122    fn from(code: u32) -> Self {
123        match code {
124            0 => SystemState::Unknown,
125            1 => SystemState::PlatformOnline,
126            2 => SystemState::PlatformOffline,
127            3 => SystemState::PlatformShutdown,
128            _ => SystemState::Unknown,
129        }
130    }
131}
132
133/// Main error type for TapSDK operations
134#[derive(Debug, Error)]
135pub enum TapSdkError {
136    /// SDK initialization failed
137    #[error("SDK initialization failed: {result:?} - {message}")]
138    InitFailed { result: InitResult, message: String },
139
140    /// SDK not initialized
141    #[error("SDK not initialized")]
142    NotInitialized,
143
144    /// Authorization failed
145    #[error("Authorization failed: {0:?}")]
146    AuthorizeFailed(AuthorizeResult),
147
148    /// Cloud save operation failed to start
149    #[error("Cloud save request failed: {0:?}")]
150    CloudSaveRequestFailed(CloudSaveResult),
151
152    /// API error returned from the SDK
153    #[error("API error ({code}): {message}")]
154    ApiError { code: i64, message: String },
155
156    /// Invalid argument provided
157    #[error("Invalid argument: {0}")]
158    InvalidArgument(String),
159
160    /// Null pointer returned
161    #[error("Null pointer returned from SDK")]
162    NullPointer,
163
164    /// UTF-8 conversion error
165    #[error("UTF-8 conversion error: {0}")]
166    Utf8Error(#[from] std::str::Utf8Error),
167
168    /// String contains null byte
169    #[error("String contains null byte: {0}")]
170    NulError(#[from] std::ffi::NulError),
171}
172
173impl TapSdkError {
174    /// Create an API error from SDK error code and message
175    pub fn from_api_error(code: i64, message: impl Into<String>) -> Self {
176        TapSdkError::ApiError {
177            code,
178            message: message.into(),
179        }
180    }
181
182    /// Create an API error from raw SDK error pointer
183    ///
184    /// # Safety
185    /// The error pointer must be valid and point to a valid TapSDK_Error struct
186    pub unsafe fn from_raw_error(error: *const tapsdk_pc_sys::TapSDK_Error) -> Option<Self> {
187        if error.is_null() {
188            return None;
189        }
190
191        let err = &*error;
192        let message = if err.message.is_null() {
193            String::new()
194        } else {
195            std::ffi::CStr::from_ptr(err.message)
196                .to_string_lossy()
197                .into_owned()
198        };
199
200        Some(TapSdkError::ApiError {
201            code: err.code,
202            message,
203        })
204    }
205}
206
207/// Error code constants matching the C SDK
208pub mod error_code {
209    pub const SUCCESS: i64 = 0;
210    pub const UNKNOWN: i64 = 1;
211    pub const UNAUTHORIZED: i64 = 2;
212    pub const METHOD_NOT_ALLOWED: i64 = 3;
213    pub const UNIMPLEMENTED: i64 = 4;
214    pub const INVALID_ARGUMENTS: i64 = 5;
215    pub const FORBIDDEN: i64 = 6;
216    pub const USER_IS_DEACTIVATED: i64 = 7;
217    pub const INTERNAL_SERVER_ERROR: i64 = 8;
218    pub const INTERNAL_SDK_ERROR: i64 = 9;
219    pub const NETWORK_ERROR: i64 = 10;
220
221    // Cloud save specific errors (400000-499999)
222    pub const CLOUD_SAVE_INVALID_FILE_SIZE: i64 = 400000;
223    pub const CLOUD_SAVE_UPLOAD_RATE_LIMIT: i64 = 400001;
224    pub const CLOUD_SAVE_FILE_NOT_FOUND: i64 = 400002;
225    pub const CLOUD_SAVE_FILE_COUNT_LIMIT_PER_CLIENT: i64 = 400003;
226    pub const CLOUD_SAVE_STORAGE_SIZE_LIMIT_PER_CLIENT: i64 = 400004;
227    pub const CLOUD_SAVE_TOTAL_STORAGE_SIZE_LIMIT: i64 = 400005;
228    pub const CLOUD_SAVE_TIMEOUT: i64 = 400006;
229    pub const CLOUD_SAVE_CONCURRENT_CALL_DISALLOWED: i64 = 400007;
230    pub const CLOUD_SAVE_STORAGE_SERVER_ERROR: i64 = 400008;
231    pub const CLOUD_SAVE_INVALID_NAME: i64 = 400009;
232}