package faker import ( _ "embed" "encoding/json" "reflect" "github.com/go-faker/faker/v4/pkg/options" ) var ( //go:embed misc/addresses-us-1000.min.json addressesUSBytes []byte addressesUS []RealAddress //go:embed misc/country_info.json countriesBytes []byte countries []CountryInfo ) func init() { data := struct { Addresses []RealAddress `json:"addresses"` Countries []CountryInfo `json:"countries"` }{} if err := json.Unmarshal(addressesUSBytes, &data); err != nil { panic(err) } addressesUS = data.Addresses if err := json.Unmarshal(countriesBytes, &data); err != nil { panic(err) } countries = data.Countries } // GetAddress returns a new Addresser interface of Address func GetAddress() Addresser { address := &Address{} return address } // Addresser is logical layer for Address type Addresser interface { Latitude(v reflect.Value) (interface{}, error) Longitude(v reflect.Value) (interface{}, error) RealWorld(v reflect.Value) (interface{}, error) CountryInfo(v reflect.Value) (interface{}, error) } // Address struct type Address struct{} func (i Address) latitude() float32 { return (rand.Float32() * 180) - 90 } // Latitude sets latitude of the address func (i Address) Latitude(v reflect.Value) (interface{}, error) { kind := v.Kind() val := i.latitude() if kind == reflect.Float32 { return val, nil } return float64(val), nil } func (i Address) longitude() float32 { return (rand.Float32() * 360) - 180 } // Longitude sets longitude of the address func (i Address) Longitude(v reflect.Value) (interface{}, error) { kind := v.Kind() val := i.longitude() if kind == reflect.Float32 { return val, nil } return float64(val), nil } func (i Address) realWorld() RealAddress { return addressesUS[rand.Intn(len(addressesUS))] } func (i Address) countryInfo() CountryInfo { return countries[rand.Intn(len(countries))] } func (i Address) CountryInfo(_ reflect.Value) (interface{}, error) { return i.countryInfo(), nil } // RealWorld sets real world address func (i Address) RealWorld(_ reflect.Value) (interface{}, error) { return i.realWorld(), nil } // Longitude get fake longitude randomly func Longitude(opts ...options.OptionFunc) float64 { return singleFakeData(LONGITUDE, func() interface{} { address := Address{} return float64(address.longitude()) }, opts...).(float64) } // Latitude get fake latitude randomly func Latitude(opts ...options.OptionFunc) float64 { return singleFakeData(LATITUDE, func() interface{} { address := Address{} return float64(address.latitude()) }, opts...).(float64) } type RealCoordinates struct { Latitude float64 `json:"lat"` Longitude float64 `json:"lng"` } type RealAddress struct { Address string `json:"address1"` City string `json:"city"` State string `json:"state"` PostalCode string `json:"postalCode"` Coordinates RealCoordinates `json:"coordinates"` } // GetRealAddress get real world address randomly func GetRealAddress(opts ...options.OptionFunc) RealAddress { return singleFakeData(RealAddressTag, func() interface{} { address := Address{} return address.realWorld() }, opts...).(RealAddress) } type CountryInfo struct { Abbr string `json:"abbr"` Name string `json:"name"` Capital string `json:"capital"` Population string `json:"population"` Continent string `json:"continent"` } func GetCountryInfo(opts ...options.OptionFunc) CountryInfo { return singleFakeData(CountryInfoTag, func() interface{} { address := Address{} return address.countryInfo() }, opts...).(CountryInfo) }