gamut-xmp registers Darwin Core as http://rs.tdwg.org/dwc/index.htm, and WellKnownNs::from_uri
additionally recognises http://rs.tdwg.org/dwc/index.htm/ (DWC_URI_TRAILING_SLASH) as a
read alias, because exiv2 appends / to any namespace URI ending in neither / nor # before
registering it with XMPCore (third_party/exiv2/src/properties.cpp, XmpProperties::registerNs),
and Darwin Core is the only registered schema whose URI ends in neither.
The alias resolves a prefix, not a URI. Reading does not canonicalize: the parsed graph keeps
the slashed URI its packet declared, and XmpMeta::to_packet writes that URI straight back. So for
a packet an exiv2/XMPCore writer produced:
- the graph re-serializes under the
dwc prefix rather than a synthesized ns1 — the intended win;
meta.get_text(WellKnownNs::DarwinCore.uri(), "Record") returns None, while
meta.get_text(DWC_URI_TRAILING_SLASH, "Record") returns the value.
That is the naive use of the registry, and it is the asymmetry this option would close.
The option
Canonicalize the URI on read: when the reader resolves a declared namespace URI through
WellKnownNs::from_uri, store ns.uri() in the graph instead of the declared string, so a caller
can always resolve a well-known property by WellKnownNs::….uri() regardless of which spelling the
writer used.
Why it is not done today
Identity preservation is this crate's consistent posture: rewriting a caller's URI to the registered
form would change bytes exiv2 wrote, so a packet read and written back would no longer be
byte-identical to its input for the one schema affected. Prefix fidelity was the stated intent of
the alias, and no consumer needs URI canonicalization yet.
What it would leave asymmetric either way
- As today:
from_uri(u).map(WellKnownNs::uri) == Some(u) holds for every registry entry and
not for the alias — pinned by
crates/gamut-xmp/src/namespace.rs::the_trailing_slash_alias_is_the_only_uri_from_uri_does_not_hand_back.
Callers must resolve by the URI the packet carries.
- If canonicalized: the graph would no longer be a faithful record of the bytes read, and
round-tripping an exiv2-written dwc packet would change its namespace URI. Any such change needs
to say which of the two properties it is giving up, and would want a knob (a ConvertPolicy-style
opt-in) rather than a silent rewrite.
Acceptance, if taken
- A decision recorded in
crates/gamut-xmp/STATUS.md naming which property is given up.
- Either behaviour pinned by a test that reads an XMPCore-written
dwc packet and asserts the URI
the graph carries.
README.md, STATUS.md and WellKnownNs::from_uri's own documentation updated together — that
documentation is where a caller meets the trap.
Raised while reviewing #507 (issue #421). No code change is proposed here; this records the option
and the asymmetry so a consumer that needs it has somewhere to say so.
gamut-xmpregisters Darwin Core ashttp://rs.tdwg.org/dwc/index.htm, andWellKnownNs::from_uriadditionally recognises
http://rs.tdwg.org/dwc/index.htm/(DWC_URI_TRAILING_SLASH) as aread alias, because exiv2 appends
/to any namespace URI ending in neither/nor#beforeregistering it with XMPCore (
third_party/exiv2/src/properties.cpp,XmpProperties::registerNs),and Darwin Core is the only registered schema whose URI ends in neither.
The alias resolves a prefix, not a URI. Reading does not canonicalize: the parsed graph keeps
the slashed URI its packet declared, and
XmpMeta::to_packetwrites that URI straight back. So fora packet an exiv2/XMPCore writer produced:
dwcprefix rather than a synthesizedns1— the intended win;meta.get_text(WellKnownNs::DarwinCore.uri(), "Record")returnsNone, whilemeta.get_text(DWC_URI_TRAILING_SLASH, "Record")returns the value.That is the naive use of the registry, and it is the asymmetry this option would close.
The option
Canonicalize the URI on read: when the reader resolves a declared namespace URI through
WellKnownNs::from_uri, storens.uri()in the graph instead of the declared string, so a callercan always resolve a well-known property by
WellKnownNs::….uri()regardless of which spelling thewriter used.
Why it is not done today
Identity preservation is this crate's consistent posture: rewriting a caller's URI to the registered
form would change bytes exiv2 wrote, so a packet read and written back would no longer be
byte-identical to its input for the one schema affected. Prefix fidelity was the stated intent of
the alias, and no consumer needs URI canonicalization yet.
What it would leave asymmetric either way
from_uri(u).map(WellKnownNs::uri) == Some(u)holds for every registry entry andnot for the alias — pinned by
crates/gamut-xmp/src/namespace.rs::the_trailing_slash_alias_is_the_only_uri_from_uri_does_not_hand_back.Callers must resolve by the URI the packet carries.
round-tripping an exiv2-written
dwcpacket would change its namespace URI. Any such change needsto say which of the two properties it is giving up, and would want a knob (a
ConvertPolicy-styleopt-in) rather than a silent rewrite.
Acceptance, if taken
crates/gamut-xmp/STATUS.mdnaming which property is given up.dwcpacket and asserts the URIthe graph carries.
README.md,STATUS.mdandWellKnownNs::from_uri's own documentation updated together — thatdocumentation is where a caller meets the trap.
Raised while reviewing #507 (issue #421). No code change is proposed here; this records the option
and the asymmetry so a consumer that needs it has somewhere to say so.