fix: AshGeo.GeoJson.cast_stored handles GeoJSON maps#14
Conversation
`cast_input/2` decodes GeoJSON-shaped maps (atom- or string-keyed) via
`Geo.JSON.decode/1`, but `cast_stored/2` falls through to the base
`AshGeo.Geometry` implementation, which only accepts `%Geo.*{}` structs
and `nil` — it rejects maps with `:error`.
That breaks any data layer that stores GeoJSON as a map/JSON value, and
in particular any containing type whose nested `AshGeo.GeoJson` field
deserialises to a map on read. For example an `AshGeo.GeoJson` field
inside an `Ash.TypedStruct`: when the struct walks its fields on
cast_stored, the geo field is handed the decoded map and
`AshGeo.GeoJson.cast_stored` returns `:error`, failing the load.
Adds map-handling `cast_stored/2` clauses to `AshGeo.GeoJson.Use`
mirroring the existing `cast_input/2` clauses (same Jason-roundtrip for
atom-keyed maps, same `Geo.JSON.decode` for string-keyed). Geo structs,
nil, and the binary-rejection behaviour are unchanged.
Tests: cast_stored from atom-keyed map, string-keyed map, and nil.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThis PR adds ChangesGeoJSON Stored Value Deserialization
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
Problem
AshGeo.GeoJson.cast_input/2decodes GeoJSON-shaped maps (atom- or string-keyed) viaGeo.JSON.decode/1:But
cast_stored/2is not overridden inAshGeo.GeoJson.Use, so it falls through to the baseAshGeo.Geometryimplementation, which only accepts%Geo.*{}structs andnil:This breaks any data layer that stores GeoJSON as a map/JSON value and hands it back as a map on read. The case that bit me: an
AshGeo.GeoJsonfield nested inside anAsh.TypedStruct. When the TypedStruct walks its fields oncast_stored, the geo field is handed the decoded GeoJSON map andAshGeo.GeoJson.cast_storedreturns:error, failing the whole load — even thoughcast_inputwould have accepted the identical map.Fix
Add map-handling
cast_stored/2clauses toAshGeo.GeoJson.Usemirroring the existingcast_input/2clauses — same Jason round-trip for atom-keyed maps, sameGeo.JSON.decodefor string-keyed maps, falling through tosuper/2for structs/nil/binaries.Tests
Adds
cast_storedcases for atom-keyed map, string-keyed map, and nil, alongside the existing Geo-struct case. Verified locally that Geo struct / nil / binary-rejection behaviour is unchanged.Discovered while adopting AshGeo as the spatial type surface for ash_neo4j (a Neo4j
Ash.DataLayer), which stores geometries as RFC 7946 GeoJSON. Pairs with #13 (the bare-atomgeo_typesformatter crash). Happy to adjust to fit your preferences.Summary by CodeRabbit
Bug Fixes
Tests