Interface Codec<A>

Type Parameters:
A - the type to encode and decode
All Superinterfaces:
Decoder<A>, Encoder<A>
All Known Subinterfaces:
PrimitiveCodec<A>
All Known Implementing Classes:
CompoundListCodec, EitherCodec, ListCodec, MapCodec.MapCodecCodec, PairCodec, UnboundedMapCodec

public interface Codec<A> extends Encoder<A>, Decoder<A>
A combined Encoder and Decoder which can convert objects to and from a serialized form. A codec is one of the core components of DFU's serialization API. Conceptually, a codec generally represents a series of two-way transformations going from the serialized form to the object type, going through any number of intermediate steps.

Codecs are normally built through methods that combine or transform existing codecs. The Codec class contains a number of built-in codecs for simple types, such as STRING; while more complicated codecs can be created by implementing the interface directly, it is often easier to use the built-in methods to combine or transform existing codecs. Some common tools for building codecs include:

To transform codecs for an existing type, by providing functions to convert between the two types, several options are available: If the serialized form of your data involves a known set of keys in a map, or if your data has a record-like structure, you will likely want to look into the various ways of creating a MapCodec and RecordCodecBuilder. Codecs are quite versatile, and a variety of other implementations exist.
See Also:
  • Field Details

  • Method Details

    • withLifecycle

      default Codec<A> withLifecycle(Lifecycle lifecycle)
      Produces a new codec with the given Lifecycle.
      Specified by:
      withLifecycle in interface Decoder<A>
      Specified by:
      withLifecycle in interface Encoder<A>
      Parameters:
      lifecycle - the lifecycle to apply to the new codec
      Returns:
      a new codec
    • stable

      default Codec<A> stable()
      Returns a version of this codec with the stable lifecycle.
      Returns:
      a version of this codec with the stable lifecycle
      See Also:
    • deprecated

      default Codec<A> deprecated(int since)
      Returns a version of this codec with a deprecated lifecycle.
      Returns:
      a version of this codec with a deprecated lifecycle
      See Also:
    • of

      static <A> Codec<A> of(Encoder<A> encoder, Decoder<A> decoder)
      Returns a new codec with the behavior of the given encoder and decoder.
      Type Parameters:
      A - the type to encode and decode
      Parameters:
      encoder - used to encode objects to a serialized form
      decoder - used to decode objects from a serialized form
      Returns:
      a new codec with the behavior of the given encoder and decoder
    • of

      static <A> Codec<A> of(Encoder<A> encoder, Decoder<A> decoder, String name)
      Returns a new codec with the behavior of the given encoder and decoder, with a custom name.
      Type Parameters:
      A - the type to encode and decode
      Parameters:
      encoder - used to encode objects to a serialized form
      decoder - used to decode objects from a serialized form
      name - the name of the codec when printed
      Returns:
      a new codec with the behavior of the given encoder and decoder, with a custom name
    • of

      static <A> MapCodec<A> of(MapEncoder<A> encoder, MapDecoder<A> decoder)
      Creates a new MapCodec by combining a MapEncoder and MapDecoder.
      Type Parameters:
      A - the type to encode and decode
      Parameters:
      encoder - used to encode objects to key-value pairs in a serialized form
      decoder - used to decode objects from a serialized form
      Returns:
      a new map MapCodec with the behavior of the given encoder and decoder
    • of

      static <A> MapCodec<A> of(MapEncoder<A> encoder, MapDecoder<A> decoder, Supplier<String> name)
      Creates a new MapCodec by combining a MapEncoder and MapDecoder, with a custom name.
      Type Parameters:
      A - the type to encode and decode
      Parameters:
      encoder - used to encode objects to key-value pairs in a serialized form
      decoder - used to decode objects from a serialized form
      name - the name of the codec when printed
      Returns:
      a new map MapCodec with the behavior of the given encoder and decoder
    • pair

      static <F, S> Codec<Pair<F,S>> pair(Codec<F> first, Codec<S> second)
      Creates a new codec that decodes and encodes two different types from the same data, in sequence. Note that while decoding, the second codec only sees data not consumed by the first codec; if the first codec consumes all the provided data, the second codec will be given an empty input. This works particularly well with codecs constructed with MapCodec.codec(), as different codecs can consume different keys.
      Type Parameters:
      F - the type to decode first and encode second
      S - the type to decode second and encode first
      Parameters:
      first - the codec used first on encoding and second on decoding
      second - the codec used second on encoding and first on decoding
      Returns:
      a new codec that decodes and encodes two different types from the same data, in sequence
    • either

      static <F, S> Codec<Either<F,S>> either(Codec<F> first, Codec<S> second)
      Creates a new codec that decodes and encodes either of two different types from the same data. If the first codec fails to decode, the second codec will be used instead. If both codecs fail to decode, the error from the second codec will be returned, and the error from the first silently swallowed.
      Type Parameters:
      F - the type to attempt to decode first
      S - the type to attempt to decode second
      Parameters:
      first - the codec used to attempt decoding first, or to encode the left component
      second - the codec used to attempt decoding second, or to encode the right component
      Returns:
      a new codec that decodes and encodes either of two different types from the same data
    • mapPair

      static <F, S> MapCodec<Pair<F,S>> mapPair(MapCodec<F> first, MapCodec<S> second)
      Creates a new MapCodec that decodes and encodes two different types from the same data, in sequence. Note that unlike when using pair(Codec, Codec), no data is "consumed" by a MapCodec, so the second MapCodec will see the same input as the first.
      Type Parameters:
      F - the type to decode and encode first
      S - the type to decode and encode second
      Parameters:
      first - used to encode and decode the first component
      second - used to encode and decode the second component
      Returns:
      a new MapCodec that decodes and encodes two different types from the same data, in sequence
    • mapEither

      static <F, S> MapCodec<Either<F,S>> mapEither(MapCodec<F> first, MapCodec<S> second)
      Creates a new MapCodec that decodes and encodes either of two different types from the same data. If the first MapCodec fails to decode, the second MapCodec will be used instead. If both fail to decode, the error from the second codec will be returned, and the error from the first silently swallowed.
      Type Parameters:
      F - the type to attempt to decode first
      S - the type to attempt to decode second
      Parameters:
      first - used to attempt decoding first, or to encode the left component
      second - used to attempt decoding second, or to encode the right component
      Returns:
      a new MapCodec that decodes and encodes either of two different types from the same data
    • list

      static <E> Codec<List<E>> list(Codec<E> elementCodec)
      Returns a new codec that decodes and encodes a list of a single type.
      Type Parameters:
      E - the type to decode and encode
      Parameters:
      elementCodec - the codec used to encode and decode the elements of the list
      Returns:
      a new codec that decodes and encodes a list of a single type
      See Also:
    • compoundList

      static <K, V> Codec<List<Pair<K,V>>> compoundList(Codec<K> keyCodec, Codec<V> elementCodec)
      Returns a codec which represents a list of key-value pairs as a map-like structure in serialized form.
      Type Parameters:
      K - the type of the keys
      V - the type of the values
      Parameters:
      keyCodec - the codec used to encode and decode the keys of the map. Will likely cause issues if the keys do not eventually serialize to strings
      elementCodec - the codec used to encode and decode the values of the map
      Returns:
      a codec which represents a list of key-value pairs as a map-like structure in serialized form
    • simpleMap

      static <K, V> SimpleMapCodec<K,V> simpleMap(Codec<K> keyCodec, Codec<V> elementCodec, Keyable keys)
      Creates a MapCodec which represents bounded map - that is, a map with a fixed set of keys - as a map-like structure when serialized.
      Type Parameters:
      K - the type of the keys
      V - the type of the values
      Parameters:
      keyCodec - used to encode and decode the keys of the map. Will likely cause issues if the keys do not eventually serialize to strings
      elementCodec - used to encode and decode the values of the map
      keys - provides the set of keys that the map can contain
      Returns:
      a new SimpleMapCodec representing a bounded map
    • unboundedMap

      static <K, V> UnboundedMapCodec<K,V> unboundedMap(Codec<K> keyCodec, Codec<V> elementCodec)
      Creates a codec which represents an unbounded map - that is, a map with an arbitrary set of keys - as a map-like structure when serialized.
      Type Parameters:
      K - the type of the keys
      V - the type of the values
      Parameters:
      keyCodec - used to encode and decode the keys of the map. Will likely cause issues if the keys do not eventually serialize to strings
      elementCodec - used to encode and decode the values of the map
      Returns:
      a new UnboundedMapCodec representing an unbounded map
    • optionalField

      static <F> MapCodec<Optional<F>> optionalField(String name, Codec<F> elementCodec)
      Creates a MapCodec representing a type as single field in a map-like structure when serialized which may be absent.
      Type Parameters:
      F - the type of the field
      Parameters:
      name - the name of the field
      elementCodec - the codec used to encode and decode the value of the field
      Returns:
      a new MapCodec
    • listOf

      default Codec<List<A>> listOf()
      Returns a new codec that decodes and encodes a list of a single type.
      Returns:
      a new codec that decodes and encodes a list of a single type
      See Also:
    • xmap

      default <S> Codec<S> xmap(Function<? super A,? extends S> to, Function<? super S,? extends A> from)
      Creates a new codec by transforming the output of this codec during decoding, and the input while encoding.
      Type Parameters:
      S - the target type of the new codec
      Parameters:
      to - applied to the output of this codec during decoding, to produce the output of the new codec
      from - applied to the input of this codec during encoding
      Returns:
      a new codec
      See Also:
    • comapFlatMap

      default <S> Codec<S> comapFlatMap(Function<? super A,? extends DataResult<? extends S>> to, Function<? super S,? extends A> from)
      Similar to xmap(Function, Function), except that the forwards (decoding) transformation produces a DataResult and is allowed to fail.
      Type Parameters:
      S - the target type of the new codec
      Parameters:
      to - applied to the output of this codec during decoding, to produce the output of the new codec
      from - applied to the input of this codec during encoding
      Returns:
      a new codec
      See Also:
    • flatComapMap

      default <S> Codec<S> flatComapMap(Function<? super A,? extends S> to, Function<? super S,? extends DataResult<? extends A>> from)
      Similar to xmap(Function, Function), except that the backwards (encoding) transformation produces a DataResult and is allowed to fail.
      Type Parameters:
      S - the target type of the new codec
      Parameters:
      to - applied to the output of this codec during decoding, to produce the output of the new codec
      from - applied to the input of this codec during encoding
      Returns:
      a new codec
      See Also:
    • flatXmap

      default <S> Codec<S> flatXmap(Function<? super A,? extends DataResult<? extends S>> to, Function<? super S,? extends DataResult<? extends A>> from)
      Similar to xmap(Function, Function), except that both the forwards and backwards transformations produce a DataResult and are allowed to fail.
      Type Parameters:
      S - the target type of the new codec
      Parameters:
      to - applied to the output of this codec during decoding, to produce the output of the new codec
      from - applied to the input of this codec during encoding
      Returns:
      a new codec
      See Also:
    • fieldOf

      default MapCodec<A> fieldOf(String name)
      Creates a MapCodec representing this as single field in a map-like structure when serialized.
      Specified by:
      fieldOf in interface Decoder<A>
      Specified by:
      fieldOf in interface Encoder<A>
      Parameters:
      name - the name of the field
      Returns:
      a new MapCodec
      See Also:
    • optionalFieldOf

      default MapCodec<Optional<A>> optionalFieldOf(String name)
      Similar to fieldOf(String), except that the produced field may be absent. Thus, the deserialized type is an Optional of the codec type
      Parameters:
      name - the name of the field
      Returns:
      a new MapCodec
    • optionalFieldOf

      default MapCodec<A> optionalFieldOf(String name, A defaultValue)
      Similar to fieldOf(String), except that the produced field may be absent. A default value is provided to be used when the field is absent, and if the default value is encoded nothing will be encoded.
      Parameters:
      name - the name of the field
      defaultValue - the default value to use when the field is absent
      Returns:
      a new MapCodec
    • optionalFieldOf

      default MapCodec<A> optionalFieldOf(String name, A defaultValue, Lifecycle lifecycleOfDefault)
      Equivalent to optionalFieldOf(String, Object) except that when the field is absent, the produced result will have the given Lifecycle. If the field is present, the lifecycle of the produced result will be Lifecycle.experimental().
      Parameters:
      name - the name of the field
      defaultValue - the default value to use when the field is absent, or when the encoded value is the default
      lifecycleOfDefault - the lifecycle to provide in the produced result when the field is absent
      Returns:
      a new MapCodec
    • optionalFieldOf

      default MapCodec<A> optionalFieldOf(String name, Lifecycle fieldLifecycle, A defaultValue, Lifecycle lifecycleOfDefault)
      Equivalent to optionalFieldOf(String, Object, Lifecycle) except that the lifecycle of non-default results can be specified.
      Parameters:
      name - the name of the field
      fieldLifecycle - the lifecycle to provide in the produced result when the field is present
      defaultValue - the default value to use when the field is absent, or when the encoded value is the default
      lifecycleOfDefault - the lifecycle to provide in the produced result when the field is absent
      Returns:
      a new MapCodec
    • mapResult

      default Codec<A> mapResult(Codec.ResultFunction<A> function)
      Creates a new codec by transforming the current one with the given Codec.ResultFunction.
      Parameters:
      function - the function to apply to the result of encoding and decoding
      Returns:
      a new codec
    • orElse

      default Codec<A> orElse(Consumer<String> onError, A value)
      Similar to orElse(UnaryOperator, Object) except that the error message is not transformed, but only fed to the provided consumer.
      Parameters:
      onError - is called with the error message if decoding or encoding fails
      value - the value to return if decoding fails
      Returns:
      a new codec
    • orElse

      default Codec<A> orElse(UnaryOperator<String> onError, A value)
      Creates a codec which attempts to decode using this codec, and if that fails, returns the given value and maps the error using the given function while encoding or decoding. The result of the providing function is thrown out on decoding, as the default value is used, but any side effects will still occur.
      Parameters:
      onError - a function to map the error message on encoding or decoding
      value - the value to return if decoding fails
      Returns:
      a new codec
    • orElseGet

      default Codec<A> orElseGet(Consumer<String> onError, Supplier<? extends A> value)
      Similar to orElse(Consumer, Object) except that the default value is calculated lazily.
      Parameters:
      onError - is called with the error message if decoding or encoding fails
      value - supplies the value to return if decoding fails
      Returns:
      a new codec
    • orElseGet

      default Codec<A> orElseGet(UnaryOperator<String> onError, Supplier<? extends A> value)
      Similar to orElse(UnaryOperator, Object) except that the default value is calculated lazily.
      Parameters:
      onError - a function to map the error message on encoding or decoding
      value - supplies the value to return if decoding fails
      Returns:
      a new codec
    • orElse

      default Codec<A> orElse(A value)
      Creates a codec which attempts to decode using this codec, and if that fails, returns the given value.
      Parameters:
      value - the value to return if decoding fails
      Returns:
      a new codec
    • orElseGet

      default Codec<A> orElseGet(Supplier<? extends A> value)
      Similar to orElse(Object) except that the default value is calculated lazily.
      Parameters:
      value - supplies the value to return if decoding fails
      Returns:
      a new codec
    • promotePartial

      default Codec<A> promotePartial(Consumer<String> onError)
      Description copied from interface: Decoder
      Returns a new decoder that decodes the same object as this decoder, but also runs the given action on an error.
      Specified by:
      promotePartial in interface Decoder<A>
      Parameters:
      onError - an action to run on an error
      Returns:
      a new decoder that decodes the same object as this decoder, but also runs the given action on an error
    • unit

      static <A> Codec<A> unit(A defaultValue)
      Returns a codec which always decodes the provided value, and encodes nothing. Useful for representing singleton or unit types.
      Type Parameters:
      A - the type to encode and decode
      Parameters:
      defaultValue - the value to decode to
      Returns:
      a codec which always decodes the provided value, and encodes nothing
    • unit

      static <A> Codec<A> unit(Supplier<A> defaultValue)
      Returns a codec which always decodes a value from the provided supplier, and encodes nothing. Useful for representing singleton or unit types where the single instance is supplied lazily.
      Type Parameters:
      A - the type to encode and decode
      Parameters:
      defaultValue - supplies the value to decode to
      Returns:
      a codec which always decodes a value from the provided supplier, and encodes nothing
    • dispatch

      default <E> Codec<E> dispatch(Function<? super E,? extends A> type, Function<? super A,? extends Codec<? extends E>> codec)
      An overload of dispatch(String, Function, Function) which uses the string "type" as name of the key field.

      Note: dispatch codecs have several quirks it is good to be aware of. See dispatch(String, Function, Function) and KeyDispatchCodec.

      Type Parameters:
      E - the type to encode and decode
      Parameters:
      type - a function which can find a dispatch key from an instance of the target type
      codec - a function which can find a codec from a dispatch key
      Returns:
      a new codec
    • dispatch

      default <E> Codec<E> dispatch(String typeKey, Function<? super E,? extends A> type, Function<? super A,? extends Codec<? extends E>> codec)
      Delegate codecs allow using the value of an initially decoded key to determine how to decode the rest of the input. On encoding, the behaviour is similar, with the dispatch codec finding a codec from the supplied type, using that to encode the value and using the receiver to encode the key. The reciever for this method is a codec decoding the type of the key. Note that delegated-to codecs constructed from a MapCodec.MapCodecCodec have special behaviour compared to other codecs; see KeyDispatchCodec for more information.

      Note: the second argument, which provides a codec given the key, is used on both encoding on decoding. As on encoding the type function is first used to find a key, and the codec function only used after that, there is no guarantee that the capture of ? super E is the same in both cases! In other words, this method is not inherently typesafe. Take care that whatever functions you provide only involve a single capture of that generic for a given key; a common approach is using the codec itself as the key.

      Type Parameters:
      E - the type to encode and decode
      Parameters:
      typeKey - the name of the field which will contain the key in the serialized form
      type - a function which can find a dispatch key from an instance of the target type
      codec - a function which can find a codec from a dispatch key
      Returns:
      a new codec
      See Also:
    • dispatchStable

      default <E> Codec<E> dispatchStable(Function<? super E,? extends A> type, Function<? super A,? extends Codec<? extends E>> codec)
      Similar to dispatch(Function, Function) except that the decoding of the key is considered to be in the Lifecycle.stable() lifecycle.

      Note: dispatch codecs have several quirks it is good to be aware of. See dispatch(String, Function, Function) and KeyDispatchCodec.

      Type Parameters:
      E - the type to encode and decode
      Parameters:
      type - a function which can find a dispatch key from an instance of the target type
      codec - a function which can find a codec from a dispatch key
      Returns:
      a new codec
    • partialDispatch

      default <E> Codec<E> partialDispatch(String typeKey, Function<? super E,? extends DataResult<? extends A>> type, Function<? super A,? extends DataResult<? extends Codec<? extends E>>> codec)
      Creates a dispatch codec where each of the transforming functions produces a DataResult and is allowed to fail.

      Note: dispatch codecs have several quirks it is good to be aware of. See dispatch(String, Function, Function) and KeyDispatchCodec.

      Type Parameters:
      E - the type to encode and decode
      Parameters:
      typeKey - the name of the field which will contain the key in the serialized form
      type - a function which can find a dispatch key or fail from an instance of the target type
      codec - a function which can find a codec or fail from a dispatch key
      Returns:
      a new codec
      See Also:
    • dispatchMap

      default <E> MapCodec<E> dispatchMap(Function<? super E,? extends A> type, Function<? super A,? extends Codec<? extends E>> codec)
      Similar to dispatch(Function, Function) except that MapCodec is constructed instead of a Codec.

      Note: dispatch codecs have several quirks it is good to be aware of. See dispatch(String, Function, Function) and KeyDispatchCodec.

      Type Parameters:
      E - the type to encode and decode
      Parameters:
      type - a function which can find a dispatch key from an instance of the target type
      codec - a function which can find a codec from a dispatch key
      Returns:
      a new MapCodec
    • dispatchMap

      default <E> MapCodec<E> dispatchMap(String typeKey, Function<? super E,? extends A> type, Function<? super A,? extends Codec<? extends E>> codec)
      Similar to dispatch(String, Function, Function) except that MapCodec is constructed instead of a Codec.

      Note: dispatch codecs have several quirks it is good to be aware of. See dispatch(String, Function, Function) and KeyDispatchCodec.

      Type Parameters:
      E - the type to encode and decode
      Parameters:
      typeKey - the name of the field which will contain the key in the serialized form
      type - a function which can find a dispatch key from an instance of the target type
      codec - a function which can find a codec from a dispatch key
      Returns:
      a new MapCodec
    • intRange

      static Codec<Integer> intRange(int minInclusive, int maxInclusive)
      Returns a codec that will encode and decode integers only within the specified range.
      Parameters:
      minInclusive - the minimum value to accept, inclusive
      maxInclusive - the maximum value to accept, inclusive
      Returns:
      a codec that will encode and decode integers only within the specified range
    • floatRange

      static Codec<Float> floatRange(float minInclusive, float maxInclusive)
      Returns a codec that will encode and decode floats only within the specified range.
      Parameters:
      minInclusive - the minimum value to accept, inclusive
      maxInclusive - the maximum value to accept, inclusive
      Returns:
      a codec that will encode and decode floats only within the specified range
    • doubleRange

      static Codec<Double> doubleRange(double minInclusive, double maxInclusive)
      Returns a codec that will encode and decode doubles only within the specified range.
      Parameters:
      minInclusive - the minimum value to accept, inclusive
      maxInclusive - the maximum value to accept, inclusive
      Returns:
      a codec that will encode and decode doubles only within the specified range