Skip to content

gamut-iptc: should extension structure emission be fallible? #573

Description

@justin13888

gamut_iptc::extension's to_xmp methods are infallible: they return an XmpValue, matching
gamut_exif::GpsInfo::to_ifd's shape. That leaves them with no way to report a value they cannot
express, so the only choices at such a value are to write something the declared type does not
admit, or to drop it.

PR #540 took the second: put_number now skips a non-finite coordinate (NaN, ±inf) instead of
writing the text NaN/inf/-inf, which is not an XMP Real and which nothing reads back as a
number. That is the right default — a graph that says nothing is better than a graph that lies —
but it is still a silent drop through safe public API, and the caller who set the field is not told.

The question this issue holds open: should structure emission become fallible instead?

Sketch of the fork:

  • Keep it infallible, skip and document (what ships today). Cheapest, keeps the GpsInfo shape
    the crate deliberately mirrors, and keeps a to_xmp() usable in an expression. A caller who
    hands in f64::NAN gets no signal.
  • Return Result<XmpValue, IptcError>. Honest, and consistent with the crate's strict-write
    posture elsewhere (IptcWriter rejects an overlong or unencodable value rather than truncating).
    It is a breaking change to a published v1 crate — to_xmp is public on seven types — and it
    makes the setters on PhotoMetadata fallible too, or forces them to swallow the error.
  • Make the coordinate fields un-representable-if-invalid (a Finite(f64) newtype, or private
    fields with a checked constructor). No error type, no breaking signature, but a heavier public
    API for what is otherwise plain data, and it diverges from the "configs are plain data" convention
    in AGENTS.md.

Whichever way it goes, it should be decided once for the whole extension module rather than per
field, and the same answer should cover the other value a projection cannot express (a numeric field
whose text does not parse, which reads as absent today).

Scope: crates/gamut-iptc/src/extension.rs. Refs #422, and PR #540 where the current behaviour and
its test (a_non_finite_coordinate_is_not_written) landed.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions