diff --git a/tools/types/geo_point.go b/tools/types/geo_point.go index 647dbabc..286120d0 100644 --- a/tools/types/geo_point.go +++ b/tools/types/geo_point.go @@ -22,6 +22,15 @@ func (p GeoPoint) String() string { return string(raw) } +// AsMap implements [core.mapExtractor] and returns a value suitable +// to be used in an API rule expression. +func (p GeoPoint) AsMap() map[string]any { + return map[string]any{ + "lon": p.Lon, + "lat": p.Lat, + } +} + // Value implements the [driver.Valuer] interface. func (p GeoPoint) Value() (driver.Value, error) { data, err := json.Marshal(p) diff --git a/tools/types/geo_point_test.go b/tools/types/geo_point_test.go index 5ee3990e..fa7c5d5a 100644 --- a/tools/types/geo_point_test.go +++ b/tools/types/geo_point_test.go @@ -7,6 +7,40 @@ import ( "github.com/pocketbase/pocketbase/tools/types" ) +func TestGeoPointAsMap(t *testing.T) { + t.Parallel() + + scenarios := []struct { + name string + point types.GeoPoint + expected map[string]any + }{ + {"zero", types.GeoPoint{}, map[string]any{"lon": 0.0, "lat": 0.0}}, + {"non-zero", types.GeoPoint{Lon: -10, Lat: 20.123}, map[string]any{"lon": -10.0, "lat": 20.123}}, + } + + for _, s := range scenarios { + t.Run(s.name, func(t *testing.T) { + result := s.point.AsMap() + + if len(result) != len(s.expected) { + t.Fatalf("Expected %d keys, got %d: %v", len(s.expected), len(result), result) + } + + for k, v := range s.expected { + found, ok := result[k] + if !ok { + t.Fatalf("Missing expected %q key: %v", k, result) + } + + if found != v { + t.Fatalf("Expected %q key value %v, got %v", k, v, found) + } + } + }) + } +} + func TestGeoPointStringAndValue(t *testing.T) { t.Parallel()