Coerce raw URPX parser output into typed Clojure values.
The parser (urpx.core/load-rate-plan) produces a Clojure map with
namespaced keys but all-string leaf values. This namespace applies the
:decode/urpx-jsonld decoders attached to urpx.schema schemas to convert
those strings into BigDecimals, java.time values, Durations, and integer
month numbers — and to normalize fields that URPX permits as either a single
map or a vector of maps.
Coerce raw URPX parser output into typed Clojure values. The parser (`urpx.core/load-rate-plan`) produces a Clojure map with namespaced keys but all-string leaf values. This namespace applies the `:decode/urpx-jsonld` decoders attached to `urpx.schema` schemas to convert those strings into BigDecimals, java.time values, Durations, and integer month numbers — and to normalize fields that URPX permits as either a single map or a vector of maps.
(check-coerced! documents who)Throw unless every document in documents has been coerced.
who names the calling operation in the message. Reading an uncoerced
document does not fail loudly on its own: dates stay strings, so anything
that compares them throws deep inside, and anything that does NOT compare
them quietly answers a different question.
urpx.scenario-cost-model/enumerate returned 202 pairs instead of 144 that
way, a plausible number rather than a refusal.
Throw unless every document in `documents` has been coerced. `who` names the calling operation in the message. Reading an uncoerced document does not fail loudly on its own: dates stay strings, so anything that compares them throws deep inside, and anything that does NOT compare them quietly answers a different question. `urpx.scenario-cost-model/enumerate` returned 202 pairs instead of 144 that way, a plausible number rather than a refusal.
(coerce schema raw)Decode a raw value against schema using the URPX JSON-LD transformer.
Returns the typed value. Use validate afterwards if you want a strict check.
Decode a raw value against `schema` using the URPX JSON-LD transformer. Returns the typed value. Use `validate` afterwards if you want a strict check.
(coerce-doc raw)Dispatch on the document's :jsonld/type and coerce as a RatePlan, RatePlanModifier, wrapper (urpx:URPXDocument in v0.2.x, urpx:URPXPackage from v0.3.0 on), a top-level version snapshot (urpx:RatePlanVersion / urpx:RatePlanModifierVersion, which v0.5.1 documents may carry as siblings of the identity entity rather than nested inside it), or a urpx:ScenarioCostModel. Returns nil for unknown types.
Dispatch on the document's :jsonld/type and coerce as a RatePlan, RatePlanModifier, wrapper (urpx:URPXDocument in v0.2.x, urpx:URPXPackage from v0.3.0 on), a top-level version snapshot (urpx:RatePlanVersion / urpx:RatePlanModifierVersion, which v0.5.1 documents may carry as siblings of the identity entity rather than nested inside it), or a urpx:ScenarioCostModel. Returns nil for unknown types.
(coerce-rate-plan raw)Coerce a raw parsed URPX rate plan into the typed shape described by
urpx.schema/RatePlan.
Coerce a raw parsed URPX rate plan into the typed shape described by `urpx.schema/RatePlan`.
(coerce-rate-plan-modifier raw)Coerce a raw parsed URPX rate plan modifier into the typed shape described
by urpx.schema/RatePlanModifier. Modifier docs (EEC, NSE, HRA fixtures)
augment or override parts of an existing RatePlan; price resolution against
a modifier alone is not (yet) supported.
Coerce a raw parsed URPX rate plan modifier into the typed shape described by `urpx.schema/RatePlanModifier`. Modifier docs (EEC, NSE, HRA fixtures) augment or override parts of an existing RatePlan; price resolution against a modifier alone is not (yet) supported.
(coerce-rate-plan-modifier-version raw)Coerce a raw top-level urpx:RatePlanModifierVersion snapshot. Parallel to
coerce-rate-plan-version; the back pointer is urpx:forRatePlanModifier.
Coerce a raw top-level urpx:RatePlanModifierVersion snapshot. Parallel to `coerce-rate-plan-version`; the back pointer is urpx:forRatePlanModifier.
(coerce-rate-plan-version raw)Coerce a raw top-level urpx:RatePlanVersion snapshot. v0.5.1 documents may
carry the version as a sibling of the identity RatePlan rather than nested
inside it; urpx.index/versions-by-plan finds it via urpx:forRatePlan.
Coerce a raw top-level urpx:RatePlanVersion snapshot. v0.5.1 documents may carry the version as a sibling of the identity RatePlan rather than nested inside it; `urpx.index/versions-by-plan` finds it via urpx:forRatePlan.
(coerce-scenario-cost-model raw)Coerce a raw urpx:ScenarioCostModel node into the typed shape described by
urpx.schema/ScenarioCostModel.
Coerce a raw urpx:ScenarioCostModel node into the typed shape described by `urpx.schema/ScenarioCostModel`.
(coerce-urpx-document raw)Coerce a raw parsed URPX document wrapper into the typed shape described
by urpx.schema/URPXDocument. Validates the document-level metadata
(urpx:targetURPXVersion, dates, version, …) — inner urpx:hasRatePlan /
urpx:hasRatePlanModifier payloads are passed through as raw maps and
should be coerced + validated against their own schemas separately.
Coerce a raw parsed URPX document wrapper into the typed shape described by `urpx.schema/URPXDocument`. Validates the document-level metadata (urpx:targetURPXVersion, dates, version, …) — inner urpx:hasRatePlan / urpx:hasRatePlanModifier payloads are passed through as raw maps and should be coerced + validated against their own schemas separately.
(coerce-urpx-package raw)Coerce a raw parsed URPX package wrapper into the typed shape described by
urpx.schema/URPXPackage, the v0.3.0 rename of urpx:URPXDocument. Same
wrapper-level contract as coerce-urpx-document: inner payloads
(urpx:hasRatePlan / urpx:hasRatePlanModifier / urpx:packages) pass through
as raw maps and should be coerced against their own schemas separately.
Coerce a raw parsed URPX package wrapper into the typed shape described by `urpx.schema/URPXPackage`, the v0.3.0 rename of urpx:URPXDocument. Same wrapper-level contract as `coerce-urpx-document`: inner payloads (urpx:hasRatePlan / urpx:hasRatePlanModifier / urpx:packages) pass through as raw maps and should be coerced against their own schemas separately.
(encode schema typed)Encode a typed value against schema using the URPX JSON-LD transformer.
Inverse of coerce — turns BigDecimal/LocalDate/etc. back into the JSON-LD
string forms for the write side. Schemas without an :encode/urpx-jsonld
property pass values through unchanged (:default-encoder identity).
Encode a typed value against `schema` using the URPX JSON-LD transformer. Inverse of `coerce` — turns BigDecimal/LocalDate/etc. back into the JSON-LD string forms for the write side. Schemas without an :encode/urpx-jsonld property pass values through unchanged (`:default-encoder identity`).
(explain schema value)Return a Malli explanation for why value does not validate against schema,
or nil if it does.
Return a Malli explanation for why `value` does not validate against `schema`, or nil if it does.
(temporal-signature doc)Walk doc and report what temporal literals it carries:
{:times #{} :dates #{} :date-times #{} :date-shaped-strings n}.
:times holds LocalTimes and OffsetTimes, :date-times LocalDateTimes and
ZonedDateTimes.
By java.time TYPE rather than by property name, deliberately. A name list would have to be kept in step with the vocabulary, and the one it missed would be a missing value rather than a loud failure.
THE ONE IMPLEMENTATION of this walk. urpx.schedule harvests boundary
candidates from it and urpx.scenario-cost-model uses it only to tell a
coerced document from an uncoerced one; two copies of the test is two
chances to disagree about what "coerced" means.
Walk `doc` and report what temporal literals it carries:
`{:times #{} :dates #{} :date-times #{} :date-shaped-strings n}`.
`:times` holds LocalTimes and OffsetTimes, `:date-times` LocalDateTimes and
ZonedDateTimes.
By java.time TYPE rather than by property name, deliberately. A name list
would have to be kept in step with the vocabulary, and the one it missed
would be a missing value rather than a loud failure.
THE ONE IMPLEMENTATION of this walk. `urpx.schedule` harvests boundary
candidates from it and `urpx.scenario-cost-model` uses it only to tell a
coerced document from an uncoerced one; two copies of the test is two
chances to disagree about what "coerced" means.(uncoerced? doc)True if doc has the SIGNATURE of a document that was never coerced: it
carries date-shaped strings and no java.time values anywhere at all.
It is NOT enough that a date-shaped string exists. urpx:version is
rdfs:range xsd:string and filings use the effective date as the version
LABEL, so "2026-03-20" is a perfectly coerced string. A shape-based test
on strings alone rejected real modifier filings when urpx.schedule first
tried it, which is why the test is the ABSENCE of real temporals rather than
the presence of a string.
A document with no temporal content at all is not uncoerced, merely empty of dates, and reports false.
True if `doc` has the SIGNATURE of a document that was never coerced: it carries date-shaped strings and no java.time values anywhere at all. It is NOT enough that a date-shaped string exists. urpx:version is `rdfs:range xsd:string` and filings use the effective date as the version LABEL, so "2026-03-20" is a perfectly coerced string. A shape-based test on strings alone rejected real modifier filings when `urpx.schedule` first tried it, which is why the test is the ABSENCE of real temporals rather than the presence of a string. A document with no temporal content at all is not uncoerced, merely empty of dates, and reports false.
(validate schema value)Validate value against schema. Returns true on success.
Validate `value` against `schema`. Returns true on success.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |