Skip to main content

lingxia_provider/
lib.rs

1use std::future::Future;
2use std::pin::Pin;
3
4/// Boxed future type for dyn compatibility.
5pub type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
6
7/// Error type for provider operations.
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub enum ProviderErrorCode {
10    InvalidRequest,
11    NotFound,
12    Network,
13    Timeout,
14    Server,
15    PermissionDenied,
16    Internal,
17}
18
19impl ProviderErrorCode {
20    pub const fn biz_code(self) -> u32 {
21        match self {
22            Self::InvalidRequest => 1002,
23            Self::NotFound => 1003,
24            Self::Network => 5001,
25            Self::Timeout => 5002,
26            Self::Server => 5003,
27            Self::PermissionDenied => 3000,
28            Self::Internal => 1005,
29        }
30    }
31
32    pub const fn as_str(self) -> &'static str {
33        match self {
34            Self::InvalidRequest => "invalid_request",
35            Self::NotFound => "not_found",
36            Self::Network => "network",
37            Self::Timeout => "timeout",
38            Self::Server => "server",
39            Self::PermissionDenied => "permission_denied",
40            Self::Internal => "internal",
41        }
42    }
43}
44
45#[derive(Debug, Clone)]
46pub struct ProviderError {
47    code: ProviderErrorCode,
48    detail: String,
49}
50
51impl ProviderError {
52    pub fn new(code: ProviderErrorCode, detail: impl Into<String>) -> Self {
53        Self {
54            code,
55            detail: detail.into(),
56        }
57    }
58
59    pub fn invalid_request(detail: impl Into<String>) -> Self {
60        Self::new(ProviderErrorCode::InvalidRequest, detail)
61    }
62
63    pub fn not_found(detail: impl Into<String>) -> Self {
64        Self::new(ProviderErrorCode::NotFound, detail)
65    }
66
67    pub fn network(detail: impl Into<String>) -> Self {
68        Self::new(ProviderErrorCode::Network, detail)
69    }
70
71    pub fn timeout(detail: impl Into<String>) -> Self {
72        Self::new(ProviderErrorCode::Timeout, detail)
73    }
74
75    pub fn server(detail: impl Into<String>) -> Self {
76        Self::new(ProviderErrorCode::Server, detail)
77    }
78
79    pub fn permission_denied(detail: impl Into<String>) -> Self {
80        Self::new(ProviderErrorCode::PermissionDenied, detail)
81    }
82
83    pub fn internal(detail: impl Into<String>) -> Self {
84        Self::new(ProviderErrorCode::Internal, detail)
85    }
86
87    pub const fn code(&self) -> ProviderErrorCode {
88        self.code
89    }
90
91    pub const fn biz_code(&self) -> u32 {
92        self.code.biz_code()
93    }
94
95    pub fn detail(&self) -> &str {
96        &self.detail
97    }
98}
99
100impl std::fmt::Display for ProviderError {
101    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
102        write!(f, "[{}] {}", self.code.as_str(), self.detail)
103    }
104}
105
106impl std::error::Error for ProviderError {}
107
108/// Error type for fingerprint operations.
109#[derive(Debug, Clone, Copy, PartialEq, Eq)]
110pub enum FingerprintError {
111    /// Device ID cannot be loaded/generated on current runtime.
112    DeviceIdUnavailable,
113}
114
115impl std::fmt::Display for FingerprintError {
116    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
117        match self {
118            Self::DeviceIdUnavailable => write!(f, "device_id_unavailable"),
119        }
120    }
121}
122
123impl std::error::Error for FingerprintError {}
124
125/// Trait for device fingerprint.
126pub trait FingerprintProvider: Send + Sync + 'static {
127    /// Get the device fingerprint ID.
128    fn get_fingerprint(&self) -> Result<String, FingerprintError> {
129        Err(FingerprintError::DeviceIdUnavailable)
130    }
131}
132
133/// Trait for push token binding.
134pub trait PushNotificationProvider: Send + Sync + 'static {
135    /// Bind push token to cloud side.
136    fn bind_push_token<'a>(&'a self, _token: String) -> BoxFuture<'a, Result<(), ProviderError>> {
137        Box::pin(async { Ok(()) })
138    }
139}