use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(i32)]
pub enum ErrorCode {
Success = 0,
MessageBodyIsEmpty = 1,
UserLimited = 2,
NumberNotAssignedToYou = 3,
RecipientsEmpty = 4,
CreditNotEnough = 5,
NumberNotProfitForBulkSend = 7,
NumberCannotSendAtThisHour = 9,
MaxRecipientsExceeded = 98,
OperatorLineDisconnected = 99,
AudioFileExtensionInvalid = 21,
AudioFileSizeInvalid = 22,
AudioMessageRetryInvalid = 23,
PhonebookContactInvalid = 100,
ContactExists = 101,
ContactSaved = 102,
MaxRecipientsVoiceNotMet = 111,
VoiceRetryMustBeOne = 131,
AudioFileAddressNotEntered = 132,
UsernameSpecialChar = 301,
PricingNotSet = 302,
UsernameNotEntered = 303,
UsernameAlreadyChosen = 304,
NationalCodeNotEntered = 306,
NationalCodeInvalid = 307,
BirthCertInvalid = 308,
BirthCertNotEntered = 309,
EmailNotEntered = 310,
PhoneNotEntered = 311,
PhoneIncorrect = 312,
AddressNotEntered = 313,
MobileNotEntered = 314,
MobileIncorrect = 315,
AccessLevelIncorrect = 316,
PasswordNotEntered = 317,
FutureBulkCanceled = 455,
BulkCodeInvalid = 456,
TicketCodeInvalid = 458,
NoAgencyAccess = 964,
UsernameOrPasswordIncorrect = 962,
AccessInvalid = 963,
PatternInvalid = 971,
PatternParamsInvalid = 970,
PatternRecipientInvalid = 972,
SendTimeInvalid = 992,
PhonebookNotArray = 993,
NeedBankCardImage = 994,
NeedBankCardNumber = 995,
PatternNotActive = 996,
PatternNotAllowed = 997,
NationalIdOrCardNotApproved = 998,
UsernameFormatInvalid = 1001,
PasswordTooSimple = 1002,
RegistrationError = 1003,
RegistrationError2 = 1004,
RegistrationError3 = 1005,
Unknown = -1,
}
impl ErrorCode {
pub fn from_i32(code: i32) -> Self {
use ErrorCode::*;
match code {
0 => Success,
1 => MessageBodyIsEmpty,
2 => UserLimited,
3 => NumberNotAssignedToYou,
4 => RecipientsEmpty,
5 => CreditNotEnough,
7 => NumberNotProfitForBulkSend,
9 => NumberCannotSendAtThisHour,
98 => MaxRecipientsExceeded,
99 => OperatorLineDisconnected,
21 => AudioFileExtensionInvalid,
22 => AudioFileSizeInvalid,
23 => AudioMessageRetryInvalid,
100 => PhonebookContactInvalid,
101 => ContactExists,
102 => ContactSaved,
111 => MaxRecipientsVoiceNotMet,
131 => VoiceRetryMustBeOne,
132 => AudioFileAddressNotEntered,
301 => UsernameSpecialChar,
302 => PricingNotSet,
303 => UsernameNotEntered,
304 => UsernameAlreadyChosen,
305 => UsernameNotEntered,
306 => NationalCodeNotEntered,
307 => NationalCodeInvalid,
308 => BirthCertInvalid,
309 => BirthCertNotEntered,
310 => EmailNotEntered,
311 => PhoneNotEntered,
312 => PhoneIncorrect,
313 => AddressNotEntered,
314 => MobileNotEntered,
315 => MobileIncorrect,
316 => AccessLevelIncorrect,
317 => PasswordNotEntered,
455 => FutureBulkCanceled,
456 => BulkCodeInvalid,
458 => TicketCodeInvalid,
964 => NoAgencyAccess,
962 => UsernameOrPasswordIncorrect,
963 => AccessInvalid,
971 => PatternInvalid,
970 => PatternParamsInvalid,
972 => PatternRecipientInvalid,
992 => SendTimeInvalid,
993 => PhonebookNotArray,
994 => NeedBankCardImage,
995 => NeedBankCardNumber,
996 => PatternNotActive,
997 => PatternNotAllowed,
998 => NationalIdOrCardNotApproved,
1001 => UsernameFormatInvalid,
1002 => PasswordTooSimple,
1003 => RegistrationError,
1004 => RegistrationError2,
1005 => RegistrationError3,
_ => Unknown,
}
}
pub fn code(&self) -> i32 {
*self as i32
}
pub fn english_message(&self) -> &'static str {
match self {
ErrorCode::Success => "Operation completed successfully.",
ErrorCode::MessageBodyIsEmpty => "Message body is empty.",
ErrorCode::UserLimited => "User is limited.",
ErrorCode::NumberNotAssignedToYou => "Number not assigned to you.",
ErrorCode::RecipientsEmpty => "Recipients is empty.",
ErrorCode::CreditNotEnough => "Credit not enough.",
ErrorCode::NumberNotProfitForBulkSend => "Number not profit for bulk send.",
ErrorCode::NumberCannotSendAtThisHour => "Number cannot send at this hour.",
ErrorCode::MaxRecipientsExceeded => "Maximum recipients number exceeded.",
ErrorCode::OperatorLineDisconnected => "Operator line is disconnected.",
ErrorCode::AudioFileExtensionInvalid => "Audio file extension is invalid.",
ErrorCode::AudioFileSizeInvalid => "Audio file size is invalid.",
ErrorCode::AudioMessageRetryInvalid => "Audio message retry count is invalid.",
ErrorCode::PhonebookContactInvalid => "Phonebook contact number is invalid.",
ErrorCode::ContactExists => "Contact already exists in phonebook.",
ErrorCode::ContactSaved => "Contact saved successfully in phonebook.",
ErrorCode::MaxRecipientsVoiceNotMet => "Maximum recipients for voice message not met.",
ErrorCode::VoiceRetryMustBeOne => "Voice message retry count must be one.",
ErrorCode::AudioFileAddressNotEntered => "Audio file address not entered.",
ErrorCode::UsernameSpecialChar => "Special character used in username.",
ErrorCode::PricingNotSet => "Pricing not set.",
ErrorCode::UsernameNotEntered => "Username not entered.",
ErrorCode::UsernameAlreadyChosen => "Username already chosen.",
ErrorCode::NationalCodeNotEntered => "National code not entered.",
ErrorCode::NationalCodeInvalid => "National code entered incorrectly.",
ErrorCode::BirthCertInvalid => "Birth certificate number is invalid.",
ErrorCode::BirthCertNotEntered => "Birth certificate number not entered.",
ErrorCode::EmailNotEntered => "User email not entered.",
ErrorCode::PhoneNotEntered => "Phone number not entered.",
ErrorCode::PhoneIncorrect => "Phone entered incorrectly.",
ErrorCode::AddressNotEntered => "Address not entered.",
ErrorCode::MobileNotEntered => "Mobile number not entered.",
ErrorCode::MobileIncorrect => "Mobile number entered incorrectly.",
ErrorCode::AccessLevelIncorrect => "Access level entered incorrectly.",
ErrorCode::PasswordNotEntered => "Password not entered.",
ErrorCode::FutureBulkCanceled => "Future sending for bulk code canceled.",
ErrorCode::BulkCodeInvalid => "Bulk code is invalid.",
ErrorCode::TicketCodeInvalid => "Ticket code is invalid.",
ErrorCode::NoAgencyAccess => "You do not have agency access.",
ErrorCode::UsernameOrPasswordIncorrect => "Username or password is incorrect.",
ErrorCode::AccessInvalid => "Access is invalid.",
ErrorCode::PatternInvalid => "Pattern is invalid.",
ErrorCode::PatternParamsInvalid => "Pattern parameters are invalid.",
ErrorCode::PatternRecipientInvalid => "Recipient for pattern is invalid.",
ErrorCode::SendTimeInvalid => "Messages can be sent from 8 to 23.",
ErrorCode::PhonebookNotArray => "Phonebook must be an array.",
ErrorCode::NeedBankCardImage => "Please upload a picture of your bank card from the documents menu.",
ErrorCode::NeedBankCardNumber => "To send with shared lines, please register your bank card number for identity verification.",
ErrorCode::PatternNotActive => "Pattern is not active.",
ErrorCode::PatternNotAllowed => "You are not allowed to send from this pattern.",
ErrorCode::NationalIdOrCardNotApproved => "Your national ID or bank card is not approved.",
ErrorCode::UsernameFormatInvalid => "Username format is incorrect, at least 5 characters (letters and numbers only).",
ErrorCode::PasswordTooSimple => "Password is too simple.",
ErrorCode::RegistrationError | ErrorCode::RegistrationError2 | ErrorCode::RegistrationError3 => "Registration error, contact support.",
ErrorCode::Unknown => "Unknown error.",
}
}
pub fn persian_message(&self) -> &'static str {
match self {
ErrorCode::Success => "عملیات با موفقیت انجام شده است.",
ErrorCode::MessageBodyIsEmpty => "متن پیام خالی می باشد.",
ErrorCode::UserLimited => "کاربر محدود گردیده است.",
ErrorCode::NumberNotAssignedToYou => "خط به شما تعلق ندارد.",
ErrorCode::RecipientsEmpty => "گیرندگان خالی است.",
ErrorCode::CreditNotEnough => "اعتبار کافی نیست.",
ErrorCode::NumberNotProfitForBulkSend => "خط مورد نظر برای ارسال انبوه مناسب نمیباشد.",
ErrorCode::NumberCannotSendAtThisHour => "خط مورد نظر در این ساعت امکان ارسال ندارد.",
ErrorCode::MaxRecipientsExceeded => "حداکثر تعداد گیرنده رعایت نشده است.",
ErrorCode::OperatorLineDisconnected => "اپراتور خط ارسالی قطع میباشد.",
ErrorCode::AudioFileExtensionInvalid => "پسوند فایل صوتی نامعتبر است.",
ErrorCode::AudioFileSizeInvalid => "سایز فایل صوتی نامعتبر است.",
ErrorCode::AudioMessageRetryInvalid => "تعداد تلاش در پیام صوتی نامعتبر است.",
ErrorCode::PhonebookContactInvalid => "شماره مخاطب دفترچه تلفن نامعتبر میباشد.",
ErrorCode::ContactExists => "شماره مخاطب در دفترچه تلفن وجود دارد.",
ErrorCode::ContactSaved => "شماره مخاطب با موفقیت در دفترچه تلفن ذخیره گردید.",
ErrorCode::MaxRecipientsVoiceNotMet => "حداکثر تعداد گیرنده برای ارسال پیام صوتی رعایت نشده است.",
ErrorCode::VoiceRetryMustBeOne => "تعداد تلاش در پیام صوتی باید یکبار باشد.",
ErrorCode::AudioFileAddressNotEntered => "آدرس فایل صوتی وارد نگردیده است.",
ErrorCode::UsernameSpecialChar => "از حرف ویژه در نام کاربری استفاده گردیده است.",
ErrorCode::PricingNotSet => "قیمت گذاری انجام نشده است.",
ErrorCode::UsernameNotEntered => "نام کاربری وارد نگردیده است.",
ErrorCode::UsernameAlreadyChosen => "نام کاربری قبلا انتخاب گردیده است.",
ErrorCode::NationalCodeNotEntered => "کد ملی وارد نشده است.",
ErrorCode::NationalCodeInvalid => "کد ملی به خطا وارد شده است.",
ErrorCode::BirthCertInvalid => "شماره شناسنامه نا معتبر است.",
ErrorCode::BirthCertNotEntered => "شماره شناسنامه وارد نگردیده است.",
ErrorCode::EmailNotEntered => "ایمیل کاربر وارد نگردیده است.",
ErrorCode::PhoneNotEntered => "شماره تلفن وارد نگردیده است.",
ErrorCode::PhoneIncorrect => "تلفن به درستی وارد نگردیده است.",
ErrorCode::AddressNotEntered => "آدرس شما وارد نگردیده است.",
ErrorCode::MobileNotEntered => "شماره موبایل را وارد نکرده اید.",
ErrorCode::MobileIncorrect => "شماره موبایل به نادرستی وارد گردیده است.",
ErrorCode::AccessLevelIncorrect => "سطح دسترسی به نادرستی وارد گردیده است.",
ErrorCode::PasswordNotEntered => "کلمه عبور وارد نشده است.",
ErrorCode::FutureBulkCanceled => "ارسال در آینده برای کد بالک ارسالی لغو شد.",
ErrorCode::BulkCodeInvalid => "کد بالک ارسالی نامعتبر است.",
ErrorCode::TicketCodeInvalid => "کد تیکت نامعتبر است.",
ErrorCode::NoAgencyAccess => "شما دسترسی نمایندگی ندارید.",
ErrorCode::UsernameOrPasswordIncorrect => "نام کاربری یا کلمه عبور نادرست می باشد.",
ErrorCode::AccessInvalid => "دسترسی نامعتبر می باشد.",
ErrorCode::PatternInvalid => "پترن ارسالی نامعتبر است.",
ErrorCode::PatternParamsInvalid => "پارامتر های ارسالی برای پترن نامعتبر است.",
ErrorCode::PatternRecipientInvalid => "دریافت کننده برای ارسال پترن نامعتبر می باشد.",
ErrorCode::SendTimeInvalid => "ارسال پیام از ساعت 8 تا 23 می باشد.",
ErrorCode::PhonebookNotArray => "دفترچه تلفن باید یک آرایه باشد",
ErrorCode::NeedBankCardImage => "لطفا تصویری از کارت بانکی خود را از منو مدارک ارسال کنید",
ErrorCode::NeedBankCardNumber => "جهت ارسال با خطوط اشتراکی سامانه، لطفا شماره کارت بانکی خود را به دلیل تکمیل فرایند احراز هویت از بخش ارسال مدارک ثبت نمایید.",
ErrorCode::PatternNotActive => "پترن فعال نیست.",
ErrorCode::PatternNotAllowed => "شما اجازه ارسال از این پترن را ندارید.",
ErrorCode::NationalIdOrCardNotApproved => "کارت ملی یا کارت بانکی شما تایید نشده است.",
ErrorCode::UsernameFormatInvalid => "فرمت نام کاربری درست نمی باشد،حداقل ۵ کاراکتر(فقط حروف و اعداد)",
ErrorCode::PasswordTooSimple => "گذرواژه خیلی ساده می باشد.",
ErrorCode::RegistrationError | ErrorCode::RegistrationError2 | ErrorCode::RegistrationError3 => "مشکل در ثبت، با پشتیبانی تماس بگیرید.",
ErrorCode::Unknown => "خطای ناشناخته",
}
}
}
impl fmt::Display for ErrorCode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.english_message())
}
}
#[derive(Debug)]
pub struct IppanelError {
pub message: String,
pub code: ErrorCode,
}
impl fmt::Display for IppanelError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "IppanelError(code: {}, message: {})", self.code.code(), self.message)
}
}
impl std::error::Error for IppanelError {}
impl IppanelError {
pub fn new(message: impl Into<String>, code: i32) -> Self {
Self { message: message.into(), code: ErrorCode::from_i32(code) }
}
pub fn unwrap(&self) -> &str {
&self.message
}
pub fn code(&self) -> ErrorCode {
self.code
}
pub fn parse_api_error(response: &serde_json::Value) -> Option<IppanelError> {
if let Some(data) = response.get("data") {
if let Some(error) = data.get("error") {
let code = response.get("code").and_then(|c| c.as_i64()).unwrap_or(0) as i32;
return Some(IppanelError::new(error.to_string(), code));
}
}
None
}
pub fn to_persian_message(&self) -> &'static str {
self.code.persian_message()
}
pub fn to_english_message(&self) -> &'static str {
self.code.english_message()
}
}