proteus 0.2.3 API

Proteus

A modern, bidirectional type adapting library for Java.


Resources

This is the official documentation for Proteus. You might also find the following resources helpful:

Having trouble or found a bug? Feel free to open an issue here.

Getting Proteus

Proteus is distributed via maven central.

Gradle

repositories {
   mavenCentral()
}
dependencies {
   implementation("io.github.kaktushose:proteus:VERSION")
}

Maven

<dependency>
   <groupId>io.github.kaktushose</groupId>
   <artifactId>proteus</artifactId>
   <version>VERSION</version>
</dependency>

Example Usage

Proteus Instance

The intended way of integrating Proteus in your project is using the global Proteus instance. Thus, all libraries or frameworks that work with Proteus have a shared pool of mappers and can benefit from each other. You can access the global instance like this:

Proteus proteus = Proteus.global();

This global instance is thread-safe. You can also create a new empty Proteus instance by calling Proteus#create() or use the builder via Proteus#builder(). These instances will have their own pool of mappers and will not interact with the global instance.

Types

Proteus doesn't just use the type of the data that you want to convert. Instead, Proteus provides an additional layer. You can define types by using one of the static factory methods of the Type class.

The simplest way of creating a type reference looks like this:

Type<String> stringType = Type.of(String.class);

This type doesn't have any identity yet. You can add context to your types by providing an implementation of the Format interface:

Type<String> stringType = Type.of(new JSONFormat(), String.class);

Mappers

In Proteus there are three types of mappers:

  1. lossy unidirectional mappers
  2. lossless unidirectional mappers
  3. bidirectional mappers (always lossless)

The following example will register a lossless UniMapper from Integer to String:

Type<Integer> integerType = Type.of(Integer.class);
Type<String> stringType = Type.of(String.class);

proteus.map(integerType).to(stringType, Mapper.lossless((source, context) -> MappingResult.success(String.valueOf(source))));

Conversion

Proteus keeps track of all registered mappers by using an unweighted, undirected graph. This means that the conversion can have any number of intermediate steps and no explicit mapper for A -> B is always required. Proteus will always search for the shortest path possible to convert from one type to another.

Full Example

// get proteus instance
Proteus proteus = Proteus.global();

// define types and mapper
Type<Integer> integerType = Type.of(Integer.class);
Type<String> stringType = Type.of(String.class);

// register mapper
proteus.map(integerType).to(stringType, Mapper.lossless((source, context) -> MappingResult.success(String.valueOf(source))));

// attempt conversion
ConversionResult<String> result = proteus.convert(0, integerType, stringType);

// check result
switch (result) {
    case ConversionResult.Success<String>(String success) -> System.out.println(success);
    case ConversionResult.Failure<?> failure -> System.out.println(failure.detailedMessage());
}
Modules
Module
Description