1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
use derive_more::Display;
use regex::Regex;
use crate::{error::TypeError, CountryCode};
/// This crate provides functionality to parse and validate phone numbers with country codes.
///
/// # Example
///
/// ```
/// use custom_type::{PhoneNumber, CountryCode};
///
/// let phone_number = PhoneNumber::parse(CountryCode::USA, "1234567890").unwrap();
/// println!("{}", phone_number);
/// ```
///
/// # Features
///
/// - Parse and validate phone numbers with a specified country code.
/// - Custom error type `TypeError` for handling invalid phone numbers.
/// ### PhoneNumber : Parse `impl ToString` Into a Valid Phone Number
/// Provides a method to parse and validate phone numbers with specified country codes.
#[derive(Debug, PartialEq, Display)]
pub struct PhoneNumber(String);
impl PhoneNumber {
/// Parses a given string into a phone number with the specified country code.
///
/// A valid phone number must be between 10 to 15 digits long.
///
/// # Arguments
///
/// * `country_code` - The country code to be prepended to the phone number.
/// * `phone_number` - A string slice that holds the phone number to be parsed.
///
/// # Returns
///
/// * `Ok(Self)` if the phone number meets the criteria.
/// * `Err(TypeError::ParseError)` if the phone number is invalid.
///
/// # Examples
///
/// ```
/// use custom_type::{PhoneNumber, CountryCode};
///
/// let phone_number = PhoneNumber::parse(CountryCode::USA, "1234567890");
/// assert!(phone_number.is_ok());
///
/// let invalid_phone_number = PhoneNumber::parse(CountryCode::USA, "12345");
/// assert!(invalid_phone_number.is_err());
/// ```
pub fn parse(
country_code: CountryCode,
phone_number: impl ToString,
) -> Result<Self, TypeError> {
let phone_number = phone_number.to_string();
let phone_regex = Regex::new(r"^[0-9]{10,15}$").unwrap();
if phone_regex.is_match(&phone_number) {
Ok(Self(format!("{}{}", country_code, phone_number)))
} else {
Err(TypeError::ParseError(
"unable to parse phone number, invalid phone number.".to_string(),
))
}
}
}
/// ======================================================================
/// ========================= Unit Test
/// ======================================================================
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_valid_phone_number() {
assert_eq!(
PhoneNumber::parse(CountryCode::USA, "1234567890"),
Ok(PhoneNumber("+11234567890".to_string()))
);
assert_eq!(
PhoneNumber::parse(CountryCode::UK, "123456789012"),
Ok(PhoneNumber("+44123456789012".to_string()))
);
assert_eq!(
PhoneNumber::parse(CountryCode::IND, "1234567890"),
Ok(PhoneNumber("+911234567890".to_string()))
);
assert_eq!(
PhoneNumber::parse(CountryCode::AUS, "1234567890"),
Ok(PhoneNumber("+611234567890".to_string()))
);
}
#[test]
fn test_invalid_phone_number() {
assert_eq!(
PhoneNumber::parse(CountryCode::USA, "12345"),
Err(TypeError::ParseError(
"unable to parse phone number, invalid phone number.".to_string()
))
);
assert_eq!(
PhoneNumber::parse(CountryCode::UK, "phone123456"),
Err(TypeError::ParseError(
"unable to parse phone number, invalid phone number.".to_string()
))
);
assert_eq!(
PhoneNumber::parse(CountryCode::IND, "123-456-7890"),
Err(TypeError::ParseError(
"unable to parse phone number, invalid phone number.".to_string()
))
);
}
}