jsonfg 0.1.0

Types for OGC Features and Geometries JSON (JSON-FG), a GeoJSON superset with support for arbitrary coordinate reference systems, solids, and curved geometries.
Documentation
# AGENTS.md

Guidance for AI coding agents working in this repository.

## What this is

`jsonfg` is a Rust crate providing serde-based data types for **OGC Features and
Geometries JSON** ([JSON-FG], OGC 21-045r1 v1.0), a strict superset of GeoJSON. It is the
JSON-FG counterpart to the [`geojson`] crate: a pure data model with **no I/O, no HTTP,
and no content negotiation**. Its defining job is **lossless round-tripping** of JSON-FG
documents.

- Single crate (not a workspace), edition 2024, MSRV 1.85.
- `#![forbid(unsafe_code)]` — do not introduce `unsafe`.
- Published to crates.io as `jsonfg`; docs on docs.rs.

## Layout

| Path | Contents |
|------|----------|
| `src/lib.rs` | Crate root, module wiring, public re-exports, crate-level docs |
| `src/feature.rs` | `Feature`, `FeatureType`, `FeatureSchema`, `Id` |
| `src/feature_collection.rs` | `FeatureCollection` |
| `src/geometry.rs` | `Geometry` enum (all types), `Position`, `Bbox`, geojson conversions |
| `src/crs.rs` | `CoordRefSys`, `RefSys`, `Reference`, `CRS84`/`CRS84H` constants |
| `src/measures.rs` | `Measures` |
| `src/time.rs` | `Time`, `UNBOUNDED` |
| `src/conformance.rs` | Conformance-class URI constants and the media type |
| `tests/roundtrip.rs` | Round-trip fixtures for members and geometry types |
| `examples/validate.rs` | CLI to round-trip every `*.json` in a directory |

## Core invariants — do not break these

1. **Lossless round-trip.** Deserialize → serialize must produce a semantically identical
   document: no members dropped, none spuriously added. Unknown/foreign members (e.g. OGC
   API `links`) are preserved verbatim. Any new field must round-trip.
2. **Member ordering is preserved.** `serde_json` is used with `preserve_order`. Keep it.
3. **The `place` / `geometry` split.** WGS 84 geometry goes in GeoJSON `geometry`; native
   geometry in any other CRS or of a non-GeoJSON type goes in `place` with `coordRefSys`.
   Don't collapse or auto-convert between them.
4. **GeoJSON compatibility.** A JSON-FG document must still parse as GeoJSON; JSON-FG
   additions are foreign members. The `geojson` feature is optional and additive — arcs
   and solids have no GeoJSON equivalent and return `NotGeoJson` when converting *to*
   GeoJSON.
5. **Spec fidelity.** Field names, conformance URIs, and the media type come from the
   normative spec ([21-045r1]). When in doubt, match the spec text, not intuition.

## Workflow

Before proposing a change as done, all of these must pass (this is exactly what CI runs):

```sh
cargo fmt --all --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test
cargo test --all-features
```

- Add a round-trip fixture in `tests/roundtrip.rs` for any new member or geometry type.
- Prefer validating against the normative OGC example corpus via `cargo run --example
  validate -- <dir>` when touching parsing/serialization.
- Keep public items documented; doc examples are compiled as tests.

## Conventions

- Match the surrounding style: doc comments on public items, terse module-level `//!`
  headers explaining the *why*.
- Serde attributes carry the spec's exact JSON member names (`rename`,
  `skip_serializing_if`, `#[serde(flatten)]` for foreign members). Changing these is a
  breaking, spec-visible change.
- This is a released library: public API changes are semver-relevant. CI runs
  `cargo-semver-checks` on PRs — an intentional break needs a matching version bump.
- Record user-facing changes in `CHANGELOG.md` under `[Unreleased]` as you make them
  ([Keep a Changelog] format).

## Releasing

See the "Releasing" section of `README.md`. In short: releases publish via GitHub
Actions using crates.io **Trusted Publishing (OIDC)** — no API token secret. Tag `vX.Y.Z`,
publish a GitHub Release, and `.github/workflows/publish.yaml` builds and publishes.

[JSON-FG]: https://docs.ogc.org/is/21-045r1/21-045r1.html
[21-045r1]: https://docs.ogc.org/is/21-045r1/21-045r1.html
[`geojson`]: https://docs.rs/geojson
[Keep a Changelog]: https://keepachangelog.com/en/1.1.0/