1package faker
  2
  3import (
  4	_ "embed"
  5	"encoding/json"
  6	"reflect"
  7
  8	"github.com/go-faker/faker/v4/pkg/options"
  9)
 10
 11var (
 12	//go:embed misc/addresses-us-1000.min.json
 13	addressesUSBytes []byte
 14	addressesUS      []RealAddress
 15
 16	//go:embed misc/country_info.json
 17	countriesBytes []byte
 18	countries      []CountryInfo
 19)
 20
 21func init() {
 22	data := struct {
 23		Addresses []RealAddress `json:"addresses"`
 24		Countries []CountryInfo `json:"countries"`
 25	}{}
 26	if err := json.Unmarshal(addressesUSBytes, &data); err != nil {
 27		panic(err)
 28	}
 29	addressesUS = data.Addresses
 30
 31	if err := json.Unmarshal(countriesBytes, &data); err != nil {
 32		panic(err)
 33	}
 34	countries = data.Countries
 35}
 36
 37// GetAddress returns a new Addresser interface of Address
 38func GetAddress() Addresser {
 39	address := &Address{}
 40	return address
 41}
 42
 43// Addresser is logical layer for Address
 44type Addresser interface {
 45	Latitude(v reflect.Value) (interface{}, error)
 46	Longitude(v reflect.Value) (interface{}, error)
 47	RealWorld(v reflect.Value) (interface{}, error)
 48	CountryInfo(v reflect.Value) (interface{}, error)
 49}
 50
 51// Address struct
 52type Address struct{}
 53
 54func (i Address) latitude() float32 {
 55	return (rand.Float32() * 180) - 90
 56}
 57
 58// Latitude sets latitude of the address
 59func (i Address) Latitude(v reflect.Value) (interface{}, error) {
 60	kind := v.Kind()
 61	val := i.latitude()
 62	if kind == reflect.Float32 {
 63		return val, nil
 64	}
 65	return float64(val), nil
 66}
 67
 68func (i Address) longitude() float32 {
 69	return (rand.Float32() * 360) - 180
 70}
 71
 72// Longitude sets longitude of the address
 73func (i Address) Longitude(v reflect.Value) (interface{}, error) {
 74	kind := v.Kind()
 75	val := i.longitude()
 76	if kind == reflect.Float32 {
 77		return val, nil
 78	}
 79	return float64(val), nil
 80}
 81
 82func (i Address) realWorld() RealAddress {
 83	return addressesUS[rand.Intn(len(addressesUS))]
 84}
 85
 86func (i Address) countryInfo() CountryInfo {
 87	return countries[rand.Intn(len(countries))]
 88}
 89
 90func (i Address) CountryInfo(_ reflect.Value) (interface{}, error) {
 91	return i.countryInfo(), nil
 92}
 93
 94// RealWorld sets real world address
 95func (i Address) RealWorld(_ reflect.Value) (interface{}, error) {
 96	return i.realWorld(), nil
 97}
 98
 99// Longitude get fake longitude randomly
100func Longitude(opts ...options.OptionFunc) float64 {
101	return singleFakeData(LONGITUDE, func() interface{} {
102		address := Address{}
103		return float64(address.longitude())
104	}, opts...).(float64)
105}
106
107// Latitude get fake latitude randomly
108func Latitude(opts ...options.OptionFunc) float64 {
109	return singleFakeData(LATITUDE, func() interface{} {
110		address := Address{}
111		return float64(address.latitude())
112	}, opts...).(float64)
113}
114
115type RealCoordinates struct {
116	Latitude  float64 `json:"lat"`
117	Longitude float64 `json:"lng"`
118}
119
120type RealAddress struct {
121	Address     string          `json:"address1"`
122	City        string          `json:"city"`
123	State       string          `json:"state"`
124	PostalCode  string          `json:"postalCode"`
125	Coordinates RealCoordinates `json:"coordinates"`
126}
127
128// GetRealAddress get real world address randomly
129func GetRealAddress(opts ...options.OptionFunc) RealAddress {
130	return singleFakeData(RealAddressTag, func() interface{} {
131		address := Address{}
132		return address.realWorld()
133	}, opts...).(RealAddress)
134}
135
136type CountryInfo struct {
137	Abbr       string `json:"abbr"`
138	Name       string `json:"name"`
139	Capital    string `json:"capital"`
140	Population string `json:"population"`
141	Continent  string `json:"continent"`
142}
143
144func GetCountryInfo(opts ...options.OptionFunc) CountryInfo {
145	return singleFakeData(CountryInfoTag, func() interface{} {
146		address := Address{}
147		return address.countryInfo()
148	}, opts...).(CountryInfo)
149}