Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add phone-number package #15

Merged
merged 2 commits into from
Jul 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions phone_numbers/operators.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package phonenumbers

import "errors"

type Operator string
type SimType string

var ErrInvalidFormat = errors.New("invalid phone number format")

// List of valid prefixes
var Prefixes = []string{"+98", "98", "0098", "0"}

const (
ShatelMobile Operator = "ShatelMobile"
MCI Operator = "MCI"
Irancell Operator = "Irancell"
Taliya Operator = "Taliya"
RightTel Operator = "RightTel"

Permanent SimType = "Permanent"
Credit SimType = "Credit"
)

type OperatorDetails struct {
base string
province []string
model string
operator Operator
simTypes []SimType
}

func (o Operator) Details() map[string]OperatorDetails {
switch o {
case MCI:
return MCIMap
case Taliya:
return TALIYA
case RightTel:
return RIGHTTEL
case Irancell:
return IRANCELL
case ShatelMobile:
return SHATELMOBILE
default:
return nil
}
}

func (od *OperatorDetails) GetProvinceList() []string {
return od.province
}

func (od *OperatorDetails) GetBase() string {
return od.base
}

func (od *OperatorDetails) GetModel() string {
return od.model
}

func (od *OperatorDetails) GetOperator() Operator {
return od.operator
}

func (od *OperatorDetails) GetSimTypeList() []SimType {
return od.simTypes
}
87 changes: 87 additions & 0 deletions phone_numbers/phone.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package phonenumbers

import (
"errors"
"strings"
)

// GetPhoneDetails returns the OperatorDetails for the given phoneNumber
func GetPhoneDetails(phoneNumber string) (*OperatorDetails, error) {
if ok := IsPhoneValid(phoneNumber); !ok {
return nil, ErrInvalidFormat
}
prefix, err := GetOperatorPrefix(phoneNumber)
if err != nil {
return nil, err
}
return GetPrefixDetails(prefix)
}

func GetPrefixDetails(prefix string) (*OperatorDetails, error) {
// Define a slice of maps to iterate over
operatorsMap := []map[string]OperatorDetails{
MCIMap,
TALIYA,
RIGHTTEL,
IRANCELL,
SHATELMOBILE,
}

// Iterate over each map and check for the prefix
for _, m := range operatorsMap {
if details, found := m[prefix]; found {
return &details, nil
}
}

return nil, errors.New("Invalid prefix")
}

// IsPhoneValid returns if the phoneNumber is valid
func IsPhoneValid(phoneNumber string) bool {
prefix := GetPhonePrefix(phoneNumber)

phoneNumberWithoutPrefix := phoneNumber[len(prefix):]
if len(phoneNumberWithoutPrefix) == 10 && phoneNumberWithoutPrefix[0] == '9' {
return true
}

return false
}

// GetPhonePrefix returns the prefix for Iranian phone numbers
// Example +98 98 0098 0
func GetPhonePrefix(phoneNumber string) string {
for _, prefix := range Prefixes {
if strings.HasPrefix(phoneNumber, prefix) {
return prefix
}
}
return ""
}

// phoneNumberNormalizer replaces the current phone number prefix with the desired prefix
func PhoneNumberNormalizer(phoneNumber, newPrefix string) (string, error) {
if ok := IsPhoneValid(phoneNumber); !ok {
return "", ErrInvalidFormat
}

prefix := GetPhonePrefix(phoneNumber)

return newPrefix + phoneNumber[len(prefix):], nil
}

// GetOperatorPrefix returns the operator prefix of the phone number
func GetOperatorPrefix(phoneNumber string) (string, error) {
if ok := IsPhoneValid(phoneNumber); !ok {
return "", ErrInvalidFormat
}

for _, prefix := range Prefixes {
if strings.HasPrefix(phoneNumber, prefix) {
return phoneNumber[len(prefix) : len(prefix)+3], nil
}
}

return "", ErrInvalidFormat
}
240 changes: 240 additions & 0 deletions phone_numbers/phone_numbers_list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
package phonenumbers

