Class ChoiceCodec.Builder<T,V>
- Type Parameters:
T- the tag typeV- the base type of the discriminated union
- Enclosing class:
ChoiceCodec<T,V>
ChoiceCodec.-
Method Summary
Modifier and TypeMethodDescriptionbuild()Builds the choice codec.<S extends V>
ChoiceCodec.Builder<T, V> Registers an alternative.<U extends V>
ChoiceCodec.Builder<T, V> Registers a fallback for alternatives that are not registered, so unknown types round trip instead of failing.
-
Method Details
-
on
Registers an alternative.- Type Parameters:
S- the subtype- Parameters:
tag- the tag identifying this alternative on the wiretype- the class of values for this alternativecodec- the codec for values of this class- Returns:
- this builder
- Throws:
NullPointerException- if tag, type or codec is nullIllegalArgumentException- if the tag or the type is already registered, or if the tag is an array
-
otherwise
public <U extends V> ChoiceCodec.Builder<T,V> otherwise(Class<U> type, Function<U, T> tagOf, Function<T, Codec<U>> body) Registers a fallback for alternatives that are not registered, so unknown types round trip instead of failing.Three things are needed, and each is used in both directions: the class recognises an unknown value when encoding,
tagOfsupplies the tag to write for it, andbodybuilds the codec for the bytes after the tag. Because the tag comes from the value rather than from the wire, nothing has to be rewound, so a choice codec never constrains the stream it is given..otherwise( Unknown.class, Unknown::tag, tag -> Codecs.binary().xmap(body -> new Unknown(tag, body), Unknown::body))Declaring the class keeps encoding checked: a value that is neither registered nor an instance of this type raises a
CodecExceptionnaming it, rather than reaching a codec that cannot handle it. AtagOfthat returns a tag already registered is rejected too, since those bytes would read back as that other alternative.The tag is re-encoded from the decoded value rather than replayed, so byte-for-byte passthrough of an unknown alternative holds exactly when the tag codec round trips — as every tag codec in this library does.
A body codec that reads to end-of-stream needs a bounded scope — inside
Codecs.prefixed(Codec, Codec)orCodecs.terminated(Codec, byte[]), which hand down a bounded stream — since an unknown alternative has unknown extent.- Type Parameters:
U- the fallback subtype- Parameters:
type- the class of values this fallback produces and encodestagOf- returns the tag to write for a value of that classbody- returns the codec for the body following a given tag- Returns:
- this builder
- Throws:
NullPointerException- if any argument is nullIllegalArgumentException- if a fallback is already registered, or if the type is already registered as an alternative
-
build
Builds the choice codec.- Returns:
- a new choice codec
- Throws:
IllegalArgumentException- if no alternatives have been registered
-