1
2use std::fmt;
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8#[repr(i32)]
9pub enum ErrorCode {
10 Success = 0,
11 MessageBodyIsEmpty = 1,
12 UserLimited = 2,
13 NumberNotAssignedToYou = 3,
14 RecipientsEmpty = 4,
15 CreditNotEnough = 5,
16 NumberNotProfitForBulkSend = 7,
17 NumberCannotSendAtThisHour = 9,
18 MaxRecipientsExceeded = 98,
19 OperatorLineDisconnected = 99,
20 AudioFileExtensionInvalid = 21,
21 AudioFileSizeInvalid = 22,
22 AudioMessageRetryInvalid = 23,
23 PhonebookContactInvalid = 100,
24 ContactExists = 101,
25 ContactSaved = 102,
26 MaxRecipientsVoiceNotMet = 111,
27 VoiceRetryMustBeOne = 131,
28 AudioFileAddressNotEntered = 132,
29 UsernameSpecialChar = 301,
30 PricingNotSet = 302,
31 UsernameNotEntered = 303,
32 UsernameAlreadyChosen = 304,
33 NationalCodeNotEntered = 306,
34 NationalCodeInvalid = 307,
35 BirthCertInvalid = 308,
36 BirthCertNotEntered = 309,
37 EmailNotEntered = 310,
38 PhoneNotEntered = 311,
39 PhoneIncorrect = 312,
40 AddressNotEntered = 313,
41 MobileNotEntered = 314,
42 MobileIncorrect = 315,
43 AccessLevelIncorrect = 316,
44 PasswordNotEntered = 317,
45 FutureBulkCanceled = 455,
46 BulkCodeInvalid = 456,
47 TicketCodeInvalid = 458,
48 NoAgencyAccess = 964,
49 UsernameOrPasswordIncorrect = 962,
50 AccessInvalid = 963,
51 PatternInvalid = 971,
52 PatternParamsInvalid = 970,
53 PatternRecipientInvalid = 972,
54 SendTimeInvalid = 992,
55 PhonebookNotArray = 993,
56 NeedBankCardImage = 994,
57 NeedBankCardNumber = 995,
58 PatternNotActive = 996,
59 PatternNotAllowed = 997,
60 NationalIdOrCardNotApproved = 998,
61 UsernameFormatInvalid = 1001,
62 PasswordTooSimple = 1002,
63 RegistrationError = 1003,
64 RegistrationError2 = 1004,
65 RegistrationError3 = 1005,
66 Unknown = -1,
67}
68
69impl ErrorCode {
70 pub fn from_i32(code: i32) -> Self {
71 use ErrorCode::*;
72 match code {
73 0 => Success,
74 1 => MessageBodyIsEmpty,
75 2 => UserLimited,
76 3 => NumberNotAssignedToYou,
77 4 => RecipientsEmpty,
78 5 => CreditNotEnough,
79 7 => NumberNotProfitForBulkSend,
80 9 => NumberCannotSendAtThisHour,
81 98 => MaxRecipientsExceeded,
82 99 => OperatorLineDisconnected,
83 21 => AudioFileExtensionInvalid,
84 22 => AudioFileSizeInvalid,
85 23 => AudioMessageRetryInvalid,
86 100 => PhonebookContactInvalid,
87 101 => ContactExists,
88 102 => ContactSaved,
89 111 => MaxRecipientsVoiceNotMet,
90 131 => VoiceRetryMustBeOne,
91 132 => AudioFileAddressNotEntered,
92 301 => UsernameSpecialChar,
93 302 => PricingNotSet,
94 303 => UsernameNotEntered,
95 304 => UsernameAlreadyChosen,
96 305 => UsernameNotEntered,
97 306 => NationalCodeNotEntered,
98 307 => NationalCodeInvalid,
99 308 => BirthCertInvalid,
100 309 => BirthCertNotEntered,
101 310 => EmailNotEntered,
102 311 => PhoneNotEntered,
103 312 => PhoneIncorrect,
104 313 => AddressNotEntered,
105 314 => MobileNotEntered,
106 315 => MobileIncorrect,
107 316 => AccessLevelIncorrect,
108 317 => PasswordNotEntered,
109 455 => FutureBulkCanceled,
110 456 => BulkCodeInvalid,
111 458 => TicketCodeInvalid,
112 964 => NoAgencyAccess,
113 962 => UsernameOrPasswordIncorrect,
114 963 => AccessInvalid,
115 971 => PatternInvalid,
116 970 => PatternParamsInvalid,
117 972 => PatternRecipientInvalid,
118 992 => SendTimeInvalid,
119 993 => PhonebookNotArray,
120 994 => NeedBankCardImage,
121 995 => NeedBankCardNumber,
122 996 => PatternNotActive,
123 997 => PatternNotAllowed,
124 998 => NationalIdOrCardNotApproved,
125 1001 => UsernameFormatInvalid,
126 1002 => PasswordTooSimple,
127 1003 => RegistrationError,
128 1004 => RegistrationError2,
129 1005 => RegistrationError3,
130 _ => Unknown,
131 }
132 }
133
134 pub fn code(&self) -> i32 {
135 *self as i32
136 }
137
138 pub fn english_message(&self) -> &'static str {
139 match self {
140 ErrorCode::Success => "Operation completed successfully.",
141 ErrorCode::MessageBodyIsEmpty => "Message body is empty.",
142 ErrorCode::UserLimited => "User is limited.",
143 ErrorCode::NumberNotAssignedToYou => "Number not assigned to you.",
144 ErrorCode::RecipientsEmpty => "Recipients is empty.",
145 ErrorCode::CreditNotEnough => "Credit not enough.",
146 ErrorCode::NumberNotProfitForBulkSend => "Number not profit for bulk send.",
147 ErrorCode::NumberCannotSendAtThisHour => "Number cannot send at this hour.",
148 ErrorCode::MaxRecipientsExceeded => "Maximum recipients number exceeded.",
149 ErrorCode::OperatorLineDisconnected => "Operator line is disconnected.",
150 ErrorCode::AudioFileExtensionInvalid => "Audio file extension is invalid.",
151 ErrorCode::AudioFileSizeInvalid => "Audio file size is invalid.",
152 ErrorCode::AudioMessageRetryInvalid => "Audio message retry count is invalid.",
153 ErrorCode::PhonebookContactInvalid => "Phonebook contact number is invalid.",
154 ErrorCode::ContactExists => "Contact already exists in phonebook.",
155 ErrorCode::ContactSaved => "Contact saved successfully in phonebook.",
156 ErrorCode::MaxRecipientsVoiceNotMet => "Maximum recipients for voice message not met.",
157 ErrorCode::VoiceRetryMustBeOne => "Voice message retry count must be one.",
158 ErrorCode::AudioFileAddressNotEntered => "Audio file address not entered.",
159 ErrorCode::UsernameSpecialChar => "Special character used in username.",
160 ErrorCode::PricingNotSet => "Pricing not set.",
161 ErrorCode::UsernameNotEntered => "Username not entered.",
162 ErrorCode::UsernameAlreadyChosen => "Username already chosen.",
163 ErrorCode::NationalCodeNotEntered => "National code not entered.",
164 ErrorCode::NationalCodeInvalid => "National code entered incorrectly.",
165 ErrorCode::BirthCertInvalid => "Birth certificate number is invalid.",
166 ErrorCode::BirthCertNotEntered => "Birth certificate number not entered.",
167 ErrorCode::EmailNotEntered => "User email not entered.",
168 ErrorCode::PhoneNotEntered => "Phone number not entered.",
169 ErrorCode::PhoneIncorrect => "Phone entered incorrectly.",
170 ErrorCode::AddressNotEntered => "Address not entered.",
171 ErrorCode::MobileNotEntered => "Mobile number not entered.",
172 ErrorCode::MobileIncorrect => "Mobile number entered incorrectly.",
173 ErrorCode::AccessLevelIncorrect => "Access level entered incorrectly.",
174 ErrorCode::PasswordNotEntered => "Password not entered.",
175 ErrorCode::FutureBulkCanceled => "Future sending for bulk code canceled.",
176 ErrorCode::BulkCodeInvalid => "Bulk code is invalid.",
177 ErrorCode::TicketCodeInvalid => "Ticket code is invalid.",
178 ErrorCode::NoAgencyAccess => "You do not have agency access.",
179 ErrorCode::UsernameOrPasswordIncorrect => "Username or password is incorrect.",
180 ErrorCode::AccessInvalid => "Access is invalid.",
181 ErrorCode::PatternInvalid => "Pattern is invalid.",
182 ErrorCode::PatternParamsInvalid => "Pattern parameters are invalid.",
183 ErrorCode::PatternRecipientInvalid => "Recipient for pattern is invalid.",
184 ErrorCode::SendTimeInvalid => "Messages can be sent from 8 to 23.",
185 ErrorCode::PhonebookNotArray => "Phonebook must be an array.",
186 ErrorCode::NeedBankCardImage => "Please upload a picture of your bank card from the documents menu.",
187 ErrorCode::NeedBankCardNumber => "To send with shared lines, please register your bank card number for identity verification.",
188 ErrorCode::PatternNotActive => "Pattern is not active.",
189 ErrorCode::PatternNotAllowed => "You are not allowed to send from this pattern.",
190 ErrorCode::NationalIdOrCardNotApproved => "Your national ID or bank card is not approved.",
191 ErrorCode::UsernameFormatInvalid => "Username format is incorrect, at least 5 characters (letters and numbers only).",
192 ErrorCode::PasswordTooSimple => "Password is too simple.",
193 ErrorCode::RegistrationError | ErrorCode::RegistrationError2 | ErrorCode::RegistrationError3 => "Registration error, contact support.",
194 ErrorCode::Unknown => "Unknown error.",
195 }
196 }
197
198 pub fn persian_message(&self) -> &'static str {
199 match self {
200 ErrorCode::Success => "عملیات با موفقیت انجام شده است.",
201 ErrorCode::MessageBodyIsEmpty => "متن پیام خالی می باشد.",
202 ErrorCode::UserLimited => "کاربر محدود گردیده است.",
203 ErrorCode::NumberNotAssignedToYou => "خط به شما تعلق ندارد.",
204 ErrorCode::RecipientsEmpty => "گیرندگان خالی است.",
205 ErrorCode::CreditNotEnough => "اعتبار کافی نیست.",
206 ErrorCode::NumberNotProfitForBulkSend => "خط مورد نظر برای ارسال انبوه مناسب نمیباشد.",
207 ErrorCode::NumberCannotSendAtThisHour => "خط مورد نظر در این ساعت امکان ارسال ندارد.",
208 ErrorCode::MaxRecipientsExceeded => "حداکثر تعداد گیرنده رعایت نشده است.",
209 ErrorCode::OperatorLineDisconnected => "اپراتور خط ارسالی قطع میباشد.",
210 ErrorCode::AudioFileExtensionInvalid => "پسوند فایل صوتی نامعتبر است.",
211 ErrorCode::AudioFileSizeInvalid => "سایز فایل صوتی نامعتبر است.",
212 ErrorCode::AudioMessageRetryInvalid => "تعداد تلاش در پیام صوتی نامعتبر است.",
213 ErrorCode::PhonebookContactInvalid => "شماره مخاطب دفترچه تلفن نامعتبر میباشد.",
214 ErrorCode::ContactExists => "شماره مخاطب در دفترچه تلفن وجود دارد.",
215 ErrorCode::ContactSaved => "شماره مخاطب با موفقیت در دفترچه تلفن ذخیره گردید.",
216 ErrorCode::MaxRecipientsVoiceNotMet => "حداکثر تعداد گیرنده برای ارسال پیام صوتی رعایت نشده است.",
217 ErrorCode::VoiceRetryMustBeOne => "تعداد تلاش در پیام صوتی باید یکبار باشد.",
218 ErrorCode::AudioFileAddressNotEntered => "آدرس فایل صوتی وارد نگردیده است.",
219 ErrorCode::UsernameSpecialChar => "از حرف ویژه در نام کاربری استفاده گردیده است.",
220 ErrorCode::PricingNotSet => "قیمت گذاری انجام نشده است.",
221 ErrorCode::UsernameNotEntered => "نام کاربری وارد نگردیده است.",
222 ErrorCode::UsernameAlreadyChosen => "نام کاربری قبلا انتخاب گردیده است.",
223 ErrorCode::NationalCodeNotEntered => "کد ملی وارد نشده است.",
224 ErrorCode::NationalCodeInvalid => "کد ملی به خطا وارد شده است.",
225 ErrorCode::BirthCertInvalid => "شماره شناسنامه نا معتبر است.",
226 ErrorCode::BirthCertNotEntered => "شماره شناسنامه وارد نگردیده است.",
227 ErrorCode::EmailNotEntered => "ایمیل کاربر وارد نگردیده است.",
228 ErrorCode::PhoneNotEntered => "شماره تلفن وارد نگردیده است.",
229 ErrorCode::PhoneIncorrect => "تلفن به درستی وارد نگردیده است.",
230 ErrorCode::AddressNotEntered => "آدرس شما وارد نگردیده است.",
231 ErrorCode::MobileNotEntered => "شماره موبایل را وارد نکرده اید.",
232 ErrorCode::MobileIncorrect => "شماره موبایل به نادرستی وارد گردیده است.",
233 ErrorCode::AccessLevelIncorrect => "سطح دسترسی به نادرستی وارد گردیده است.",
234 ErrorCode::PasswordNotEntered => "کلمه عبور وارد نشده است.",
235 ErrorCode::FutureBulkCanceled => "ارسال در آینده برای کد بالک ارسالی لغو شد.",
236 ErrorCode::BulkCodeInvalid => "کد بالک ارسالی نامعتبر است.",
237 ErrorCode::TicketCodeInvalid => "کد تیکت نامعتبر است.",
238 ErrorCode::NoAgencyAccess => "شما دسترسی نمایندگی ندارید.",
239 ErrorCode::UsernameOrPasswordIncorrect => "نام کاربری یا کلمه عبور نادرست می باشد.",
240 ErrorCode::AccessInvalid => "دسترسی نامعتبر می باشد.",
241 ErrorCode::PatternInvalid => "پترن ارسالی نامعتبر است.",
242 ErrorCode::PatternParamsInvalid => "پارامتر های ارسالی برای پترن نامعتبر است.",
243 ErrorCode::PatternRecipientInvalid => "دریافت کننده برای ارسال پترن نامعتبر می باشد.",
244 ErrorCode::SendTimeInvalid => "ارسال پیام از ساعت 8 تا 23 می باشد.",
245 ErrorCode::PhonebookNotArray => "دفترچه تلفن باید یک آرایه باشد",
246 ErrorCode::NeedBankCardImage => "لطفا تصویری از کارت بانکی خود را از منو مدارک ارسال کنید",
247 ErrorCode::NeedBankCardNumber => "جهت ارسال با خطوط اشتراکی سامانه، لطفا شماره کارت بانکی خود را به دلیل تکمیل فرایند احراز هویت از بخش ارسال مدارک ثبت نمایید.",
248 ErrorCode::PatternNotActive => "پترن فعال نیست.",
249 ErrorCode::PatternNotAllowed => "شما اجازه ارسال از این پترن را ندارید.",
250 ErrorCode::NationalIdOrCardNotApproved => "کارت ملی یا کارت بانکی شما تایید نشده است.",
251 ErrorCode::UsernameFormatInvalid => "فرمت نام کاربری درست نمی باشد،حداقل ۵ کاراکتر(فقط حروف و اعداد)",
252 ErrorCode::PasswordTooSimple => "گذرواژه خیلی ساده می باشد.",
253 ErrorCode::RegistrationError | ErrorCode::RegistrationError2 | ErrorCode::RegistrationError3 => "مشکل در ثبت، با پشتیبانی تماس بگیرید.",
254 ErrorCode::Unknown => "خطای ناشناخته",
255 }
256 }
257}
258
259impl fmt::Display for ErrorCode {
260 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
261 write!(f, "{}", self.english_message())
262 }
263}
264
265#[derive(Debug)]
269pub struct IppanelError {
270 pub message: String,
271 pub code: ErrorCode,
272}
273
274impl fmt::Display for IppanelError {
275 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
276 write!(f, "IppanelError(code: {}, message: {})", self.code.code(), self.message)
277 }
278}
279
280impl std::error::Error for IppanelError {}
281
282impl IppanelError {
283 pub fn new(message: impl Into<String>, code: i32) -> Self {
284 Self { message: message.into(), code: ErrorCode::from_i32(code) }
285 }
286
287 pub fn unwrap(&self) -> &str {
288 &self.message
289 }
290
291 pub fn code(&self) -> ErrorCode {
292 self.code
293 }
294
295 pub fn parse_api_error(response: &serde_json::Value) -> Option<IppanelError> {
296 if let Some(data) = response.get("data") {
297 if let Some(error) = data.get("error") {
298 let code = response.get("code").and_then(|c| c.as_i64()).unwrap_or(0) as i32;
299 return Some(IppanelError::new(error.to_string(), code));
300 }
301 }
302 None
303 }
304
305 pub fn to_persian_message(&self) -> &'static str {
306 self.code.persian_message()
307 }
308 pub fn to_english_message(&self) -> &'static str {
309 self.code.english_message()
310 }
311}