feat: typed Choice<E> and ChoiceAnswer<E> with enum constants as labels - #15
Merged
Merged
Conversation
…abels Choice<E> and ChoiceAnswer<E> carry the label type. An enum builds the question from its constants and reads the answer back as that enum, so a misspelled label is a compile error, probabilities are keyed by the constants in declaration order, and a switch over the answer is exhaustive. String labels infer Choice<String> and read back unchanged. The wire form is the same either way: the label is the constant's name. ChoiceAnswer's type parameter changes the erased return type of choice(), so consumers of 0.4.0 and earlier must recompile (#10).
garretpremo
added a commit
that referenced
this pull request
Sep 22, 2026
Choice<E> and ChoiceAnswer<E> carry the label type: build a question from an enum's constants and read the answer back as that enum, with probabilities keyed by it. String labels are unchanged. ChoiceAnswer's type parameter changes the erased return type of choice(), so consumers of 0.4.0 and earlier must recompile (#10, #15). ScoreAnswer.legend is Map<String, Object>, so a Score with an object or array level no longer fails the whole response (#11, #13). A response missing usage, or a usage missing a token count, fails with a TypeSafeException naming the field instead of reading as null or 0 (#12, #14). READMEs point at 0.5.0.
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.
Motivation:
Implements the design accepted on #10: the Java rendering of the JS SDK's
ChoiceResponse<T>. A misspelled label becomes a compile error, probabilities are keyed by the enum, and aswitchover the answer is exhaustive.Changes:
Choice<E>:of(instructions, Dept.class)builds one option per constant;builder(Dept.class)takesoption(Dept.X, …)for a subset with descriptions.of(…, String...),of(…, Map), and the existing builder inferChoice<String>. Record components are unchanged, so the wire form is identical.ChoiceAnswer<E>:as(Dept.class)converts a String-labelled answer to the enum, with probabilities in anEnumMapin declaration order. An unknown label throwsIllegalArgumentExceptionnaming the label and the enum's constants.TypeSafeResponse.choice(key, Dept.class);choice(key)returnsChoiceAnswer<String>andchoices()returnsMap<String, ChoiceAnswer<String>>.TypeSafeRequest.Builder.choice(key, Dept.class, c -> …)alongside the existing String form.Breaking:
ChoiceAnswergained a type parameter, which changes the erased return type ofchoice(). Consumers must recompile; a rawChoiceAnswerneeds<String>orvar.Fixes #10