var MCIMap = map[string]OperatorDetails{
"910": {
base: "کشوری",
province: []string{},
simTypes: []SimType{Permanent, Credit},
operator: MCI,
},
"914": {
base: "آذربایجان غربی",
province: []string{"آذربایجان شرقی", "اردبیل", "اصفهان"},
simTypes: []SimType{Permanent, Credit},
operator: MCI,
},
"911": {
base: "مازندران",
province: []string{"گلستان", "گیلان"},
simTypes: []SimType{Permanent, Credit},
operator: MCI,
},
"912": {
base: "تهران",
province: []string{"البرز", "زنجان", "سمنان", "قزوین", "قم", "برخی از شهرستان های استان مرکزی"},
simTypes: []SimType{Permanent},
operator: MCI,
},
"913": {
base: "اصفهان",
province: []string{"یزد", "چهارمحال و بختیاری", "کرمان"},
simTypes: []SimType{Permanent, Credit},
operator: MCI,
},
"915": {
base: "خراسان رضوی",
province: []string{"خراسان شمالی", "خراسان جنوبی", "سیستان و بلوچستان"},
simTypes: []SimType{Permanent, Credit},
operator: MCI,
},
"916": {
base: "خوزستان",
province: []string{"لرستان", "فارس", "اصفهان"},
simTypes: []SimType{Permanent, Credit},
operator: MCI,
},
"917": {
base: "فارس",
province: []string{"بوشهر", "کهگیلویه و بویر احمد", "هرمزگان"},
simTypes: []SimType{Permanent, Credit},
operator: MCI,
},
"918": {
base: "کرمانشاه",
province: []string{"کردستان", "ایلام", "همدان"},
simTypes: []SimType{Permanent, Credit},
operator: MCI,
},
"919": {
base: "تهران",
province: []string{"البرز", "سمنان", "قم", "قزوین", "زنجان"},
simTypes: []SimType{Credit},
operator: MCI,
},
"990": {
base: "کشوری",
province: []string{},
simTypes: []SimType{Credit},
operator: MCI,
},
"991": {
base: "کشوری",
province: []string{},
simTypes: []SimType{Permanent, Credit},
operator: MCI,
},
"992": {
base: "کشوری",
province: []string{},
simTypes: []SimType{Credit},
operator: MCI,
},
"993": {
base: "کشوری",
province: []string{},
simTypes: []SimType{Credit},
operator: MCI,
},
"994": {
base: "کشوری",
province: []string{},
simTypes: []SimType{Credit},
operator: MCI,
},
"995": {
base: "کشوری",
province: []string{},
simTypes: []SimType{Permanent, Credit},
operator: MCI,
},
"996": {
base: "کشوری",
province: []string{},
simTypes: []SimType{Permanent, Credit},
operator: MCI,
},
}

var TALIYA = map[string]OperatorDetails{
"932": {
base: "کشوری",
province: []string{},
simTypes: []SimType{Credit},
operator: Taliya,
},
}

var RIGHTTEL = map[string]OperatorDetails{
"920": {
base: "کشوری",
province: []string{},
simTypes: []SimType{Permanent},
operator: RightTel,
},
"921": {
base: "کشوری",
province: []string{},
simTypes: []SimType{Credit},
operator: RightTel,
},
"922": {
base: "کشوری",
province: []string{},
simTypes: []SimType{Credit},
operator: RightTel,
},
"923": {
base: "کشوری",
province: []string{},
simTypes: []SimType{Credit},
operator: RightTel,
},
}

var IRANCELL = map[string]OperatorDetails{
"930": {
base: "کشوری",
province: []string{},
simTypes: []SimType{Credit, Permanent},
operator: Irancell,
},
"933": {
base: "کشوری",
province: []string{},
simTypes: []SimType{Credit, Permanent},
operator: Irancell,
},
"935": {
base: "کشوری",
province: []string{},
simTypes: []SimType{Credit, Permanent},
operator: Irancell,
},
"936": {
base: "کشوری",
province: []string{},
simTypes: []SimType{Credit, Permanent},
operator: Irancell,
},
"937": {
base: "کشوری",
province: []string{},
simTypes: []SimType{Credit, Permanent},
operator: Irancell,
},
"938": {
base: "کشوری",
province: []string{},
simTypes: []SimType{Credit, Permanent},
operator: Irancell,
},
"939": {
base: "کشوری",
province: []string{},
simTypes: []SimType{Credit, Permanent},
operator: Irancell,
},
"901": {
base: "کشوری",
province: []string{},
simTypes: []SimType{Credit, Permanent},
operator: Irancell,
},
"902": {
base: "کشوری",
province: []string{},
simTypes: []SimType{Credit, Permanent},
operator: Irancell,
},
"903": {
base: "کشوری",
province: []string{},
simTypes: []SimType{Credit, Permanent},
operator: Irancell,
},
"905": {
base: "کشوری",
province: []string{},
simTypes: []SimType{Credit, Permanent},
operator: Irancell,
},
"900": {
base: "کشوری",
province: []string{},
simTypes: []SimType{Credit, Permanent},
operator: Irancell,
},
"904": {
base: "کشوری",
province: []string{},
simTypes: []SimType{Credit},
operator: Irancell,
model: "سیم‌کارت کودک",
},
"941": {
base: "کشوری",
province: []string{},
simTypes: []SimType{Credit},
operator: Irancell,
model: "TD-LTE",
},
}

var SHATELMOBILE = map[string]OperatorDetails{
"998": {
base: "کشوری",
province: []string{},
simTypes: []SimType{Credit},
operator: ShatelMobile,
},
}
Loading
Loading