Decoder class abstract interface

A data format that can decode different types of data.

The role of this interface is to convert the encoded data into the supported types. Different implementations of this interface can support different data types and decoding strategies.

Decoding is performed by mutual interaction between the Decoder and the Decodable implementation.

A Decodable implementation should first use whatsNext to determine the type of the encoded data. Then it should use one of the typed .decode...() methods of this interface to decode into its target type. If the returned DecodingType is not supported, the implementation can use expect to throw a detailed error.

/// Example of a [Decodable.decode] implementation:
@override
Data decode(Decoder decoder) {
  switch (decoder.whatsNext()) {
    case DecodingType.string:
      final value = decoder.decodeString();
      return Data.fromString(value);
    case DecodingType.double:
      final value = decoder.decodeDouble();
      return Data.fromDouble(value);
    default:
      decoder.expect('string or double');
  }
}

What possible DecodingTypes are returned by whatsNext depends on the type of data format:

  • A self-describing format (i.e. the encoded data includes information about the type and shape of the data) can return DecodingTypes for all supported types. The Decodable implementation may choose to call the appropriate decoding method based on the returned DecodingType. However, it is not required to do so.

    Self-describing formats include JSON, YAML, or binary formats like MessagePack and CBOR.

  • A non-self-describing format may only return DecodingType.unknown for all types. In this case, the Decodable implementation must choose a appropriate decoding method based on its expected type.

    Non-self-describing formats include CSV or binary formats like Protobuf or Avro (when separated from schema).

Independent of the formats preferred DecodingType, it should try to decode other types if requested by the Decodable. This allows for more flexible decoding strategies and better error handling. For example, a Decodable implementation may choose to call decodeInt even if whatsNext returns DecodingType.num.

If the Decoder is not able to decode the requested type, it should throw an exception with a detailed message.

Calling a decoding method is expected to consume the encoded data. Therefore, a Decodable implementation should call exactly one of the decoding methods a single time. Never more or less.

Implementers
Available extensions

Properties

hashCode int
The hash code for this object.
no setterinherited
runtimeType Type
A representation of the runtime type of the object.
no setterinherited

Methods

clone() Decoder
Creates a new Decoder that is a copy of this one.
decodeBool() bool
Decodes the data as a boolean value.
decodeBoolOrNull() bool?
Decodes the data as a nullable boolean value.
decodeDouble() double
Decodes the data as a double value.
decodeDoubleOrNull() double?
Decodes the data as a nullable double value.
decodeFuture<T>({Decodable<T>? using}) Future<T>

Available on Decoder, provided by the AsyncDecoder extension

Decodes a Future of T using the provided Decodable.
decodeFutureOrNull<T>({Decodable<T>? using}) Future<T>?

Available on Decoder, provided by the AsyncDecoder extension

Decodes a Future of T or null using the provided Decodable.
decodeInt() int
Decodes the data as an integer value.
decodeIntOrNull() int?
Decodes the data as a nullable integer value.
decodeIsNull() bool
Checks if the data is null.
decodeIterated() IteratedDecoder
Decodes the data as an iterated collection of nested data.
decodeKeyed() KeyedDecoder
Decodes the data as a collection of key-value pairs. The pairs are decoded in order of appearance in the encoded data.
decodeList<E>({Decodable<E>? using}) List<E>
Decodes the data as a list of elements.
decodeListOrNull<E>({Decodable<E>? using}) List<E>?
Decodes the data as a nullable list of elements.
decodeMap<K, V>({Decodable<K>? keyUsing, Decodable<V>? valueUsing}) Map<K, V>
Decodes the data as a map of key-value pairs.
decodeMapOrNull<K, V>({Decodable<K>? keyUsing, Decodable<V>? valueUsing}) Map<K, V>?
Decodes the data as a nullable map of key-value pairs.
decodeMapped() MappedDecoder
Decodes the data as a collection of key-value pairs. The values are accessed and decoded based on the provided key.
decodeNum() num
Decodes the data as a num value.
decodeNumOrNull() num?
Decodes the data as a nullable num value.
decodeObject<T>({Decodable<T>? using}) → T
Decodes the data as an object of type T.
decodeObjectOrNull<T>({Decodable<T>? using}) → T?
Decodes the data as a nullable object of type T.
decodeReference<T>({Decodable<T>? using}) Reference<T>

Available on Decoder, provided by the ReferenceDecoder extension

Decodes a Reference of T using the provided Decodable.
decodeReferenceOrNull<T>({Decodable<T>? using}) Reference<T>?

Available on Decoder, provided by the ReferenceDecoder extension

Decodes a Reference of T or null using the provided Decodable.
decodeStream<T>({Decodable<T>? using}) Stream<T>

Available on Decoder, provided by the AsyncDecoder extension

Decodes a Stream of T using the provided Decodable.
decodeStreamOrNull<T>({Decodable<T>? using}) Stream<T>?

Available on Decoder, provided by the AsyncDecoder extension

Decodes a Stream of T or null using the provided Decodable.
decodeString() String
Decodes the data as a string value.
decodeStringOrNull() String?
Decodes the data as a nullable string value.
expect(String expected) → Never
Throws an exception with a detailed message.
isHumanReadable() bool
Whether a Decodable implementation should expect to decode their human-readable form.
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
toString() String
A string representation of this object.
inherited
whatsNext() DecodingType
Returns the actual or preferred DecodingType of the encoded data.

Operators

operator ==(Object other) bool
The equality operator.
inherited