Custom Converters

You can create custom converters for not automatically generated objects by creating a class which implements DogConverter. The converter implementation must then implement a conversion mechanism to and from the graph representation. You can statically link your converter by using the linkSerializer annotation. A simple implementation will look similar to this:

@linkSerializer
class ConvertableAConverter extends DogConverter<ConvertableA> {

  @override
  ConvertableA convertFromGraph(DogGraphValue value, DogEngine engine) {
    var list = value.asList!.value;
    return ConvertableA(list[0].asInt!, list[1].asInt!);
  }

  @override
  DogGraphValue convertToGraph(ConvertableA value, DogEngine engine) {
    return DogList([DogInt(value.a), DogInt(value.b)]);
  }
}

Although this converter can convert properties of the type ConvertableA, it can not serialize it as a polymorphic value and also doesn't return any information on the structure of the graph. For this, you must mixin the StructureEmitter and return the structure of your object from the getter method. For non generated converts, you should use the synthetic factory method of DogStructure to just specify a serial name for you class (typically the class name). To change the object description for the openapi schema, override the output getter of DogConverter. This could result in a converter similar to this:

class DateTimeConverter extends DogConverter<DateTime>
    with StructureEmitter<DateTime> {
  @override
  DateTime convertFromGraph(DogGraphValue value, DogEngine engine) {
    var stringValue = value.asString!;
    var datetime = DateTime.parse(stringValue);
    return datetime;
  }

  @override
  DogGraphValue convertToGraph(DateTime value, DogEngine engine) {
    var stringValue = value.toIso8601String();
    return DogString(stringValue);
  }

  @override
  APISchemaObject get output => APISchemaObject.string(format: "date-time");

  @override
  DogStructure get structure => DogStructure<DateTime>.synthetic("DateTime");
}

If you want to specify validation logic for your converter, you must implement the Validable interface. To use the copyable mechanism with the converter, you must implement Copyable interface.

Native Values and Converter Forks

The converter also has a method call fork. This method is called, when a fork of a dog engine is created. Mostly, this is done to create a engine with a different native codec. When your converter caches anything related to the DogEngine instance, you should create a new, clean converter of the same type and return it in the fork method.

Optimizations

You should, if possible, cache data and reuse it in succeeding calls to improve the performance of your converter. The registrationCallback method of the converter is specifically made for this use case and gets called after the converter has been registered into the engine. It is ensured, that this method has been called before any value is passed to the convert methods.

To further optimize the performance of your converter, you can also implement the native conversion methods which should directly converter the object to a "primitive" form, skipping the dog graph form. Make sure to respect the engines native codec when working with native values amd also remember to implement the fork method of the converter.

Additional Properties

If you want your converter to be registrable while not binding it to its specified type argument, you can use the positional isAssociated constructor parameter.

By default, the engine simplifies conversion by automatically handling iterables for you. If you wan't to manually handle iterables, set the positional constructor paremeter keepIterables to true.

Last updated