diff --git a/geoip2.go b/geoip2.go new file mode 100644 index 0000000..69a805c --- /dev/null +++ b/geoip2.go @@ -0,0 +1,78 @@ +package geoip2 + +import ( + "context" + "fmt" + "net/netip" + "strings" +) + +// ErrNotFound is returned when the database does not contain the IP address. +const ErrNotFound = "not found" + +// Info is a structure that contains information about the IP address. +type Info struct { + // IP is the IP address. + IP netip.Addr + // ISOCode is the ISO code of the country. + ISOCode string + // Continent is the continent. + Continent string + // Country is the country. + Country string + // City is the city. + City string + // CitySubdivisions is the list of subdivisions. + CitySubdivisions []string + // TimeZone is the time zone. + TimeZone string +} + +// ToString returns a string representation of the Info structure. +func (i Info) ToString() string { + var data []string + + if i.Continent != "" { + data = append(data, i.Continent) + } + + if i.ISOCode != "" { + data = append(data, i.ISOCode) + } + + if i.Country != "" { + data = append(data, i.Country) + } + + if len(i.CitySubdivisions) > 0 { + data = append(data, strings.Join(i.CitySubdivisions, ", ")) + } + + if i.City != "" { + data = append(data, i.City) + } + + return fmt.Sprintf("%s (%s) time zone: %s", + i.IP.String(), + strings.Join(data, "/"), + i.TimeZone, + ) +} + +// GeoIP2 is an interface for geoip2. +type GeoIP2 interface { + Info(ip netip.Addr) (Info, error) +} + +// RefreshableGeoIP2 is an interface for geoip2 with refresh and close functionality. +type RefreshableGeoIP2 interface { + GeoIP2 + Refresh(ctx context.Context) error + Close() error +} + +// Logger is an interface for logging. +type Logger interface { + // Error logs an error. + Error(err error) +}