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}