Repository navigation
Adds decoding and the validity checks - #6
Merged
Merged
Conversation
Uxid.decode reads an id back to a sealed DecodeResult: a Decoded record with the prefix, size, time form, deterministic flag and time, or an Invalid record whose InvalidReason carries the wire format's refusal name. Malformed input is answered, never thrown, and the refusals are checked in the spec's order: empty, invalid_length, invalid_character, with the length counted in UTF-8 bytes. DecodeOptions takes the delimiter and a java.time.Clock. A compact time takes its high bits from the clock and steps back one 2^40 ms window when it would be more than a day ahead, with no clamp at zero, so a clock in the first window gives a negative time. The tests pin both ends of the corpus clock window from the corpus README's arithmetic. Uxid.isValid takes a delimiter and an optional required prefix and Uxid.isDeterministic takes a delimiter; neither reads a clock. Refs: uxjv-nyt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The package could generate ids but not read them back. A caller needs to decode an id to what it says about itself, and to ask the two common questions of a string (is it a well-formed id, is it a deterministic one) without handling an exception for ordinary malformed input.
What
Uxid.decode(String)andUxid.decode(String, DecodeOptions)return a sealedDecodeResult: aDecodeResult.Decodedrecord (prefix, size, compact flag, deterministic flag, time in milliseconds) or aDecodeResult.Invalidrecord whoseInvalidReasonhas awireName()ofempty,invalid_lengthorinvalid_character. Malformed input is answered, never thrown; the refusals are checked in the wire format's order, with the body length counted in UTF-8 bytes.DecodeOptions(a builder, likeUxidOptions) takes the delimiter and ajava.time.Clock; the default is_andClock.systemUTC(), read inside the call and only for a compact body.Uxid.isValid(id)andUxid.isValid(id, delimiter, requiredPrefix);Uxid.isDeterministic(id)andUxid.isDeterministic(id, delimiter). Each is "decode answers aDecoded" (plus the prefix match, or the marker); neither reads a clock.The Java API shape (static methods on
Uxid, the sealed result of two records, theInvalidReasonenum, the clock ajava.time.Clock) was decided by the conductor under a standing consent, 2026-10-21.Tests
decode.jsoncase and every decode refusal ofinvalid.jsonfrom the uxid-ex v2.10.0 corpus, each named by its case id. The decode cases run at both ends of the corpus clock window.usr_hf7yat0004hm5as -499023255552 ms), as is a clock before the epoch and a clock that is never read for a standard, deterministic or refused body.Notes
Choices the bead did not fix, each taken as the reference or the spec reads:
id, delimiter or options throwsNullPointerException, the Java convention; an empty delimiter throwsIllegalArgumentExceptionfromDecodeOptions.Builder.delimiter,isValidandisDeterministic, asUxidOptionsalready does. Only the string being decoded is "malformed input".Decodedholds no bytes: the wire format says a decoder does not report the random field, so there is no array component and no equals or hashCode concern. The prefix is anOptional<String>and the time anOptionalLong, so the record carries no nulls; its constructor refuses null components.--the stringusr---01hf7yat00splits afterusr. An id that starts with the delimiter has the prefix"", as the spec says.valid?does.isValidandisDeterministicrequire a well-formed body (the reference'sdeterministic?reads only the first body character); this matches the released ports.Gate:
mise run gategreen on this head (format check, compile with Error Prone, tests, JaCoCo, the javadoc and sources jars).Closes uxjv-nyt