CrossDial

CrossDial

CrossDial is a library for validating and formatting international phone numbers. It provides an easy-to-use interface for phone number validation with full error handling and batch support.

Table of Contents

  1. What it Does
  2. Getting Started
  3. Usage
  4. Understanding Validation Results
  5. Common Error Types
  6. Best Practices
  7. Examples
  8. Thread Safety
  9. Contributing
  10. Acknowledgements

What it Does

  • Phone Number Validation: Validates individual phone numbers.
  • Batch Validation: Supports validating multiple phone numbers at once.
  • Phone Number Formatting: Formats phone numbers according to the E.164 standard.
  • Detailed Error Reporting: Provides clear error messages for invalid numbers.
  • Country Code Validation: Ensures the country code matches the phone number format.
  • Thread-Safe: Designed to be thread-safe for use in multi-threaded environments.
  • Error Handling: Handles errors using ValidationResult—no runtime exceptions.

Getting Started

Maven

Add the following dependency to your pom.xml:

1
2
3
4
5
<dependency>
    <groupId>io.github.thesarfo</groupId>
    <artifactId>crossdial</artifactId>
    <version>1.0.0</version>
</dependency>

Gradle

Add this line to your build.gradle:

1
implementation group: 'io.github.thesarfo', name: 'crossdial', version: '1.0.0'

Usage

Validate a Single Phone Number

1
2
3
4
5
6
7
8
9
PhoneNumberValidator validator = new PhoneNumberValidator();

ValidationResult result = validator.validateNumber("+233244444444", "GH");

if (result.isValid()) {
    System.out.println("Valid: " + result.getFormattedNumber());
} else {
    System.out.println("Invalid: " + result.getError().getMessage());
}

Validate Multiple Numbers (Batch Validation)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
List<PhoneNumberRequest> numbers = Arrays.asList(
    new PhoneNumberRequest("+233244444444", "GH"),
    new PhoneNumberRequest("+1234567890", "US")
);

List<ValidationResult> results = validator.validateBatch(numbers);

results.forEach(r -> {
    if (r.isValid()) {
        System.out.println("Valid: " + r.getFormattedNumber());
    } else {
        System.out.println("Invalid: " + r.getOriginalNumber() + " - " + r.getError().getMessage());
    }
});

List Supported Countries

1
2
3
4
List<CountryCode> countries = validator.getSupportedCountries();
countries.forEach(c -> 
    System.out.println(c.getCountryName() + ": " + c.getCode())
);

Understanding Validation Results

When you validate a phone number, you receive a ValidationResult object. Here’s how to use it:

  • isValid(): Returns true if the phone number is valid.
  • getFormattedNumber(): Returns the phone number formatted according to the E.164 standard.
  • getOriginalNumber(): The phone number that was originally provided.
  • getError(): If the number is invalid, this contains the error message.

Common Error Types

The possible validation errors are encapsulated in an enum:

1
2
3
4
5
6
7
8
public enum ValidationError {
    INVALID_FORMAT("Invalid phone number format"),
    INVALID_COUNTRY_CODE("Invalid country code"),
    NUMBER_TOO_SHORT("Number is too short"),
    NUMBER_TOO_LONG("Number is too long"),
    EMPTY_NUMBER("Phone number cannot be empty"),
    PARSE_ERROR("Could not parse phone number")
}

Best Practices

  • Country Codes: Always use ISO 3166-1 alpha-2 country codes (e.g., “US”, “GB”, “GH”).
  • Phone Numbers: Numbers can include or exclude the ‘+’ prefix, spaces, or dashes as necessary. The library will clean up the formatting.

Examples

Valid Number Formats

1
2
validator.validateNumber("+1234567890", "US");
validator.validateNumber("123-456-7890", "US");

Error Handling Example

1
2
3
4
5
6
7
8
ValidationResult result = validator.validateNumber("123", "US");
if (!result.isValid()) {
    switch (result.getError()) {
        case NUMBER_TOO_SHORT -> System.out.println("Please enter a complete number");
        case INVALID_COUNTRY_CODE -> System.out.println("Invalid country code");
        default -> System.out.println("Error: " + result.getError().getMessage());
    }
}

Thread Safety

CrossDial is thread-safe, so you can use it safely across multiple threads or as a singleton in your applications:

1
2
3
4
5
6
@Service
public class PhoneValidationService {
    private final PhoneNumberValidator validator = new PhoneNumberValidator();
    
    // Use the validator in your service methods
}

Contributing

This project is meant to fit a very specific use case, but contributions are welcome. Feel free to open an issue or submit a pull request, or you can fork and build your own version


Acknowledgements

This project was built on top of Google’s libphonenumber.

© Ernest Sarfo. Some rights reserved.

Seize the Moment!