package com.timgroup.eventstore.api;

import java.util.Comparator;
import java.util.function.Function;

public interface PositionCodec {
    Position deserializePosition(String string);

    String serializePosition(Position position);

    default int comparePositions(Position left, Position right) {
        throw new UnsupportedOperationException();
    }

    static <T extends Position> PositionCodec fromComparator(
            Class<T> clazz,
            Function<? super String, ? extends T> deserialize,
            Function<? super T, String> serialize,
            Comparator<? super T> comparator) {
        return new PositionCodec() {
            @Override
            public Position deserializePosition(String string) {
                return deserialize.apply(string);
            }

            @Override
            public String serializePosition(Position position) {
                return serialize.apply(clazz.cast(position));
            }

            @Override
            public int comparePositions(Position left, Position right) {
                return comparator.compare(clazz.cast(left), clazz.cast(right));
            }
        };
    }

    static <T extends Position & Comparable<T>> PositionCodec ofComparable(
            Class<T> clazz,
            Function<? super String, ? extends T> deserialize,
            Function<? super T, String> serialize) {
        return new PositionCodec() {
            @Override
            public Position deserializePosition(String string) {
                return deserialize.apply(string);
            }

            @Override
            public String serializePosition(Position position) {
                return serialize.apply(clazz.cast(position));
            }

            @Override
            public int comparePositions(Position left, Position right) {
                return clazz.cast(left).compareTo(clazz.cast(right));
            }
        };
    }
}

@@ -1139,32 +1139,193 @@
 );%0A            %7D
+%0A%0A            @Override%0A            public String toString() %7B%0A                return %22PositionCodec%7B%22 + clazz.getName() + %22, %22 + comparator + %22%7D%22;%0A            %7D
 %0A        %7D;%0A    
@@ -2070,32 +2070,173 @@
 );%0A            %7D
+%0A%0A            @Override%0A            public String toString() %7B%0A                return %22PositionCodec%7B%22 + clazz.getName() + %22%7D%22;%0A            %7D
 %0A        %7D;%0A    

add toString methods to standard PositionCodec implementations