Skip to content

feat: add Kotlin DSL sugar, URI templates, and a kotlinx.serialization bridge#74

Merged
OmarAlJarrah merged 4 commits into
mainfrom
refactor/fold-ktx-template-drop-psl
Jul 15, 2026
Merged

feat: add Kotlin DSL sugar, URI templates, and a kotlinx.serialization bridge#74
OmarAlJarrah merged 4 commits into
mainfrom
refactor/fold-ktx-template-drop-psl

Conversation

@OmarAlJarrah

@OmarAlJarrah OmarAlJarrah commented Jul 15, 2026

Copy link
Copy Markdown
Member

Summary

  • Adds Kotlin DSL/operator sugar over Url/Uri (buildUrl {}, Url.edit {}, path/query operators) under org.dexpace.kuri.ktx, and RFC 6570 URI Template support (UriTemplate.parse/expand/match) under org.dexpace.kuri.template — both as part of the core kuri module, since neither needs an external dependency or an independent release cadence to justify a separate artifact.
  • A Public Suffix List prototype was evaluated alongside these but dropped — it only had a placeholder rule set with no data generator behind it, so it wasn't ready to ship.
  • Adds a new module, kuri-serde-kotlinx, bridging kuri's Url/Uri to kotlinx.serialization: UrlSerializer/UriSerializer KSerializers, plus QueryParametersFormat for encoding/decoding QueryParameters to/from flat @Serializable data classes. Named kuri-serde-kotlinx (not just kuri-serialization) to leave room for other JSON-library backends later.
  • Regenerates the JVM/Android/klib API dumps for the new ktx/template symbols, and adds an initial JVM API dump for kuri-serde-kotlinx.
  • Adds test coverage for template edge cases (malformed expressions, non-ASCII percent-encoding, uninvertible match() inputs), and for kuri-serde-kotlinx paths (scalar/list round-trips, nested-object rejection, missing-parameter and invalid-input decode failures).

Test plan

  • :kuri:jvmTest, :kuri:ktlintCheck, :kuri:detekt
  • :kuri:apiCheck (jvm, android, klib)
  • :kuri:koverVerify
  • :kuri:jsNodeTest, :kuri:wasmJsNodeTest, native compile/test (macOS)
  • :kuri-serde-kotlinx:jvmTest, :kuri-serde-kotlinx:ktlintCheck, :kuri-serde-kotlinx:detekt
  • :kuri-serde-kotlinx:apiCheck, :kuri-serde-kotlinx:koverVerify
  • :kuri-serde-kotlinx:jsNodeTest, :kuri-serde-kotlinx:wasmJsNodeTest, native test (macOS)

@OmarAlJarrah OmarAlJarrah changed the title refactor: fold kuri-ktx and kuri-template into kuri, drop kuri-psl refactor: reorganize kuri's satellite Gradle modules Jul 15, 2026
Adds Kotlin-idiomatic DSL/operator sugar for building and editing Url/Uri
values (buildUrl {}, Url.edit {}, path/query operators) and RFC 6570 URI
Template support (UriTemplate.parse/expand/match), under
org.dexpace.kuri.ktx and org.dexpace.kuri.template. Neither needs an
external dependency or an independent release cadence, so they ship as
part of the core kuri artifact rather than as separate modules.

A Public Suffix List prototype was evaluated alongside these but dropped —
it only had a placeholder rule set with no data generator behind it, so it
wasn't ready to ship.

Regenerates the JVM/Android/klib API dumps for the new ktx/template
symbols and adds test coverage for template edge cases (malformed
expressions, non-ASCII percent-encoding, uninvertible match() inputs).
Adds UrlSerializer/UriSerializer KSerializers so Url and Uri round-trip
through any kotlinx.serialization format via their canonical string form,
plus QueryParametersFormat for encoding and decoding QueryParameters
to and from flat @serializable data classes.

Named kuri-serde-kotlinx (package org.dexpace.kuri.serde) to leave room
for other JSON-library backends later without the name implying it's the
only serialization integration kuri has.

Also fixes lint, detekt, and coverage gaps that surfaced once the module
was actually wired into settings.gradle.kts and run through the gate for
the first time.
@OmarAlJarrah
OmarAlJarrah force-pushed the refactor/fold-ktx-template-drop-psl branch from 82c0c2d to 14c5b49 Compare July 15, 2026 11:00
@OmarAlJarrah OmarAlJarrah changed the title refactor: reorganize kuri's satellite Gradle modules feat: add Kotlin DSL sugar, URI templates, and a kotlinx.serialization bridge Jul 15, 2026
The variable-name parser accepted names RFC 6570's grammar forbids
(varname = varchar *( ["."] varchar )): a leading, trailing, or doubled
dot, e.g. ".foo", "foo.", "a..b". validateName now walks the name as a
sequence of varchars with an optional single dot strictly between two
of them, matching the grammar exactly.

match() also mis-scoped its "trailing query expression" detection: it
treated any operator with named=true (which includes ";", not just "?"
and "&") as the query to invert. Since ";" renders as ";key=value" path
segments rather than a "?"-delimited query string, this let a lone
trailing ";" expression get dropped from the path pattern while the
query-side matcher short-circuited on an empty query, so matching the
empty string against a template like "{;a}" wrongly reported a match
with no bound variables instead of no match at all. Restricting the
check to the QUERY/CONTINUATION operators fixes this.
QueryEncoder didn't override shouldEncodeElementDefault, so kotlinx
.serialization's inherited default (always encode, even when a
property equals its declared default) applied. Encoding a value that
left optional properties at their defaults spelled every one of them
out (e.g. "q=only&page=1&sort=ASC" instead of just "q=only"), which
is asymmetric with the decode side's documented "absent falls back to
default" contract and produces needlessly verbose query strings.

Overriding it to false mirrors Json's own default (encodeDefaults =
false) and keeps encoded output minimal.
@OmarAlJarrah
OmarAlJarrah merged commit a2feca0 into main Jul 15, 2026
12 checks passed
@OmarAlJarrah
OmarAlJarrah deleted the refactor/fold-ktx-template-drop-psl branch July 15, 2026 11:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant